Add Feature from Wu_Zheng

add kpu driver for edu-riscv64.
adapt kpu framework for XiZi_IIOT.
unified dvp driver for edu-riscv64.
add ethernet(W5500) example for edu-riscv64
adapt qs-fs/fx sensor framework in XiZi for edu-riscv6
This commit is contained in:
xuedongliang 2023-01-18 15:04:51 +08:00
commit d144306f76
58 changed files with 4726 additions and 248 deletions

View File

@ -192,6 +192,23 @@ menu "test app"
bool "Config test lcd device"
default n
menuconfig USER_TEST_ETHERNET
bool "Config test ethernet only for edu-riscv64"
default n
if USER_TEST_ETHERNET
if ADD_XIZI_FETURES
choice
prompt "set ethernet role as client or server"
default ETHERNET_AS_SERVER
config ETHERNET_AS_SERVER
bool "test as server"
config ETHERNET_AS_CLIENT
bool "test as client"
endchoice
endif
endif
endif
endmenu

View File

@ -83,7 +83,11 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y)
ifeq ($(CONFIG_USER_TEST_CAMERA),y)
SRC_FILES += test_camera.c
endif
endif
ifeq ($(CONFIG_USER_TEST_ETHERNET),y)
SRC_FILES += test_ethernet.c
endif
include $(KERNEL_ROOT)/compiler.mk
endif

View File

@ -2,15 +2,6 @@
#include <string.h>
#include <transform.h>
#define NULL_PARAMETER 0
#define DVP_INIT 0x00U
#define REG_SCCB_READ 0x12U
#define REG_SCCB_WRITE 0x13U
#define OUTPUT_CONFIG 0x20U
#define LCD_STRING_TYPE 0
#define LCD_DOT_TYPE 1
#define LCD_SIZE 320
static uint16_t image_buff[384000];

View File

@ -0,0 +1,173 @@
#include <stdio.h>
#include <string.h>
#include <transform.h>
#include <socket.h>
#define BUFF_SIZE 128
#define RECV_SIZE 16
#define TCP_PORT 12345
const static uint32_t sn = 0;
#ifdef ETHERNET_AS_SERVER
static int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size,
uint16_t port, enum TCP_OPTION opt) {
int32_t ret = 0;
uint16_t size = 0, sentsize = 0;
switch (getSn_SR(sn)) {
case SOCK_ESTABLISHED:
if (getSn_IR(sn) & Sn_IR_CON) {
printf("%d:Connected\r\n", sn);
setSn_IR(sn, Sn_IR_CON);
}
if (opt == SEND_DATA) {
uint32_t sent_size = 0;
memset(buf,0,buf_size);
strcpy(buf,"The message has been recved");
ret = wiz_sock_send(sn, buf, buf_size);
if (ret < 0) {
wiz_sock_close(sn);
return ret;
}
} else if (opt == RECV_DATA) {
uint32_t size = 0;
if ((size = getSn_RX_RSR(sn)) > 0) {
if (size > buf_size) size = buf_size;
memset(buf,0,buf_size);
ret = wiz_sock_recv(sn, buf, size);
printf("Recv message: %s\n",buf);
return ret;
}
}
break;
case SOCK_CLOSE_WAIT:
printf("%d:CloseWait\r\n", sn);
if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret;
printf("%d:Closed\r\n", sn);
break;
case SOCK_INIT:
printf("%d:Listen, port [%d]\r\n", sn, port);
if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret;
break;
case SOCK_CLOSED:
printf("%d:LBTStart\r\n", sn);
if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret;
printf("%d:Opened\r\n", sn);
break;
default:
break;
}
return 0;
}
void TestSocketAsServer(int argc, char *argv[])
{
x_err_t ret;
uint8_t buf[BUFF_SIZE] = {0};
while (1) {
ret = wiz_server_op(0, buf, BUFF_SIZE, TCP_PORT, RECV_DATA);
if (ret > 0) {
wiz_server_op(0, buf, BUFF_SIZE, TCP_PORT, SEND_DATA);
};
}
return ;
}
PRIV_SHELL_CMD_FUNCTION(TestSocketAsServer, a w5500 server test sample, PRIV_SHELL_CMD_MAIN_ATTR);
#elif defined ETHERNET_AS_CLIENT
static uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size,
uint8_t dst_ip[4], uint16_t dst_port,
enum TCP_OPTION opt) {
// assert(buf_size <= g_wiznet_buf_size);
int32_t ret;
switch (getSn_SR(sn)) {
case SOCK_CLOSE_WAIT:
wiz_sock_disconnect(sn);
break;
case SOCK_CLOSED:
wiz_socket(sn, Sn_MR_TCP, 5000, 0x00);
break;
case SOCK_INIT:
KPrintf("[SOCKET CLIENT] sock init.\n");
wiz_sock_connect(sn, dst_ip, dst_port);
break;
case SOCK_ESTABLISHED:
if (getSn_IR(sn) & Sn_IR_CON) {
printf("[SOCKET CLIENT] %d:Connected\r\n", sn);
setSn_IR(sn, Sn_IR_CON);
}
if (opt == SEND_DATA) {
uint32_t sent_size = 0;
ret = wiz_sock_send(sn, buf, buf_size);
if (ret < 0) {
wiz_sock_close(sn);
return ret;
}
} else if (opt == RECV_DATA) {
uint32_t size = 0;
if ((size = getSn_RX_RSR(sn)) > 0) {
if (size > buf_size) size = buf_size;
ret = wiz_sock_recv(sn, buf, size);
if (ret <= 0) return ret;
}
}
break;
default:
break;
}
}
void TestSocketAsClient(int argc, char *argv[])
{
x_err_t ret;
uint8_t buf[BUFF_SIZE] = {0};
uint32_t tmp_ip[4];
uint32_t port;
const uint8_t client_sock = 2;
if(argc<3){
printf("Please enter command like TestSocketAsClient ip:port msg\n");
}
sscanf(argv[1],"%d.%d.%d.%d:%d",tmp_ip,tmp_ip+1,tmp_ip+2,tmp_ip+3,&port);
printf("Client to %d.%d.%d.%d:%d\n",tmp_ip[0],tmp_ip[1],tmp_ip[2],tmp_ip[3],port);
uint8_t destination_ip[4]={0};
for(int i=0;i<4;i++){
destination_ip[i]=tmp_ip[i];
}
while(1){
ret = wiz_client_op(client_sock, argv[2], strlen(argv[2]), destination_ip, port,SEND_DATA);
printf("sizeof:%d\n",strlen(argv[2]));
PrivTaskDelay(1000);
if (ret > 0) {
ret=wiz_client_op(client_sock, buf, BUFF_SIZE, destination_ip, port, RECV_DATA);
printf("read ret is %d\n",ret);
if(ret>0){
printf("client recv msg successfully!\n");
printf("%s\n",buf);
}
};
PrivTaskDelay(1000);
}
return ;
}
PRIV_SHELL_CMD_FUNCTION(TestSocketAsClient, a w5500 client-ip-port-msg test sample, PRIV_SHELL_CMD_MAIN_ATTR);
#endif

View File

@ -67,7 +67,6 @@ void TestLora(int argc, char *argv[])
printf("pin configure success\n");
struct SerialDataCfg uart_cfg;
memset(&uart_cfg, 0, sizeof(struct SerialDataCfg));
// loraE220 support only 9600bps with 8N1 during initializing
uart_cfg.serial_baud_rate = BAUD_RATE_9600;
@ -96,7 +95,8 @@ void TestLora(int argc, char *argv[])
printf("lora configure into sleep(configure) mode\n");
// send configure data, and receive the same length of data
char sendbuff[] = {0xC0, 0x00, 0x05, 0x19, 0x49, 0xE6, 0x00, 0x17}; // config as address 1949 CH17 36.8kps
// configure loraE220 as address 1949 CH17 36.8kps
char sendbuff[] = {0xC0, 0x00, 0x05, 0x19, 0x49, 0xE6, 0x00, 0x17};
PrivTaskDelay(2000);

View File

@ -29,7 +29,14 @@ void WindDirectionQsFx(void)
struct SensorQuantity *wind_direction = SensorQuantityFind(SENSOR_QUANTITY_QS_FX_WINDDIRECTION, SENSOR_QUANTITY_WINDDIRECTION);
SensorQuantityOpen(wind_direction);
PrivTaskDelay(2000);
uint16_t result = SensorQuantityReadValue(wind_direction);
printf("wind direction : %d degree\n", result);
int result = 0;
for(int i=0;i<2000;i++)
{
result = 0;
PrivTaskDelay(1000);
result = SensorQuantityReadValue(wind_direction);
if(result > 0)
printf("wind direction : %d degree\n", result);
}
SensorQuantityClose(wind_direction);
}

View File

@ -29,7 +29,14 @@ void WindSpeedQsFs(void)
struct SensorQuantity *wind_speed = SensorQuantityFind(SENSOR_QUANTITY_QS_FS_WINDSPEED, SENSOR_QUANTITY_WINDSPEED);
SensorQuantityOpen(wind_speed);
PrivTaskDelay(2000);
uint16_t result = SensorQuantityReadValue(wind_speed);
printf("wind speed : %d.%d m/s\n", result/10, result%10);
int result = 0;
for(int i=0;i<2000;i++)
{
result = 0;
PrivTaskDelay(1000);
result = SensorQuantityReadValue(wind_speed);
if(result > 0)
printf("wind speed : %d.%d m/s\n", result/10, result%10);
}
SensorQuantityClose(wind_speed);
}

View File

@ -263,7 +263,7 @@ static int E220SetRegisterParam(struct Adapter *adapter, uint16 address, uint8 c
uint8 baud_rate_bit = E220BaudRateSwitch(baud_rate);
E220LoraModeConfig(CONFIGURE_MODE_MODE);
PrivTaskDelay(30);
PrivTaskDelay(2000);
buffer[0] = 0xC0; //write register order
buffer[1] = 0x00; //register start-address
@ -286,6 +286,7 @@ static int E220SetRegisterParam(struct Adapter *adapter, uint16 address, uint8 c
printf("E220SetRegisterParam send failed %d!\n", ret);
}
PrivTaskDelay(2000);
PrivRead(adapter->fd, buffer, 11);
E220LoraModeConfig(DATA_TRANSFER_MODE);

View File

@ -1,4 +1,4 @@
SRC_DIR := tensorflow-lite
SRC_DIR := kpu tensorflow-lite
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,3 @@
SRC_DIR := k210_yolov2_detect_procedure yolov2 yolov2_json
include $(KERNEL_ROOT)/compiler.mk

View File

@ -3,5 +3,16 @@ menuconfig USING_K210_YOLOV2_DETECT
depends on USING_KPU_PROCESSING
default n
config KPU_DEV_DRIVER
string "Set kpu dev path"
default "/dev/kpu_dev"
config CAMERA_DEV_DRIVER
string "Set camera dev path for kpu"
default "/dev/ov2640"
config KPU_LCD_DEV_DRIVER
string "Set lcd dev path for kpu"
default "/dev/lcd_dev"

View File

@ -0,0 +1,4 @@
SRC_FILES := k210_yolov2_detect.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,35 @@
# YOLO Framework for K210 KPU
## Usage
* Include all src and header there in menuconfig, and copy codes like below in *main.c* in folder *Application*.
* In board *edu-riscv64*, if all operations are right, the LCD should light and show the image from camera and YOLO inference.
```C
#include <stdio.h>
#include <string.h>
// #include <user_api.h>
#include <transform.h>
extern int FrameworkInit();
extern void ApplicationOtaTaskInit(void);
extern void k210_detect(char *json_file_path);
int main(void)
{
printf("Hello, world! \n");
FrameworkInit();
#ifdef APPLICATION_OTA
ApplicationOtaTaskInit();
#endif
k210_detect("instrusion.json");
return 0;
}
```
## TODO
* KPU drivers and frameworks are still not completed, because it is undefined how to reisgter KPU's bus and device name in rt-fusion system. The framework is still directly using the SDK with *ifdef* From Canaan Inc. But after the driver completed, it will be easy to adapt framework for the APIs.
* Camera and LCD drivers between RT and XIZI are not completely compatible. So there are some marcos like *ifdef* to make the framework compatible for both systems.
* After completed, all codes from kernel in knowing framework should be posix interfaces,like *PrivOpen*、*PrivIoctrl*、*PrivRead*.

View File

@ -1,25 +1,29 @@
#include "k210_yolov2_detect.h"
#include "cJSON.h"
#include "dvp.h"
#ifdef USING_YOLOV2_JSONPARSER
#include <json_parser.h>
#endif
#include "region_layer.h"
#define STACK_SIZE (128 * 1024)
static dmac_channel_number_t dma_ch = DMAC_CHANNEL_MAX;
#define THREAD_PRIORITY_D (11)
static dmac_channel_number_t dma_ch = DMAC_CHANNEL_MAX - 1;
static _ioctl_shoot_para shoot_para_t = {0};
static pthread_t tid = 0;
static void *thread_detect_entry(void *parameter);
static int g_fd = 0;
static int camera_fd = 0;
static int kmodel_fd = 0;
static int kpu_fd = 0;
static int if_exit = 0;
static unsigned char *showbuffer = NULL;
static unsigned char *kpurgbbuffer = NULL;
static int image_width = IMAGE_WIDTH;
static int image_height = IMAGE_HEIGHT;
static _ioctl_shoot_para shoot_para_t = {0};
unsigned char *model_data = NULL; // kpu data load memory
unsigned char *model_data = NULL; // kpu data load memory
unsigned char *model_data_align = NULL;
kpu_model_context_t detect_task;
@ -29,6 +33,7 @@ volatile uint32_t g_ai_done_flag;
static void ai_done(void *ctx) { g_ai_done_flag = 1; }
void k210_detect(char *json_file_path)
{
int ret = 0;
@ -36,45 +41,72 @@ void k210_detect(char *json_file_path)
int size = 0;
char kmodel_path[127] = {};
// open and parse from json file
yolov2_params_t detect_params = param_parse(json_file_path);
if (!detect_params.is_valid) {
if (!detect_params.is_valid)
{
return;
}
g_fd = open("/dev/ov2640", O_RDONLY);
if (g_fd < 0) {
printf("open ov2640 fail !!");
#ifdef ADD_XIZI_FETURES
kpu_fd = PrivOpen(KPU_DEV_DRIVER, O_RDONLY);
if (camera_fd < 0)
{
printf("open %s fail !!", KPU_DEV_DRIVER);
return;
}
#endif
printf("select camera device name:%s\n", CAMERA_DEV_DRIVER);
camera_fd = PrivOpen(CAMERA_DEV_DRIVER, O_RDONLY);
if (camera_fd < 0)
{
printf("open %s fail !!", CAMERA_DEV_DRIVER);
return;
}
// configure the resolution of camera
_ioctl_set_reso set_dvp_reso = {detect_params.sensor_output_size[1], detect_params.sensor_output_size[0]};
ioctl(g_fd, IOCTRL_CAMERA_OUT_SIZE_RESO, &set_dvp_reso);
showbuffer =
(unsigned char *)rt_malloc_align(detect_params.sensor_output_size[0] * detect_params.sensor_output_size[1] * 2, 64);
if (NULL == showbuffer) {
close(g_fd);
printf("showbuffer apply memory fail !!");
return;
}
kpurgbbuffer = (unsigned char *)rt_malloc_align(detect_params.net_input_size[0] * detect_params.net_input_size[1] * 3, 64);
if (NULL == kpurgbbuffer) {
close(g_fd);
rt_free_align(showbuffer);
printf("kpurgbbuffer apply memory fail !!");
return;
}
struct PrivIoctlCfg camera_cfg;
camera_cfg.args = &set_dvp_reso;
camera_cfg.ioctl_driver_type = CAMERA_TYPE;
PrivIoctl(camera_fd, IOCTRL_CAMERA_OUT_SIZE_RESO, &camera_cfg);
image_height = set_dvp_reso.height;
image_width = set_dvp_reso.width;
// alloc the memory for camera and kpu running
model_data = (unsigned char *)malloc(detect_params.kmodel_size + 255);
if (NULL == model_data) {
rt_free_align(showbuffer);
rt_free_align(kpurgbbuffer);
close(g_fd);
if (NULL == model_data)
{
free(showbuffer);
free(kpurgbbuffer);
PrivClose(camera_fd);
printf("model_data apply memory fail !!");
return;
}
showbuffer = (unsigned char *)malloc(detect_params.sensor_output_size[0] * detect_params.sensor_output_size[1] * 2);
if (NULL == showbuffer)
{
PrivClose(camera_fd);
printf("showbuffer apply memory fail !!");
return;
}
kpurgbbuffer = (unsigned char *)malloc(detect_params.net_input_size[0] * detect_params.net_input_size[1] * 3);
if (NULL == kpurgbbuffer)
{
PrivClose(camera_fd);
free(showbuffer);
printf("kpurgbbuffer apply memory fail !!");
return;
}
memset(model_data, 0, detect_params.kmodel_size + 255);
memset(showbuffer, 0, detect_params.sensor_output_size[0] * detect_params.sensor_output_size[1] * 2);
memset(kpurgbbuffer, 0, detect_params.net_input_size[0] * detect_params.net_input_size[1] * 3);
shoot_para_t.pdata = (unsigned int *)(showbuffer);
shoot_para_t.pdata = (uintptr_t)(showbuffer);
shoot_para_t.length = (size_t)(detect_params.sensor_output_size[0] * detect_params.sensor_output_size[1] * 2);
/*
load memory
*/
@ -83,83 +115,123 @@ void k210_detect(char *json_file_path)
int idx_suffix_start = strlen(json_file_path) - 4;
const char kmodel_suffix[7] = "kmodel";
int kmodel_suffix_len = 6;
while (kmodel_suffix_len--) {
while (kmodel_suffix_len--)
{
kmodel_path[idx_suffix_start + 5 - kmodel_suffix_len] = kmodel_suffix[5 - kmodel_suffix_len];
}
printf("kmodel path: %s\n", kmodel_path);
kmodel_fd = open(kmodel_path, O_RDONLY);
if (kmodel_fd < 0) {
unsigned char *model_data_align = (unsigned char *)(((uintptr_t)model_data + 255) & (~255));
printf("model address:%x->%x\n", model_data_align, model_data_align + detect_params.kmodel_size);
kmodel_fd = PrivOpen(kmodel_path, O_RDONLY);
if (kmodel_fd < 0)
{
printf("open kmodel fail");
close(g_fd);
PrivClose(camera_fd);
free(showbuffer);
free(kpurgbbuffer);
free(model_data);
return;
} else {
size = read(kmodel_fd, model_data, detect_params.kmodel_size);
if (size != detect_params.kmodel_size) {
}
else
{
size = PrivRead(kmodel_fd, model_data_align, detect_params.kmodel_size);
if (size != detect_params.kmodel_size)
{
printf("read kmodel error size %d\n", size);
close(g_fd);
close(kmodel_fd);
PrivClose(camera_fd);
PrivClose(kmodel_fd);
free(showbuffer);
free(kpurgbbuffer);
free(model_data);
return;
} else {
}
else
{
PrivClose(kmodel_fd);
printf("read kmodel success \n");
}
}
unsigned char *model_data_align = (unsigned char *)(((unsigned int)model_data + 255) & (~255));
// dvp_set_ai_addr((uint32_t)kpurgbbuffer,
// (uint32_t)(kpurgbbuffer + detect_params.net_input_size[0] * detect_params.net_input_size[1]),
// (uint32_t)(kpurgbbuffer + detect_params.net_input_size[0] * detect_params.net_input_size[1] * 2));
#ifdef ADD_RTTHREAD_FETURES
dvp_set_ai_addr(
(uint32_t)(kpurgbbuffer +
detect_params.net_input_size[1] * (detect_params.net_input_size[0] - detect_params.sensor_output_size[0])),
(uint32_t)(kpurgbbuffer +
detect_params.net_input_size[1] * (detect_params.net_input_size[0] - detect_params.sensor_output_size[0]) +
detect_params.net_input_size[0] * detect_params.net_input_size[1]),
(uint32_t)(kpurgbbuffer +
detect_params.net_input_size[1] * (detect_params.net_input_size[0] - detect_params.sensor_output_size[0]) +
detect_params.net_input_size[0] * detect_params.net_input_size[1] * 2));
if (kpu_load_kmodel(&detect_task, model_data_align) != 0) {
(uintptr_t)(kpurgbbuffer +
detect_params.net_input_size[1] * (detect_params.net_input_size[0] - detect_params.sensor_output_size[0])),
(uintptr_t)(kpurgbbuffer +
detect_params.net_input_size[1] * (detect_params.net_input_size[0] - detect_params.sensor_output_size[0]) +
detect_params.net_input_size[0] * detect_params.net_input_size[1]),
(uintptr_t)(kpurgbbuffer +
detect_params.net_input_size[1] * (detect_params.net_input_size[0] - detect_params.sensor_output_size[0]) +
detect_params.net_input_size[0] * detect_params.net_input_size[1] * 2));
#else
// Set AI buff address of Camera
RgbAddress ai_address_preset;
ai_address_preset.r_addr = (uintptr_t)kpurgbbuffer + detect_params.net_input_size[1];
ai_address_preset.g_addr = ai_address_preset.r_addr + detect_params.net_input_size[0] * detect_params.net_input_size[1];
ai_address_preset.b_addr = ai_address_preset.g_addr + detect_params.net_input_size[0] * detect_params.net_input_size[1];
camera_cfg.args = &ai_address_preset;
PrivIoctl(camera_fd, SET_AI_ADDR, &camera_cfg);
#endif
// Load kmodel into kpu task
#ifdef ADD_RTTHREAD_FETURES
if (kpu_load_kmodel(&detect_task, model_data_align) != 0)
{
printf("\nmodel init error\n");
close(g_fd);
close(kmodel_fd);
PrivClose(camera_fd);
PrivClose(kmodel_fd);
free(showbuffer);
free(kpurgbbuffer);
free(model_data);
return;
}
#else
struct PrivIoctlCfg kpu_cfg;
kpu_cfg.args = model_data_align;
kpu_cfg.ioctl_driver_type = KPU_TYPE;
if (PrivIoctl(kpu_fd,LOAD_KMODEL,&kpu_cfg) != 0)
{
printf("\nmodel init error\n");
PrivClose(camera_fd);
PrivClose(kmodel_fd);
free(showbuffer);
free(kpurgbbuffer);
free(model_data);
return;
}
#endif
detect_rl.anchor_number = ANCHOR_NUM;
detect_rl.anchor = detect_params.anchor;
detect_rl.nms_value = detect_params.nms_thresh;
detect_rl.classes = detect_params.class_num;
result =
region_layer_init(&detect_rl, detect_params.net_output_shape[0], detect_params.net_output_shape[1],
detect_params.net_output_shape[2], detect_params.net_input_size[1], detect_params.net_input_size[0]);
result = region_layer_init(&detect_rl, detect_params.net_output_shape[0], detect_params.net_output_shape[1],
detect_params.net_output_shape[2], detect_params.net_input_size[1], detect_params.net_input_size[0]);
printf("region_layer_init result %d \n\r", result);
for (int idx = 0; idx < detect_params.class_num; idx++) {
for (int idx = 0; idx < detect_params.class_num; idx++)
{
detect_rl.threshold[idx] = detect_params.obj_thresh[idx];
}
size_t stack_size = STACK_SIZE;
pthread_attr_t attr; /* 线程属性 */
struct sched_param prio; /* 线程优先级 */
prio.sched_priority = 8; /* 优先级设置为 8 */
prio.sched_priority = THREAD_PRIORITY_D; /* 优先级设置为 11 */
pthread_attr_init(&attr); /* 先使用默认值初始化属性 */
pthread_attr_setschedparam(&attr, &prio); /* 修改属性对应的优先级 */
pthread_attr_setstacksize(&attr, stack_size);
/* 创建线程 1, 属性为 attr入口函数是 thread_entry入口函数参数是 1 */
result = pthread_create(&tid, &attr, thread_detect_entry, &detect_params);
if (0 == result) {
if (0 == result)
{
printf("thread_detect_entry successfully!\n");
} else {
}
else
{
printf("thread_detect_entry failed! error code is %d\n", result);
close(g_fd);
PrivClose(camera_fd);
}
}
// #ifdef __RT_THREAD_H__
@ -168,39 +240,93 @@ void k210_detect(char *json_file_path)
static void *thread_detect_entry(void *parameter)
{
#ifdef BSP_USING_LCD
int lcd_fd = PrivOpen(KPU_LCD_DEV_DRIVER, O_RDWR);
if (lcd_fd < 0)
{
printf("open lcd fd error:%d\n", lcd_fd);
}
LcdWriteParam graph_param;
graph_param.type = LCD_DOT_TYPE;
for (int i = 0; i < LCD_SIZE; i++)
{
graph_param.pixel_info.pixel_color = (uint16_t *)showbuffer;
graph_param.pixel_info.x_startpos = 0;
graph_param.pixel_info.y_startpos = i;
graph_param.pixel_info.x_endpos = LCD_SIZE - 1;
graph_param.pixel_info.y_endpos = graph_param.pixel_info.y_startpos;
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
}
#endif
yolov2_params_t detect_params = *(yolov2_params_t *)parameter;
extern void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t * ptr);
struct PrivIoctlCfg camera_cfg;
camera_cfg.ioctl_driver_type = CAMERA_TYPE;
printf("thread_detect_entry start!\n");
int ret = 0;
// sysctl_enable_irq();
while (1) {
// memset(showbuffer,0,320*240*2);
while (1)
{
g_ai_done_flag = 0;
ret = ioctl(g_fd, IOCTRL_CAMERA_START_SHOT, &shoot_para_t);
if (RT_ERROR == ret) {
// get a graph map from camera
camera_cfg.args = &shoot_para_t;
ret = PrivIoctl(camera_fd, IOCTRL_CAMERA_START_SHOT, &camera_cfg);
if (EOF == ret)
{
printf("ov2640 can't wait event flag");
rt_free(showbuffer);
close(g_fd);
free(showbuffer);
PrivClose(camera_fd);
pthread_exit(NULL);
return NULL;
}
if (dmalock_sync_take(&dma_ch, 2000)) {
int shoot_flag = 0;
camera_cfg.args = (int *)&shoot_flag;
PrivIoctl(camera_fd, FLAG_CHECK, &camera_cfg);
while (shoot_flag == 2)
PrivIoctl(camera_fd, FLAG_CHECK, &camera_cfg);
#ifdef ADD_RTTHREAD_FETURES
if (dmalock_sync_take(&dma_ch, 2000))
{
printf("Fail to take DMA channel");
}
kpu_run_kmodel(&detect_task, kpurgbbuffer, DMAC_CHANNEL5, ai_done, NULL);
while (!g_ai_done_flag)
;
dmalock_release(dma_ch);
#elif defined ADD_XIZI_FETURES
struct PrivIoctlCfg kpu_cfg;
kpu_cfg.args = kpurgbbuffer;
kpu_cfg.ioctl_driver_type = KPU_TYPE;
PrivIoctl(kpu_fd,RUN_KMODEL,&kpu_cfg);
int wait_flag=0;
kpu_cfg.args = &wait_flag;
while (0==wait_flag){
PrivIoctl(kpu_fd,WAIT_FLAG,&kpu_cfg);
}
#endif
#ifdef ADD_RTTHREAD_FETURES
float *output;
size_t output_size;
kpu_get_output(&detect_task, 0, (uint8_t **)&output, &output_size);
detect_rl.input = output;
#else
KpuOutputBuffer output_buffer;
kpu_cfg.args = &output_buffer;
PrivIoctl(kpu_fd,GET_OUTPUT,&kpu_cfg);
detect_rl.input = (float*)(output_buffer.buffer);
#endif
region_layer_run(&detect_rl, &detect_info);
printf("detect_info.obj_number:%d\n", detect_info.obj_number);
/* display result */
for (int cnt = 0; cnt < detect_info.obj_number; cnt++) {
detect_info.obj[cnt].y1 += (detect_params.sensor_output_size[0] - detect_params.net_input_size[0])/2;
detect_info.obj[cnt].y2 += (detect_params.sensor_output_size[0] - detect_params.net_input_size[0])/2;
for (int cnt = 0; cnt < detect_info.obj_number; cnt++)
{
detect_info.obj[cnt].y1 += (detect_params.sensor_output_size[0] - detect_params.net_input_size[0]) / 2;
detect_info.obj[cnt].y2 += (detect_params.sensor_output_size[0] - detect_params.net_input_size[0]) / 2;
draw_edge((uint32_t *)showbuffer, &detect_info, cnt, 0xF800, (uint16_t)detect_params.sensor_output_size[1],
(uint16_t)detect_params.sensor_output_size[0]);
printf("%d: (%d, %d, %d, %d) cls: %s conf: %f\t", cnt, detect_info.obj[cnt].x1, detect_info.obj[cnt].y1,
@ -208,13 +334,29 @@ static void *thread_detect_entry(void *parameter)
detect_info.obj[cnt].prob);
}
#ifdef BSP_USING_LCD
#ifdef ADD_RTTHREAD_FETURES
extern void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t * ptr);
lcd_draw_picture(0, 0, (uint16_t)detect_params.sensor_output_size[1] - 1,
(uint16_t)detect_params.sensor_output_size[0] - 1, (uint32_t *)showbuffer);
// lcd_show_image(0, 0, (uint16_t)detect_params.sensor_output_size[1], (uint16_t)detect_params.sensor_output_size[0],
// (unsigned int *)showbuffer);
#else
// refresh the LCD using photo of camera
for (int i = 0; i < image_height; i++)
{
graph_param.pixel_info.pixel_color = (uint16_t *)showbuffer + (image_height-i-1) * image_width;
graph_param.pixel_info.x_startpos = (LCD_SIZE - image_width) / 2;
graph_param.pixel_info.y_startpos = i + (LCD_SIZE - image_height) / 2;
graph_param.pixel_info.x_endpos = LCD_SIZE - 1 - (LCD_SIZE - image_width) / 2;
graph_param.pixel_info.y_endpos = graph_param.pixel_info.y_startpos;
PrivWrite(lcd_fd, &graph_param, NULL_PARAMETER);
}
#endif
usleep(500);
if (1 == if_exit) {
#endif
if (1 == if_exit)
{
if_exit = 0;
printf("thread_detect_entry exit");
pthread_exit(NULL);
@ -224,10 +366,11 @@ static void *thread_detect_entry(void *parameter)
void detect_delete()
{
if (showbuffer != NULL) {
if (showbuffer != NULL)
{
int ret = 0;
close(g_fd);
close(kmodel_fd);
PrivClose(camera_fd);
PrivClose(kmodel_fd);
free(showbuffer);
free(kpurgbbuffer);
free(model_data);
@ -235,46 +378,3 @@ void detect_delete()
if_exit = 1;
}
}
// #ifdef __RT_THREAD_H__
// MSH_CMD_EXPORT(detect_delete, detect task delete);
// #endif
// void kmodel_load(unsigned char *model_data)
// {
// int kmodel_fd = 0;
// int size = 0;
// char kmodel_path[127] = {};
// // kmodel path generate from json file path, *.json -> *.kmodel
// memcpy(kmodel_path, json_file_path, strlen(json_file_path));
// int idx_suffix_start = strlen(json_file_path) - 4;
// const char kmodel_suffix[5] = "kmodel";
// int kmodel_suffix_len = 5;
// while (kmodel_suffix_len--) {
// kmodel_path[idx_suffix_start + 4 - kmodel_suffix_len] = kmodel_suffix[4 - kmodel_suffix_len];
// }
// printf("Kmodel path: %s\n", kmodel_path);
// kmodel_fd = open(kmodel_path, O_RDONLY);
// model_data = (unsigned char *)malloc(detect_params.kmodel_size + 255);
// if (NULL == model_data) {
// printf("model_data apply memory fail !!");
// return;
// }
// memset(model_data, 0, detect_params.kmodel_size + 255);
// if (kmodel_fd >= 0) {
// size = read(kmodel_fd, model_data, detect_params.kmodel_size);
// if (size != detect_params.kmodel_size) {
// printf("read kmodel error size %d\n", size);
// } else {
// printf("read kmodel success");
// }
// } else {
// free(model_data);
// printf("open kmodel fail");
// }
// }
// #ifdef __RT_THREAD_H__
// MSH_CMD_EXPORT(kmodel_load, kmodel load memory);
// #endif

View File

@ -1,7 +1,10 @@
#ifndef _K210_DETECT_H_
#define _K210_DETECT_H_
#include <stdio.h>
#include <string.h>
#include <transform.h>
#include "sleep.h"
void k210_detect(char *json_file_path);

View File

@ -0,0 +1,4 @@
SRC_FILES := region_layer.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -224,7 +224,7 @@ static void get_region_boxes(region_layer_t *rl, float *predictions, float **pro
correct_region_boxes(rl, boxes);
}
static int nms_comparator(void *pa, void *pb)
static int nms_comparator(const void *pa,const void *pb)
{
sortable_box_t a = *(sortable_box_t *)pa;
sortable_box_t b = *(sortable_box_t *)pb;

View File

@ -0,0 +1,4 @@
SRC_FILES := json_parser.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -1,6 +1,9 @@
#include "json_parser.h"
#include <fcntl.h>
// #include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <transform.h>
#include "cJSON.h"
@ -31,9 +34,9 @@ yolov2_params_t param_parse(char *json_file_path)
} else {
printf("Reading config from: %s\n", json_file_path);
}
read(fin, buffer, sizeof(buffer));
close(fin);
// read json string
json_obj = cJSON_Parse(buffer);
// free(buffer);

View File

@ -22,6 +22,14 @@ config SENSOR_QS_FX
default "/dev/uart2_dev2"
depends on !SENSOR_QS_FX_DRIVER_EXTUART
config SENSOR_DEVICE_QS_FX_PIN_DEV
string "qs-fx pin device name"
default "/dev/pin_dev"
config SENSOR_DEVICE_QS_FX_PIN_NUMBER
int "qs-fx pin device number"
default 24
if SENSOR_QS_FX_DRIVER_EXTUART
config SENSOR_DEVICE_QS_FX_DEV
string "qs-fx device extra uart path"

View File

@ -53,6 +53,7 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
cfg.serial_parity_mode = PARITY_NONE;
cfg.serial_bit_order = 0;
cfg.serial_invert_mode = 0;
cfg.serial_timeout = 1000;
cfg.is_ext_uart = 0;
#ifdef SENSOR_QS_FX_DRIVER_EXTUART
cfg.is_ext_uart = 1;
@ -66,7 +67,34 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
result = PrivIoctl(sdev->fd, OPE_INT, &ioctl_cfg);
return result;
}
}
static int PinOpen(void){
int pin_fd = PrivOpen(SENSOR_DEVICE_QS_FX_PIN_DEV, O_RDWR);
if (pin_fd < 0) {
printf("open %s error\n", SENSOR_DEVICE_QS_FX_PIN_DEV);
return -1;
}
//config led pin in board
struct PinParam pin_parameter;
memset(&pin_parameter, 0, sizeof(struct PinParam));
pin_parameter.cmd = GPIO_CONFIG_MODE;
pin_parameter.pin = SENSOR_DEVICE_QS_FX_PIN_NUMBER;
pin_parameter.mode = GPIO_CFG_OUTPUT;
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = (void *)&pin_parameter;
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
printf("ioctl pin fd error %d\n", pin_fd);
PrivClose(pin_fd);
return -1;
}
return pin_fd;
}
/**
* @description: Read sensor device
@ -76,12 +104,25 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
*/
static int SensorDeviceRead(struct SensorDevice *sdev, size_t len)
{
int pin_fd=PinOpen();
struct PinStat pin_dir;
pin_dir.pin = SENSOR_DEVICE_QS_FX_PIN_NUMBER;
pin_dir.val = GPIO_HIGH;
if (PrivWrite(pin_fd,&pin_dir,0) < 0) // pull-up pin to configure as tx mode
return -1;
PrivTaskDelay(20);
if (PrivWrite(sdev->fd, instructions, sizeof(instructions)) < 0)
return -1;
PrivTaskDelay(20);
pin_dir.val = GPIO_LOW;
if (PrivWrite(pin_fd,&pin_dir,0) < 0) // pull-down pin to configure as rx mode
return -1;
if (PrivRead(sdev->fd, sdev->buffer, len) < 0)
return -1;
PrivClose(pin_fd);
return 0;
}
@ -124,7 +165,10 @@ static int32_t ReadWindDirection(struct SensorQuantity *quant)
short result;
if (quant->sdev->done->read != NULL) {
if (quant->sdev->status == SENSOR_DEVICE_PASSIVE) {
quant->sdev->done->read(quant->sdev, 6);
quant->sdev->done->read(quant->sdev, 7);
if(Crc16(quant->sdev->buffer,7)!=0x00){
return -1;
}
result = (quant->sdev->buffer[3] << 8) | quant->sdev->buffer[4];
return (int32_t)result;

View File

@ -19,9 +19,17 @@ config SENSOR_QS_FS
config SENSOR_DEVICE_QS_FS_DEV
string "qs-fx device name"
default "/dev/uart2_dev2"
default "/dev/uart1_dev1"
depends on !SENSOR_QS_FS_DRIVER_EXTUART
config SENSOR_DEVICE_QS_FS_PIN_DEV
string "qs-fx pin device name"
default "/dev/pin_dev"
config SENSOR_DEVICE_QS_FS_PIN_NUMBER
int "qs-fs pin device number"
default 24
if SENSOR_QS_FS_DRIVER_EXTUART
config SENSOR_DEVICE_QS_FS_DEV
string "qs-fx device extra uart path"

View File

@ -21,7 +21,7 @@
#include <sensor.h>
static struct SensorDevice qs_fs;
static const unsigned char instructions[] = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
static const unsigned char instructions[] = {0x02,0x03,0x00,0x00,0x00,0x01,0x84,0x39};
static struct SensorProductInfo info =
{
@ -68,6 +68,34 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
return result;
}
static int PinOpen(void){
int pin_fd = PrivOpen(SENSOR_DEVICE_QS_FS_PIN_DEV, O_RDWR);
if (pin_fd < 0) {
printf("open %s error\n", SENSOR_DEVICE_QS_FS_PIN_DEV);
return -1;
}
//config led pin in board
struct PinParam pin_parameter;
memset(&pin_parameter, 0, sizeof(struct PinParam));
pin_parameter.cmd = GPIO_CONFIG_MODE;
pin_parameter.pin = SENSOR_DEVICE_QS_FS_PIN_NUMBER;
pin_parameter.mode = GPIO_CFG_OUTPUT;
struct PrivIoctlCfg ioctl_cfg;
ioctl_cfg.ioctl_driver_type = PIN_TYPE;
ioctl_cfg.args = (void *)&pin_parameter;
if (0 != PrivIoctl(pin_fd, OPE_CFG, &ioctl_cfg)) {
printf("ioctl pin fd error %d\n", pin_fd);
PrivClose(pin_fd);
return -1;
}
return pin_fd;
}
/**
* @description: Read sensor device
* @param sdev - sensor device pointer
@ -76,12 +104,27 @@ static int SensorDeviceOpen(struct SensorDevice *sdev)
*/
static int SensorDeviceRead(struct SensorDevice *sdev, size_t len)
{
int pin_fd=PinOpen();
struct PinStat pin_dir;
pin_dir.pin = SENSOR_DEVICE_QS_FS_PIN_NUMBER;
pin_dir.val = GPIO_HIGH;
if (PrivWrite(pin_fd,&pin_dir,0) < 0) // pull-up pin to configure as tx mode
return -1;
PrivTaskDelay(20);
if (PrivWrite(sdev->fd, instructions, sizeof(instructions)) < 0)
return -1;
PrivTaskDelay(20);
pin_dir.val = GPIO_LOW;
if (PrivWrite(pin_fd,&pin_dir,0) < 0) // pull-down pin to configure as rx mode
return -1;
if (PrivRead(sdev->fd, sdev->buffer, len) < 0)
return -1;
PrivClose(pin_fd);
return 0;
}
@ -124,7 +167,10 @@ static int32_t ReadWindSpeed(struct SensorQuantity *quant)
short result;
if (quant->sdev->done->read != NULL) {
if (quant->sdev->status == SENSOR_DEVICE_PASSIVE) {
quant->sdev->done->read(quant->sdev, 6);
quant->sdev->done->read(quant->sdev, 7);
if(Crc16(quant->sdev->buffer,7)!=0x00){
return -1;
}
result = (quant->sdev->buffer[3] << 8) | quant->sdev->buffer[4];
return (int32_t)result;

View File

@ -154,7 +154,6 @@ int PrivIoctl(int fd, int cmd, void *args)
{
int ret;
struct PrivIoctlCfg *ioctl_cfg = (struct PrivIoctlCfg *)args;
switch (ioctl_cfg->ioctl_driver_type)
{
case SERIAL_TYPE:
@ -163,17 +162,16 @@ int PrivIoctl(int fd, int cmd, void *args)
case PIN_TYPE:
ret = PrivPinIoctl(fd, cmd, ioctl_cfg->args);
break;
case I2C_TYPE:
ret = ioctl(fd, cmd, ioctl_cfg->args);
break;
case LCD_TYPE:
ret = PrivLcdIoctl(fd, cmd, ioctl_cfg->args);
break;
case I2C_TYPE:
case RTC_TYPE:
case ADC_TYPE:
case DAC_TYPE:
case WDT_TYPE:
case CAMERA_TYPE:
case KPU_TYPE:
ret = ioctl(fd, cmd, ioctl_cfg->args);
break;
default:

View File

@ -151,6 +151,7 @@ enum IoctlDriverType
WDT_TYPE,
RTC_TYPE,
CAMERA_TYPE,
KPU_TYPE,
DEFAULT_TYPE,
};
@ -227,6 +228,36 @@ struct RtcDrvConfigureParam
time_t *time;
};
typedef struct
{
uintptr_t pdata;
uint32_t length;
}_ioctl_shoot_para;
typedef struct
{
uint32_t width; // width The width of image
uint32_t height; // height The height of image
}_ioctl_set_reso;
typedef struct
{
uintptr_t r_addr;
uintptr_t g_addr;
uintptr_t b_addr;
}RgbAddress;
enum TCP_OPTION {
SEND_DATA = 0,
RECV_DATA,
};
typedef struct
{
uint8_t *buffer;
size_t length;
}KpuOutputBuffer;
#define PRIV_SYSTICK_GET (CurrentTicksGain())
#define PRIV_LCD_DEV "/dev/lcd_dev"
#define MY_DISP_HOR_RES BSP_LCD_Y_MAX
@ -236,6 +267,35 @@ struct RtcDrvConfigureParam
#define MY_INDEV_X BSP_LCD_Y_MAX
#define MY_INDEV_Y BSP_LCD_X_MAX
#define LCD_STRING_TYPE 0
#define LCD_DOT_TYPE 1
#define LCD_SIZE 320
#define IMAGE_HEIGHT 240
#define IMAGE_WIDTH 320
#define NULL_PARAMETER 0
#define REG_SCCB_READ 0xA2U
#define REG_SCCB_WRITE 0xA3U
#define SCCB_REG_LENGTH 0x08U
#define SET_DISPLAY_ADDR (0xD1)
#define SET_AI_ADDR (0xD2)
#define FLAG_CHECK (0xD4)
#define LOAD_KMODEL 0xA0
#define RUN_KMODEL 0xA1
#define GET_OUTPUT 0xA2
#define WAIT_FLAG 0xA3
#define IOCTRL_CAMERA_START_SHOT (22) // start shoot
#define IOCTRL_CAMERA_OUT_SIZE_RESO (23)
#define IOCTRL_CAMERA_SET_WINDOWS_SIZE (21) // user set specific windows outsize
#define IOCTRL_CAMERA_SET_LIGHT (24) //set light mode
#define IOCTRL_CAMERA_SET_COLOR (25) //set color saturation
#define IOCTRL_CAMERA_SET_BRIGHTNESS (26) //set color brightness
#define IOCTRL_CAMERA_SET_CONTRAST (27) //set contrast
#define IOCTRL_CAMERA_SET_EFFECT (28) //set effect
#define IOCTRL_CAMERA_SET_EXPOSURE (29) //set auto exposure
/*********************shell***********************/
//for int func(int argc, char *agrv[])
#define PRIV_SHELL_CMD_MAIN_ATTR (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN))

View File

@ -73,6 +73,12 @@ typedef int pid_t;
int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void));
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
int pthread_attr_init(pthread_attr_t *attr);
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size);
int pthread_attr_setschedparam(pthread_attr_t *attr,struct sched_param const *param);
int pthread_attr_setstack(pthread_attr_t *attr,
void *stack_base,
size_t stack_size);
void pthread_exit(void *value_ptr);
int pthread_detach(pthread_t thread);
int pthread_join(pthread_t thread, void **retval);

View File

@ -22,6 +22,10 @@
#include <stdio.h>
#include "include/pthread.h"
#define DEFAULT_STACK_SIZE 2048
#define DEFAULT_PRIORITY (KTASK_PRIORITY_MAX/2 + KTASK_PRIORITY_MAX/4)
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg)
{
@ -55,6 +59,28 @@ int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
}
int pthread_attr_init(pthread_attr_t *attr)
{
return 0;
}
int pthread_attr_setschedparam(pthread_attr_t *attr,
struct sched_param const *param)
{
NULL_PARAM_CHECK(attr != NULL);
NULL_PARAM_CHECK(param != NULL);
attr->schedparam.sched_priority = param->sched_priority;
return 0;
}
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size)
{
attr->stacksize = stack_size;
return 0;
}
void pthread_exit(void *value_ptr){
//todo add exit value
UserTaskQuit();

View File

@ -48,6 +48,7 @@ Modification:
#include "connect_w5500.h"
#include "connect_wdt.h"
#include "connect_dvp.h"
#include "connect_kpu.h"
#include "dmac.h"
#include "encoding.h"
#include "fpioa.h"
@ -70,6 +71,8 @@ extern int HwLcdInit(void);
extern int HwSpiInit(void);
extern int HwSoftSPIInit(void);
extern int HwWiznetInit(void);
extern int HwDvpInit(void);
extern int HwKpuInit(void);
#include <iot-vfs.h>
#ifdef MOUNT_USB
@ -220,6 +223,9 @@ struct InitSequenceDesc _board_init[] = {
#endif
#ifdef BSP_USING_CAMERA
{"hw_camera", HwDvpInit },
#endif
#ifdef BSP_USING_KPU
{"hw_kpu", HwKpuInit },
#endif
{ " NONE ",NONE },
};

View File

@ -123,9 +123,17 @@ menuconfig BSP_USING_WIZCHIP
menuconfig BSP_USING_CAMERA
bool "Using camera device"
default y
default n
select RESOURCES_CAMERA
if BSP_USING_CAMERA
source "$BSP_DIR/third_party_driver/dvp/Kconfig"
endif
menuconfig BSP_USING_KPU
bool "Using kpu device"
default n
select RESOURCES_KPU
if BSP_USING_KPU
source "$BSP_DIR/third_party_driver/kpu/Kconfig"
endif

View File

@ -59,9 +59,13 @@ endif
ifeq ($(CONFIG_BSP_USING_WIZCHIP),y)
SRC_DIR += ethernet
endif
ifeq ($(CONFIG_BSP_USING_CAMERA),y)
SRC_DIR += dvp
endif
ifeq ($(CONFIG_BSP_USING_KPU),y)
SRC_DIR += kpu
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -31,6 +31,7 @@
#include "utils.h"
#include "plic.h"
#include "stdlib.h"
#include <device.h>
volatile dmac_t *const dmac = (dmac_t *)DMAC_BASE_ADDR;
@ -172,6 +173,7 @@ void dmac_channel_disable(dmac_channel_number_t channel_num)
}
writeq(chen.data, &dmac->chen);
}
int32_t dmac_check_channel_busy(dmac_channel_number_t channel_num)
@ -766,26 +768,30 @@ void dmac_set_src_dest_length(dmac_channel_number_t channel_num, const void *src
dmac_channel_enable(channel_num);
}
static int dmac_irq_callback(void *ctx)
static int dmac_irq_callback(int vector,void *ctx)
{
dmac_context_t *v_dmac_context = (dmac_context_t *)(ctx);
dmac_channel_number_t v_dmac_channel = v_dmac_context->dmac_channel;
dmac_chanel_interrupt_clear(v_dmac_channel);
if(v_dmac_context->callback != NULL)
if(v_dmac_context->callback != NULL){
v_dmac_context->callback(v_dmac_context->ctx);
}
return 0;
}
void dmac_irq_register(dmac_channel_number_t channel_num , plic_irq_callback_t dmac_callback, void *ctx, uint32_t priority)
{
dmac_context[channel_num].dmac_channel = channel_num;
dmac_context[channel_num].callback = dmac_callback;
dmac_context[channel_num].ctx = ctx;
dmac_enable_channel_interrupt(channel_num);
plic_set_priority(IRQN_DMA0_INTERRUPT + channel_num, priority);
plic_irq_enable(IRQN_DMA0_INTERRUPT + channel_num);
plic_irq_register(IRQN_DMA0_INTERRUPT + channel_num, dmac_irq_callback, &dmac_context[channel_num]);
// plic_set_priority(IRQN_DMA0_INTERRUPT + channel_num, priority);
// plic_irq_enable(IRQN_DMA0_INTERRUPT + channel_num);
// plic_irq_register(IRQN_DMA0_INTERRUPT + channel_num, dmac_irq_callback, &dmac_context[channel_num]);
isrManager.done->enableIrq(IRQN_DMA0_INTERRUPT + channel_num);
isrManager.done->registerIrq(IRQN_DMA0_INTERRUPT + channel_num, (IsrHandlerType)dmac_irq_callback, &dmac_context[channel_num]);
}
void __attribute__((weak, alias("dmac_irq_register"))) dmac_set_irq(dmac_channel_number_t channel_num , plic_irq_callback_t dmac_callback, void *ctx, uint32_t priority);

View File

@ -6,9 +6,11 @@
#include "plic.h"
#include <ov2640.h>
#define REG_SCCB_READ 0x12U
#define REG_SCCB_WRITE 0x13U
#define SCCB_REG_LENGTH 0x08U
#define CONTINOUS_SHOOTS 1
#define ONLY_ONE_SHOOT 2
#define STOP_SHOOT 0
static int shoot_flag = 0; // shoot will close when shoot_flag == 0
// irq interrupt function
static int on_irq_dvp(int irq, void *arg)
@ -17,11 +19,16 @@ static int on_irq_dvp(int irq, void *arg)
{
dvp_clear_interrupt(DVP_STS_FRAME_FINISH);
}
else
{
dvp_start_convert();
else{
if(shoot_flag>0){
dvp_start_convert();
if(ONLY_ONE_SHOOT==shoot_flag){
shoot_flag=STOP_SHOOT;
}
}
dvp_clear_interrupt(DVP_STS_FRAME_START);
}
return 0;
}
@ -64,14 +71,14 @@ static uint32 DvpDrvInit(void)
#endif
#ifdef DVP_AI_OUTPUT
dvp_set_output_enable(DVP_OUTPUT_AI, 1);
dvp_set_ai_addr((uint32_t)DVP_AI_RED_ADRESS, (uint32_t)DVP_AI_GREEN_ADRESS, (uint32_t)DVP_AI_BLUE_ADRESS);
// dvp_set_ai_addr((uint32_t)DVP_AI_RED_ADRESS, (uint32_t)DVP_AI_GREEN_ADRESS, (uint32_t)DVP_AI_BLUE_ADRESS);
#endif
#ifdef DVP_INTERRUPT_ENABLE
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0);
isrManager.done->registerIrq(IRQN_DVP_INTERRUPT, (IsrHandlerType)on_irq_dvp, NULL);
isrManager.done->enableIrq(IRQN_DVP_INTERRUPT);
dvp_clear_interrupt(DVP_STS_FRAME_START | DVP_STS_FRAME_FINISH);
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 1);
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 0);
KPrintf("camera interrupt has open!\n");
#endif
return ret;
@ -115,25 +122,74 @@ static uint32 DvpRead(void *dev, struct BusBlockReadParam *read_param)
dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 0);
dvp_set_display_addr((uintptr_t)read_param->buffer);
dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 1);
shoot_flag=CONTINOUS_SHOOTS;
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 1);
return ret;
}
/**
* @brief configure api for dvp device
* TODO: unified APIs to keep consistent with RT-thread
*/
static uint32 DvpDrvConfigure(void *drv, struct BusConfigureInfo *args)
{
x_err_t ret = EOK;
int cmd_type = args->configure_cmd;
struct CameraCfg* tmp_cfg;
RgbAddress* kpu_rgb_address;
_ioctl_shoot_para* pixel_cfg;
int value = ((int*)args->private_data)[0];
switch (cmd_type)
{
case OPE_INT:
break;
case OPE_CFG:
tmp_cfg = (struct CameraCfg *)args->private_data;
SensorConfigure(tmp_cfg);
memcpy(&sensor_config,tmp_cfg,sizeof(struct CameraCfg));
SensorConfigure(&sensor_config);
dvp_set_image_size(tmp_cfg->output_w, tmp_cfg->output_h);
break;
case IOCTRL_CAMERA_START_SHOT:
pixel_cfg = (_ioctl_shoot_para*)args->private_data;
dvp_set_display_addr(pixel_cfg->pdata);
dvp_set_output_enable(DVP_OUTPUT_DISPLAY, 1);
dvp_config_interrupt(DVP_CFG_START_INT_ENABLE | DVP_CFG_FINISH_INT_ENABLE, 1);
shoot_flag=ONLY_ONE_SHOOT;
break;
case IOCTRL_CAMERA_OUT_SIZE_RESO:
dvp_set_image_size(((uint32_t*)args->private_data)[0], ((uint32_t*)args->private_data)[1]);
break;
case FLAG_CHECK:
*((int*)args->private_data) = shoot_flag;
break;
case SET_AI_ADDR:
kpu_rgb_address = (RgbAddress*)args->private_data;
dvp_set_output_enable(DVP_OUTPUT_AI, 1);
dvp_set_ai_addr(kpu_rgb_address->r_addr,kpu_rgb_address->g_addr,kpu_rgb_address->b_addr);
break;
// make compatible for rt-fusion xizi
case IOCTRL_CAMERA_SET_LIGHT:
ov2640_set_light_mode(value);
break;
case IOCTRL_CAMERA_SET_COLOR:
ov2640_set_color_saturation(value);
break;
case IOCTRL_CAMERA_SET_BRIGHTNESS:
ov2640_set_brightness(value);
break;
case IOCTRL_CAMERA_SET_CONTRAST:
ov2640_set_contrast(value);
break;
case IOCTRL_CAMERA_SET_EFFECT:
ov2640_set_special_effects(value);
break;
case IOCTRL_CAMERA_SET_EXPOSURE:
ov2640_set_auto_exposure(value);
break;
case REG_SCCB_READ:
ReadDvpReg(drv, (struct DvpRegConfigureInfo *)args->private_data);
break;

View File

@ -399,8 +399,8 @@ const uint8_t ov2640_config[][2]=
#else
const uint8_t ov2640_config[][2]=
{
{0x00,x00}
}
{0x00,0x00}
};
#endif
@ -447,7 +447,7 @@ int SensorConfigure(struct CameraCfg *cfg_info)
//set reg mode to dsp
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x01);
//configure dsp gain
if(cfg_info->gain_manu_enable){
reg_tmp = dvp_sccb_receive_data(OV2640_ADDR, 0x13);
@ -461,3 +461,399 @@ int SensorConfigure(struct CameraCfg *cfg_info)
return 1;
}
const uint8_t OV2640_AUTOEXPOSURE_LEVEL[5][8]=
{
{
0xFF,0x01,
0x24,0x20,
0x25,0x18,
0x26,0x60,
},
{
0xFF,0x01,
0x24,0x34,
0x25,0x1c,
0x26,0x00,
},
{
0xFF,0x01,
0x24,0x3e,
0x25,0x38,
0x26,0x81,
},
{
0xFF,0x01,
0x24,0x48,
0x25,0x40,
0x26,0x81,
},
{
0xFF,0x01,
0x24,0x58,
0x25,0x50,
0x26,0x92,
},
};
const uint8_t ov2640_yuv422_reg_tbl[][2] =
{
{0xFF, 0x00},
{0xDA, 0x10},
{0xD7, 0x03},
{0xDF, 0x00},
{0x33, 0x80},
{0x3C, 0x40},
{0xe1, 0x77},
{0x00, 0x00},
};
const uint8_t ov2640_jpeg_reg_tbl[][2]=
{
{0xff, 0x01},
{0xe0, 0x14},
{0xe1, 0x77},
{0xe5, 0x1f},
{0xd7, 0x03},
{0xda, 0x10},
{0xe0, 0x00},
};
const uint8_t ov2640_rgb565_reg_tbl[][2]=
{
{0xFF, 0x00},
{0xDA, 0x08},
{0xD7, 0x03},
{0xDF, 0x02},
{0x33, 0xa0},
{0x3C, 0x00},
{0xe1, 0x67},
{0xff, 0x01},
{0xe0, 0x00},
{0xe1, 0x00},
{0xe5, 0x00},
{0xd7, 0x00},
{0xda, 0x00},
{0xe0, 0x00},
};
/* change ov2640 to jpeg mode */
void ov2640_jpeg_mode(void)
{
uint16_t i=0;
/* set yun422 mode */
for (i = 0; i < (sizeof(ov2640_yuv422_reg_tbl) / 2); i++)
{
dvp_sccb_send_data(OV2640_ADDR, ov2640_yuv422_reg_tbl[i][0],ov2640_yuv422_reg_tbl[i][1]);
}
/* set jpeg mode */
for(i=0;i<(sizeof(ov2640_jpeg_reg_tbl)/2);i++)
{
dvp_sccb_send_data(OV2640_ADDR, ov2640_jpeg_reg_tbl[i][0],ov2640_jpeg_reg_tbl[i][1]);
}
}
/* change ov2640 to rgb565 mode */
void ov2640_rgb565_mode(void)
{
uint16_t i=0;
for (i = 0; i < (sizeof(ov2640_rgb565_reg_tbl) / 2); i++)
{
dvp_sccb_send_data(OV2640_ADDR, ov2640_rgb565_reg_tbl[i][0],ov2640_rgb565_reg_tbl[i][1]);
}
}
/* set auto exposure level value must be 0 ~4 */
void ov2640_set_auto_exposure(uint8_t level)
{
uint8_t i = 0;
uint8_t *p = (uint8_t*)OV2640_AUTOEXPOSURE_LEVEL[level];
for (i = 0; i < 4; i++)
{
dvp_sccb_send_data(OV2640_ADDR, p[i*2],p[i*2+1]);
}
}
/* set light mode
* 0: auto
* 1: sunny
* 2: cloudy
* 3: office
* 4: home
* */
void ov2640_set_light_mode(uint8_t mode)
{
uint8_t regccval, regcdval, regceval;
switch(mode)
{
case 0:
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0xC7, 0x10);
return;
case 2:
regccval = 0x65;
regcdval = 0x41;
regceval = 0x4F;
break;
case 3:
regccval = 0x52;
regcdval = 0x41;
regceval = 0x66;
break;
case 4:
regccval = 0x42;
regcdval = 0x3F;
regceval = 0x71;
break;
default:
regccval = 0x5E;
regcdval = 0x41;
regceval = 0x54;
break;
}
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0xC7, 0x40);
dvp_sccb_send_data(OV2640_ADDR, 0xCC, regccval);
dvp_sccb_send_data(OV2640_ADDR, 0xCD, regcdval);
dvp_sccb_send_data(OV2640_ADDR, 0xCE, regceval);
}
/* set color saturation
* 0: -2
* 1: -1
* 2: 0
* 3: +1
* 4: +2
* */
void ov2640_set_color_saturation(uint8_t sat)
{
uint8_t reg7dval = ((sat+2)<<4) | 0x08;
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0X00);
dvp_sccb_send_data(OV2640_ADDR, 0x7C, 0X00);
dvp_sccb_send_data(OV2640_ADDR, 0x7D, 0X02);
dvp_sccb_send_data(OV2640_ADDR, 0x7C, 0X03);
dvp_sccb_send_data(OV2640_ADDR, 0x7D, reg7dval);
dvp_sccb_send_data(OV2640_ADDR, 0x7D, reg7dval);
}
/* set brightness
* 0: -2
* 1: -1
* 2: 0
* 3: 1
* 4: 2
* */
void ov2640_set_brightness(uint8_t bright)
{
dvp_sccb_send_data(OV2640_ADDR, 0xff, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0x7c, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, 0x04);
dvp_sccb_send_data(OV2640_ADDR, 0x7c, 0x09);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, bright << 4);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, 0x00);
}
/* set contrast
* 0: -2
* 1: -1
* 2: 0
* 3: 1
* 4: 2
* */
void ov2640_set_contrast(uint8_t contrast)
{
uint8_t reg7d0val, reg7d1val;
switch(contrast)
{
case 0:
reg7d0val = 0x18;
reg7d1val = 0x34;
break;
case 1:
reg7d0val = 0x1C;
reg7d1val = 0x2A;
break;
case 3:
reg7d0val = 0x24;
reg7d1val = 0x16;
break;
case 4:
reg7d0val = 0x28;
reg7d1val = 0x0C;
break;
default:
reg7d0val = 0x20;
reg7d1val = 0x20;
break;
}
dvp_sccb_send_data(OV2640_ADDR, 0xff, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0x7c, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, 0x04);
dvp_sccb_send_data(OV2640_ADDR, 0x7c, 0x07);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, 0x20);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, reg7d0val);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, reg7d1val);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, 0x06);
}
/* set special effects
* 0: noraml
* 1: negative film
* 2: black-and-white
* 3: the red
* 4: the green
* 5: the blue
* 6: Retro
*/
void ov2640_set_special_effects(uint8_t eft)
{
uint8_t reg7d0val, reg7d1val, reg7d2val;
switch(eft)
{
case 1:
reg7d0val = 0x40;
break;
case 2:
reg7d0val = 0x18;
break;
case 3:
reg7d0val = 0x18;
reg7d1val = 0x40;
reg7d2val = 0xC0;
break;
case 4:
reg7d0val = 0x18;
reg7d1val = 0x40;
reg7d2val = 0x40;
break;
case 5:
reg7d0val = 0x18;
reg7d1val = 0xA0;
reg7d2val = 0x40;
break;
case 6:
reg7d0val = 0x18;
reg7d1val = 0x40;
reg7d2val = 0xA6;
break;
default:
reg7d0val = 0x00;
reg7d1val = 0x80;
reg7d2val = 0x80;
break;
}
dvp_sccb_send_data(OV2640_ADDR, 0xff, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0x7c, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, reg7d0val);
dvp_sccb_send_data(OV2640_ADDR, 0x7c, 0x05);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, reg7d1val);
dvp_sccb_send_data(OV2640_ADDR, 0x7d, reg7d2val);
}
/* set the image output window */
void ov2640_set_window_size(uint16_t sx,uint16_t sy,uint16_t width,uint16_t height)
{
uint16_t endx;
uint16_t endy;
uint8_t temp;
endx = sx + width / 2;
endy = sy + height / 2;
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x01);
temp = dvp_sccb_receive_data(OV2640_ADDR,0x03);
temp &= 0xF0;
temp |= ((endy & 0x03) << 2) | (sy & 0x03);
dvp_sccb_send_data(OV2640_ADDR, 0x03, temp);
dvp_sccb_send_data(OV2640_ADDR, 0x19, sy>>2);
dvp_sccb_send_data(OV2640_ADDR, 0x1A, endy>>2);
temp = dvp_sccb_receive_data(OV2640_ADDR,0x32);
temp &= 0xC0;
temp |= ((endx & 0x07) << 3) | (sx & 0x07);
dvp_sccb_send_data(OV2640_ADDR, 0x32, temp);
dvp_sccb_send_data(OV2640_ADDR, 0x17, sx>>3);
dvp_sccb_send_data(OV2640_ADDR, 0x18, endx>>3);
}
/* set the image output size */
uint8_t ov2640_set_image_out_size(uint16_t width,uint16_t height)
{
uint16_t outh, outw;
uint8_t temp;
if(width%4)return 1;
if(height%4)return 2;
outw = width /4;
outh = height/4;
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0xE0, 0x04);
dvp_sccb_send_data(OV2640_ADDR, 0x5A, outw & 0XFF);
dvp_sccb_send_data(OV2640_ADDR, 0x5B, outh & 0XFF);
temp = (outw >> 8) & 0x03;
temp |= (outh >> 6) & 0x04;
dvp_sccb_send_data(OV2640_ADDR, 0x5C, temp);
dvp_sccb_send_data(OV2640_ADDR, 0xE0, 0X00);
return 1;
}
/* set the image window size */
uint8_t ov2640_set_image_window_size(uint16_t offx, uint16_t offy, uint16_t width, uint16_t height)
{
uint16_t hsize, vsize;
uint8_t temp;
if ((width % 4) || (height%4))
{
return EOF;
}
hsize = width /4;
vsize = height/4;
dvp_sccb_send_data(OV2640_ADDR, 0XFF,0X00);
dvp_sccb_send_data(OV2640_ADDR, 0XE0,0X04);
dvp_sccb_send_data(OV2640_ADDR, 0X51,hsize&0XFF);
dvp_sccb_send_data(OV2640_ADDR, 0X52,vsize&0XFF);
dvp_sccb_send_data(OV2640_ADDR, 0X53,offx&0XFF);
dvp_sccb_send_data(OV2640_ADDR, 0X54,offy&0XFF);
temp=(vsize>>1)&0X80;
temp|=(offy>>4)&0X70;
temp|=(hsize>>5)&0X08;
temp|=(offx>>8)&0X07;
dvp_sccb_send_data(OV2640_ADDR, 0X55,temp); //
dvp_sccb_send_data(OV2640_ADDR, 0X57,(hsize>>2)&0X80); //
dvp_sccb_send_data(OV2640_ADDR, 0XE0,0X00);
return 0;
}
/* set output resolution */
uint8_t ov2640_set_image_size(uint16_t width ,uint16_t height)
{
uint8_t temp;
dvp_sccb_send_data(OV2640_ADDR, 0xFF, 0x00);
dvp_sccb_send_data(OV2640_ADDR, 0xE0, 0x04);
dvp_sccb_send_data(OV2640_ADDR, 0xC0, (width >>3) & 0xFF);
dvp_sccb_send_data(OV2640_ADDR, 0xC1, (height >> 3) & 0xFF);
temp = (width & 0x07) << 3;
temp |= height & 0x07;
temp |= (width >> 4) & 0x80;
dvp_sccb_send_data(OV2640_ADDR, 0x8C, temp);
dvp_sccb_send_data(OV2640_ADDR, 0xE0, 0x00);
return 1;
}

View File

@ -22,13 +22,12 @@ extern void spi_select_cs(void);
extern void spi_deselete_cs(void);
// global configurations for w5500 tcp connection
const uint32_t socket_tcp = 0;
const uint32_t g_wiznet_buf_size = 2048;
static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11},
.ip = {192, 168, 31, 13},
.sn = {255, 255, 255, 0},
.gw = {192, 168, 31, 1},
.ip = {192, 168, 131, 42},
.sn = {255, 255, 254, 0},
.gw = {192, 168, 130, 1},
.dns = {0, 0, 0, 0},
.dhcp = NETINFO_STATIC};
@ -269,27 +268,27 @@ uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size,
enum TCP_OPTION opt) {
// assert(buf_size <= g_wiznet_buf_size);
int32_t ret;
switch (getSn_SR(socket_tcp)) {
switch (getSn_SR(sn)) {
case SOCK_CLOSE_WAIT:
wiz_sock_disconnect(socket_tcp);
wiz_sock_disconnect(sn);
break;
case SOCK_CLOSED:
wiz_socket(socket_tcp, Sn_MR_TCP, 5000, 0x00);
wiz_socket(sn, Sn_MR_TCP, 5000, 0x00);
break;
case SOCK_INIT:
KPrintf("[SOCKET CLIENT] sock init.\n");
wiz_sock_connect(socket_tcp, dst_ip, dst_port);
wiz_sock_connect(sn, dst_ip, dst_port);
break;
case SOCK_ESTABLISHED:
if (getSn_IR(socket_tcp) & Sn_IR_CON) {
printf("[SOCKET CLIENT] %d:Connected\r\n", socket_tcp);
setSn_IR(socket_tcp, Sn_IR_CON);
if (getSn_IR(sn) & Sn_IR_CON) {
printf("[SOCKET CLIENT] %d:Connected\r\n", sn);
setSn_IR(sn, Sn_IR_CON);
}
if (opt == SEND_DATA) {
uint32_t sent_size = 0;
ret = wiz_sock_send(socket_tcp, buf, buf_size);
ret = wiz_sock_send(sn, buf, buf_size);
if (ret < 0) {
wiz_sock_close(socket_tcp);
wiz_sock_close(sn);
return ret;
}
} else if (opt == RECV_DATA) {
@ -348,9 +347,9 @@ int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size,
}
if (opt == SEND_DATA) {
uint32_t sent_size = 0;
ret = wiz_sock_send(socket_tcp, buf, buf_size);
ret = wiz_sock_send(sn, buf, buf_size);
if (ret < 0) {
wiz_sock_close(socket_tcp);
wiz_sock_close(sn);
return ret;
}
} else if (opt == RECV_DATA) {
@ -473,33 +472,52 @@ void ifconfig() {
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC),
ifconfig, ifconfig, printf w5500 configurations);
void char_arr_assign(uint8_t **dst, uint32_t *src, uint32_t len) {
void char_arr_assign(uint8_t *dst, uint32_t *src, int len) {
for (int i = 0; i < len; ++i) {
(*dst)[i] = (uint8_t)(src[i]);
dst[i] = (uint8_t)(src[i]);
}
}
void config_w5500_network(char *mac, char *ip, char *sn, char *gw, char *dns) {
char *network_param_name[] = {"ip", "sn", "gw"};
void config_w5500_network(int argc, char *argv[]) {
if (argc < 2) {
KPrintf("[W5500] Network config require params.\n");
return;
}
wiz_NetInfo wiz_netinfo;
uint32_t tmp_arr[4];
// config netinfo
sscanf(mac, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2],
&tmp_arr[3]);
char_arr_assign((uint8_t **)&wiz_netinfo.mac, tmp_arr, 4);
sscanf(ip, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]);
char_arr_assign((uint8_t **)&wiz_netinfo.ip, tmp_arr, 4);
sscanf(sn, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]);
char_arr_assign((uint8_t **)&wiz_netinfo.sn, tmp_arr, 4);
sscanf(gw, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2], &tmp_arr[3]);
char_arr_assign((uint8_t **)&wiz_netinfo.gw, tmp_arr, 4);
sscanf(dns, "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], &tmp_arr[2],
&tmp_arr[3]);
char_arr_assign((uint8_t **)&wiz_netinfo.dns, tmp_arr, 4);
// set new netinfo
memcpy(&wiz_netinfo, &g_wiz_netinfo, sizeof(wiz_NetInfo));
int cur_arg_idx = 1;
while (argv[cur_arg_idx] != NULL) {
if (argv[cur_arg_idx + 1] == NULL) {
KPrintf("[W5500] Network config %s requires value.\n", argv[cur_arg_idx]);
return;
}
uint32_t tmp_arr[4];
sscanf(argv[cur_arg_idx + 1], "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1],
&tmp_arr[2], &tmp_arr[3]);
if (memcmp(argv[cur_arg_idx], network_param_name[0], 2 * sizeof(char)) ==
0) {
char_arr_assign(wiz_netinfo.ip, tmp_arr, 4);
} else if (memcmp(argv[cur_arg_idx], network_param_name[1],
2 * sizeof(char)) == 0) {
char_arr_assign(wiz_netinfo.sn, tmp_arr, 4);
} else if (memcmp(argv[cur_arg_idx], network_param_name[2],
2 * sizeof(char)) == 0) {
char_arr_assign(wiz_netinfo.gw, tmp_arr, 4);
} else {
KPrintf("[W5500] Invalid network param.\n");
}
cur_arg_idx += 2;
}
ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo);
KPrintf("[W5500] Network config success.\n", argv[cur_arg_idx]);
ifconfig();
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) |
SHELL_CMD_PARAM_NUM(5),
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
config_w5500_network, config_w5500_network,
set w5500 configurations);

View File

@ -50,6 +50,11 @@ static struct io_config
IOCONFIG(BSP_LCD_RST_PIN, HS_GPIO(FPIOA_LCD_RST)),
#endif
#ifdef BSP_USING_W5500
IOCONFIG(BSP_WIZ_RST_PIN, HS_GPIO(WIZ_RST_PIN)),
IOCONFIG(BSP_WIZ_INT_PIN, HS_GPIO(WIZ_INT_PIN)),
#endif
#ifdef BSP_USING_SPI1
IOCONFIG(BSP_SPI1_CLK_PIN, FUNC_SPI1_SCLK),
IOCONFIG(BSP_SPI1_D0_PIN, FUNC_SPI1_D0),
@ -106,16 +111,20 @@ static struct io_config
IOCONFIG(BSP_E220_M1_PIN, HS_GPIO(FUNC_GPIOHS11)),
#endif
#ifdef BSP_USING_RS485
IOCONFIG(BSP_485_DIR_PIN,HS_GPIO(FUNC_GPIOHS12));
#ifdef USER_TEST_RS485
IOCONFIG(BSP_485_DIR_PIN,HS_GPIO(FUNC_GPIOHS12)),
#elif defined SENSOR_QS_FX
IOCONFIG(BSP_485_DIR_PIN,HS_GPIO(FUNC_GPIOHS12)),
#elif defined SENSOR_QS_FS
IOCONFIG(BSP_485_DIR_PIN,HS_GPIO(FUNC_GPIOHS12)),
#endif
#ifdef BSP_USING_LED
IOCONFIG(BSP_LED_PIN,FUNC_GPIO5);
IOCONFIG(BSP_LED_PIN,FUNC_GPIO5),
#endif
#ifdef BSP_USING_KEY
IOCONFIG(BSP_KEY_PIN,FUNC_GPIO6);
IOCONFIG(BSP_KEY_PIN,FUNC_GPIO6),
#endif
};

View File

@ -25,6 +25,44 @@
extern "C" {
#endif
#define REG_SCCB_READ 0xA2U
#define REG_SCCB_WRITE 0xA3U
#define SCCB_REG_LENGTH 0x08U
#define SET_DISPLAY_ADDR (0xD1)
#define SET_AI_ADDR (0xD2)
#define FLAG_CHECK (0xD4)
#define IOCTRL_CAMERA_START_SHOT (22) // start shoot
#define IOCTRL_CAMERA_OUT_SIZE_RESO (23)
#define IOCTRL_CAMERA_SET_WINDOWS_SIZE (21) // user set specific windows outsize
#define IOCTRL_CAMERA_SET_LIGHT (24) //set light mode
#define IOCTRL_CAMERA_SET_COLOR (25) //set color saturation
#define IOCTRL_CAMERA_SET_BRIGHTNESS (26) //set color brightness
#define IOCTRL_CAMERA_SET_CONTRAST (27) //set contrast
#define IOCTRL_CAMERA_SET_EFFECT (28) //set effect
#define IOCTRL_CAMERA_SET_EXPOSURE (29) //set auto exposure
typedef struct
{
uintptr_t r_addr;
uintptr_t g_addr;
uintptr_t b_addr;
}RgbAddress;
typedef struct
{
uintptr_t pdata;
uint32_t length;
}_ioctl_shoot_para;
typedef struct
{
uint32_t width; // width The width of image
uint32_t height; // height The height of image
}_ioctl_set_reso;
int HwDvpInit(void);
#ifdef __cplusplus

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_dvp.h
* @brief define edu-riscv64-board DVP init function
* @version 2.0
* @author AIIT XUOS Lab
* @date 2022-11-21
*/
#ifndef CONNECT_DVP_H
#define CONNECT_DVP_H
#include <device.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint8_t *buffer;
size_t length;
}KpuOutputBuffer;
int HwKpuInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -47,7 +47,8 @@ enum HS_GPIO_CONFIG {
SPI1_CS3_PIN,
#endif
#ifdef BSP_USING_W5500
WIZ_RST_PIN, WIZ_INT_PIN,
WIZ_RST_PIN,
WIZ_INT_PIN,
#endif
GPIO_ALLOC_START /* index of gpio driver start */
}
@ -97,7 +98,11 @@ enum HS_GPIO_CONFIG {
#define BSP_E220_M1_PIN 33
#endif
#ifdef BSP_USING_RS485
#ifdef USER_TEST_RS485
#define BSP_485_DIR_PIN 24
#elif defined SENSOR_QS_FX
#define BSP_485_DIR_PIN 24
#elif defined SENSOR_QS_FS
#define BSP_485_DIR_PIN 24
#endif

View File

@ -0,0 +1,930 @@
/* Copyright 2018 Canaan Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _KPU_H
#define _KPU_H
#include <stdint.h>
#include <plic.h>
#include "dmac.h"
#define kpu_matmul_begin kpu_conv2d_output
typedef int (*plic_irq_callback_t)(void *ctx);
typedef struct
{
union
{
uint64_t reg;
struct
{
uint64_t int_en:1;
uint64_t ram_flag:1;
uint64_t full_add:1;
uint64_t depth_wise_layer:1;
uint64_t reserved:60;
} data;
} interrupt_enabe;
union
{
uint64_t reg;
struct
{
uint64_t image_src_addr:15;
uint64_t reserved0:17;
uint64_t image_dst_addr:15;
uint64_t reserved1:17;
} data;
} image_addr;
union
{
uint64_t reg;
struct
{
uint64_t i_ch_num:10;
uint64_t reserved0:22;
uint64_t o_ch_num:10;
uint64_t reserved1:6;
uint64_t o_ch_num_coef:10;
uint64_t reserved2:6;
} data;
} image_channel_num;
union
{
uint64_t reg;
struct
{
uint64_t i_row_wid:10;
uint64_t i_col_high:9;
uint64_t reserved0:13;
uint64_t o_row_wid:10;
uint64_t o_col_high:9;
uint64_t reserved1:13;
} data;
} image_size;
union
{
uint64_t reg;
struct
{
uint64_t kernel_type:3;
uint64_t pad_type:1;
uint64_t pool_type:4;
uint64_t first_stride:1;
uint64_t bypass_conv:1;
uint64_t load_para:1;
uint64_t reserved0:5;
uint64_t dma_burst_size:8;
uint64_t pad_value:8;
uint64_t bwsx_base_addr:32;
} data;
} kernel_pool_type_cfg;
union
{
uint64_t reg;
struct
{
uint64_t load_coor:1;
uint64_t load_time:6;
uint64_t reserved0:8;
uint64_t para_size:17;
uint64_t para_start_addr:32;
} data;
} kernel_load_cfg;
union
{
uint64_t reg;
struct
{
uint64_t coef_column_offset:4;
uint64_t coef_row_offset:12;
uint64_t reserved0:48;
} data;
} kernel_offset;
union
{
uint64_t reg;
struct
{
uint64_t channel_switch_addr:15;
uint64_t reserved:1;
uint64_t row_switch_addr:4;
uint64_t coef_size:8;
uint64_t coef_group:3;
uint64_t load_act:1;
uint64_t active_addr:32;
} data;
} kernel_calc_type_cfg;
union
{
uint64_t reg;
struct
{
uint64_t wb_channel_switch_addr:15;
uint64_t reserved0:1;
uint64_t wb_row_switch_addr:4;
uint64_t wb_group:3;
uint64_t reserved1:41;
} data;
} write_back_cfg;
union
{
uint64_t reg;
struct
{
uint64_t shr_w:4;
uint64_t shr_x:4;
uint64_t arg_w:24;
uint64_t arg_x:24;
uint64_t reserved0:8;
} data;
} conv_value;
union
{
uint64_t reg;
struct
{
uint64_t arg_add:40;
uint64_t reserved:24;
} data;
} conv_value2;
union
{
uint64_t reg;
struct
{
uint64_t send_data_out:1;
uint64_t reserved:15;
uint64_t channel_byte_num:16;
uint64_t dma_total_byte:32;
} data;
} dma_parameter;
} kpu_layer_argument_t;
typedef struct
{
union
{
uint64_t reg;
struct
{
uint64_t shift_number:8;
uint64_t y_mul:16;
uint64_t x_start:36;
} data;
} activate_para[16];
union
{
uint64_t reg;
struct
{
uint8_t result_bias[8];
} data;
} activate_para_bias0;
union
{
uint64_t reg;
struct
{
uint8_t result_bias[8];
} data;
} activate_para_bias1;
} kpu_activate_table_t;
typedef struct
{
union
{
uint64_t reg;
struct
{
uint64_t norm_mul:24;
uint64_t norm_add:32;
uint64_t norm_shift:4;
} data;
} batchnorm;
} kpu_batchnorm_argument_t;
typedef struct
{
union
{
uint64_t reg;
struct
{
uint16_t weight[9];
} data;
} weights;
} kpu_weights_kernel_16_3x3_t;
typedef struct
{
uint64_t calc_done_int:1;
uint64_t layer_cfg_almost_empty_int:1;
uint64_t layer_cfg_almost_full_int:1;
uint64_t reserved:61;
} kpu_config_interrupt_t;
typedef struct
{
uint64_t fifo_full_threshold:4;
uint64_t fifo_empty_threshold:4;
uint64_t reserved:56;
} kpu_config_fifo_threshold_t;
typedef struct
{
uint64_t dma_fifo_flush_n:1;
uint64_t gs_fifo_flush_n:1;
uint64_t cfg_fifo_flush_n:1;
uint64_t cmd_fifo_flush_n:1;
uint64_t resp_fifo_flush_n:1;
uint64_t reserved:59;
} kpu_config_fifo_ctrl_t;
typedef struct
{
uint64_t eight_bit_mode:1;
uint64_t reserved:63;
} kpu_config_eight_bit_mode_t;
typedef struct
{
volatile uint64_t layer_argument_fifo;
volatile union
{
uint64_t reg;
kpu_config_interrupt_t data;
} interrupt_status;
volatile union
{
uint64_t reg;
kpu_config_interrupt_t data;
} interrupt_raw;
volatile union {
uint64_t reg;
kpu_config_interrupt_t data;
} interrupt_mask;
volatile union
{
uint64_t reg;
kpu_config_interrupt_t data;
} interrupt_clear;
volatile union
{
uint64_t reg;
kpu_config_fifo_threshold_t data;
} fifo_threshold;
volatile uint64_t fifo_data_out;
volatile union
{
uint64_t reg;
kpu_config_fifo_ctrl_t data;
} fifo_ctrl;
volatile union
{
uint64_t reg;
kpu_config_eight_bit_mode_t data;
} eight_bit_mode;
} kpu_config_t;
typedef struct
{
kpu_layer_argument_t *layers;
kpu_layer_argument_t *remain_layers;
plic_irq_callback_t callback;
void *ctx;
uint64_t *src;
uint64_t *dst;
uint32_t src_length;
uint32_t dst_length;
uint32_t layers_length;
uint32_t remain_layers_length;
dmac_channel_number_t dma_ch;
uint32_t eight_bit_mode;
float output_scale;
float output_bias;
float input_scale;
float input_bias;
} kpu_task_t;
typedef struct
{
uint32_t version;
uint32_t flags;
uint32_t arch;
uint32_t layers_length;
uint32_t max_start_address;
uint32_t main_mem_usage;
uint32_t output_count;
} kpu_kmodel_header_t;
typedef struct
{
uint32_t version;
uint32_t flags;
uint32_t layers_length;
uint32_t max_start_address;
uint32_t layers_argument_start;
} kpu_model_header_t;
typedef struct
{
uint32_t address;
uint32_t size;
} kpu_model_output_t;
typedef enum
{
KL_INVALID = 0,
KL_ADD,
KL_QUANTIZED_ADD,
KL_GLOBAL_MAX_POOL2D,
KL_QUANTIZED_GLOBAL_MAX_POOL2D,
KL_GLOBAL_AVERAGE_POOL2D,
KL_QUANTIZED_GLOBAL_AVERAGE_POOL2D,
KL_MAX_POOL2D,
KL_QUANTIZED_MAX_POOL2D,
KL_AVERAGE_POOL2D,
KL_QUANTIZED_AVERAGE_POOL2D,
KL_QUANTIZE,
KL_DEQUANTIZE,
KL_REQUANTIZE,
KL_L2_NORMALIZATION,
KL_SOFTMAX,
KL_CONCAT,
KL_QUANTIZED_CONCAT,
KL_FULLY_CONNECTED,
KL_QUANTIZED_FULLY_CONNECTED,
KL_TENSORFLOW_FLATTEN,
KL_QUANTIZED_TENSORFLOW_FLATTEN,
KL_RESIZE_NEAREST_NEIGHBOR,
KL_QUANTIZED_RESIZE_NEAREST_NEIGHBOR,
KL_CHANNELWISE_DEQUANTIZE,
KL_K210_CONV = 10240,
KL_K210_ADD_PADDING,
KL_K210_REMOVE_PADDING,
KL_K210_UPLOAD
} kpu_model_layer_type_t;
typedef struct
{
uint32_t type;
uint32_t body_size;
} kpu_model_layer_header_t;
typedef enum
{
KLF_NONE = 0,
KLF_MAIN_MEM_OUT = 1
} kpu_model_layer_flags_t;
typedef enum
{
KLP_SAME = 0,
KLP_VALID = 1
} kpu_model_padding_t;
typedef enum
{
KLA_LINEAR = 0,
KLA_RELU = 1,
KLA_RELU6 = 2
} kpu_model_activation_t;
typedef struct
{
float scale;
float bias;
} kpu_model_quant_param_t;
typedef struct
{
uint32_t width;
uint32_t height;
uint32_t channels;
} kpu_model_shape_t;
typedef struct
{
uint32_t start;
uint32_t size;
} kpu_model_memory_range_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_out_address;
uint32_t layer_offset;
uint32_t weights_offset;
uint32_t bn_offset;
uint32_t act_offset;
} kpu_model_conv_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_a_address;
uint32_t main_mem_in_b_address;
uint32_t main_mem_out_address;
uint32_t count;
} kpu_model_add_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_a_address;
uint32_t main_mem_in_b_address;
uint32_t main_mem_out_address;
uint32_t count;
int32_t in_a_offset;
int32_t in_a_mul;
int32_t in_a_shift;
int32_t in_b_offset;
int32_t in_b_mul;
int32_t in_b_shift;
int32_t out_offset;
int32_t out_mul;
int32_t out_shift;
} kpu_model_quant_add_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
uint32_t kernel_size;
uint32_t channels;
} kpu_model_gap2d_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
kpu_model_shape_t in_shape;
kpu_model_shape_t out_shape;
uint32_t kernel_width;
uint32_t kernel_height;
uint32_t stride_width;
uint32_t stride_height;
uint32_t padding_width;
uint32_t padding_height;
} kpu_model_quant_max_pool2d_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
kpu_model_shape_t in_shape;
kpu_model_shape_t out_shape;
uint32_t kernel_width;
uint32_t kernel_height;
uint32_t stride_width;
uint32_t stride_height;
uint32_t padding_width;
uint32_t padding_height;
kpu_model_activation_t act;
} kpu_model_ave_pool2d_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t mem_out_address;
uint32_t count;
kpu_model_quant_param_t quant_param;
} kpu_model_quantize_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
uint32_t count;
kpu_model_quant_param_t quant_param;
} kpu_model_dequantize_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
uint32_t count;
uint8_t table[256];
} kpu_model_requantize_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t kpu_mem_out_address;
uint32_t channels;
} kpu_model_add_padding_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
uint32_t channels;
} kpu_model_remove_padding_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t kpu_mem_out_address;
uint32_t width;
uint32_t height;
uint32_t channels;
} kpu_model_upload_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
uint32_t channels;
} kpu_model_l2_norm_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
uint32_t channels;
} kpu_model_softmax_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_out_address;
uint32_t input_count;
kpu_model_memory_range_t inputs_mem[0];
} kpu_model_concat_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
uint32_t in_channels;
uint32_t out_channels;
kpu_model_activation_t act;
float weights[0];
} kpu_model_fully_connected_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
kpu_model_shape_t shape;
} kpu_model_tf_flatten_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
kpu_model_shape_t in_shape;
uint32_t out_width;
uint32_t out_height;
uint32_t align_corners;
} kpu_model_resize_nearest_neighbor_layer_argument_t;
typedef struct
{
uint32_t flags;
uint32_t main_mem_in_address;
uint32_t main_mem_out_address;
uint32_t channels;
uint32_t channel_size;
kpu_model_quant_param_t quant_params[0];
} kpu_model_channelwise_dequant_argument_t;
typedef void(*kpu_done_callback_t)(void* userdata);
typedef struct
{
const uint8_t *model_buffer;
uint8_t *main_buffer;
uint32_t output_count;
const kpu_model_output_t *outputs;
const kpu_model_layer_header_t *layer_headers;
const uint8_t *body_start;
uint32_t layers_length;
volatile uint32_t current_layer;
const uint8_t * volatile current_body;
dmac_channel_number_t dma_ch;
kpu_done_callback_t done_callback;
void *userdata;
} kpu_model_context_t;
typedef struct
{
uint32_t weigths_offset;
uint32_t bn_offset;
uint32_t act_offset;
float input_scale;
float input_bias;
float output_scale;
float output_bias;
} kpu_model_layer_metadata_t;
typedef struct _quantize_param
{
float scale;
float bias;
} quantize_param_t;
extern volatile kpu_config_t *const kpu;
/**
* @brief Modle complier init kpu handler
*
* @param[in] task Kpu handler
*
* @return Kpu handler
*/
extern kpu_task_t *kpu_task_init(kpu_task_t* task);
/**
* @brief Kpu run for AI
*
* @param[in] task Kpu handler
* @param[in] dma_ch DMA for kpu
* @param[in] src The picture data
* @param[in] dest The result of kpu
* @param[in] callback The callback of kpu
*
* @return result
* - 0 Success
* - Other Fail.Kpu is busy.
*/
int kpu_run(kpu_task_t* task, dmac_channel_number_t dma_ch, const void *src, void* dest, plic_irq_callback_t callback);
/**
* @brief Get kpu result buf
*
* @param[in] task Kpu handler
*
* @return Kpu result buf
*/
uint8_t *kpu_get_output_buf(kpu_task_t* task);
/**
* @brief Release kpu output buf
*
* @param[in] output_buf Kpu output buf
*
*/
void kpu_release_output_buf(uint8_t *output_buf);
/**
* @brief Kpu run for AI
*
* @param[in] task Kpu handler
*
* @return result
* - 0 Success
* - Other Fail.Kpu is busy.
*/
int kpu_start(kpu_task_t *task);
/**
* @brief Initialize kpu handler
*
* @param[in] task Kpu handler
*
* @return result
* - 0 Success
* - Other Fail.
*/
int kpu_single_task_init(kpu_task_t *task);
/**
* @brief Uninitialize kpu handler
*
* @param[in] task Kpu handler
*
* @return result
* - 0 Success
* - Other Fail.
*/
int kpu_single_task_deinit(kpu_task_t *task);
/**
* @brief Load kmodel and init kpu task
*
* @param[in] task Kpu handler
* @param[in] buffer Kmodel
* @param[in] meta Test data
*
* @return result
* - 0 Success
* - Other Fail.
*/
int kpu_model_load_from_buffer(kpu_task_t *task, uint8_t *buffer, kpu_model_layer_metadata_t **meta);
/**
* @brief Kpu initialize
*
* @param[in] eight_bit_mode 0:16bit mode 1:8bit mode
* @param[in] callback Callback of kpu
* @param[in] userdata Data of callback
*
*/
void kpu_init(int eight_bit_mode, plic_irq_callback_t callback, void *userdata);
/**
* @brief Kpu input data by dma
*
* @param[in] layer Kpu task layer
* @param[in] src Image data
* @param[in] dma_ch Dmac channel
* @param[in] callback Dmac complete callback
* @param[in] userdata Data of callback
*
*/
void kpu_input_dma(const kpu_layer_argument_t *layer, const uint8_t *src, dmac_channel_number_t dma_ch, plic_irq_callback_t callback, void *userdata);
/**
* @brief Kpu input data by cpu
*
* @param[in] layer Kpu task layer
* @param[in] src Image data
* @param[in] width Image width
* @param[in] height Image heigth
* @param[in] channels Color channel, RGB is 3
*
*/
void kpu_input_with_padding(kpu_layer_argument_t *layer, const uint8_t *src, int width, int height, int channels);
/**
* @brief Kpu run only one layer
*
* @param[in] layer Kpu task layer
*
*/
void kpu_conv2d(kpu_layer_argument_t *layer);
/**
* @brief Kpu run only one layer then get the result by dma
*
* @param[in] layer Kpu task layer
* @param[in] dma_ch Dmac channel
* @param[in] dest Result
* @param[in] callback Dmac complete callback
* @param[in] userdata Data of callback
*
*/
void kpu_conv2d_output(kpu_layer_argument_t *layer, dmac_channel_number_t dma_ch, uint8_t *dest, plic_irq_callback_t callback, void *userdata);
/**
* @brief Kpu pooling
*
* @param[in] src Source
* @param[in] src_param Source param
* @param[in] kernel_size Kernel size, 7*7 is 49
* @param[in] channels Channels
* @param[in] dest Dest
* @param[in] dest_param Dest param
*
*/
void kpu_global_average_pool(const uint8_t *src, const quantize_param_t *src_param, int kernel_size, int channels, uint8_t *dest, const quantize_param_t *dest_param);
/**
* @brief Kpu pooling
*
* @param[in] src Source
* @param[in] src_param Source param
* @param[in] kernel_size Kernel size, 7*7 is 49
* @param[in] channels Channels
* @param[in] dest Dest
*
*/
void kpu_global_average_pool_float(const uint8_t *src, const quantize_param_t *src_param, int kernel_size, int channels, float *dest);
/**
* @brief Kpu fullly connected by cpu
*
* @param[in] src Source
* @param[in] weights Weight
* @param[in] biases Biases
* @param[in] dest Dest
* @param[in] input_channels Input channels
* @param[in] output_channels Output channels
*
*/
void kpu_fully_connected(const float *src, const float *weights, const float *biases, float *dest, int input_channels, int output_channels);
/**
* @brief Kpu matrix multiplication
*
* @param[in] src Source
* @param[in] channels Channels
* @param[in] dest Dest
* @param[in] dest_param Dest param
*
*/
void kpu_matmul_end(const uint8_t *src, int channels, float *dest, const quantize_param_t *dest_param);
/**
* @brief Kpu dequantize
*
* @param[in] src Source
* @param[in] src_param Source param
* @param[in] count Dequantize count
* @param[in] dest Dest
*
*/
void kpu_dequantize(const uint8_t *src, const quantize_param_t *src_param, size_t count, float *dest);
/**
* @brief Kpu load kmodel
*
* @param[in] ctx Kmodel object
* @param[in] buffer Kmodel buffer
*
* @return result
* - 0 Success
* - Other Fail.
*/
int kpu_load_kmodel(kpu_model_context_t *ctx, const uint8_t *buffer);
/**
* @brief Kpu free kmodel buffer
*
* @param[in] ctx kmodel object
*
*/
void kpu_model_free(kpu_model_context_t *ctx);
/**
* @brief Kpu load kmodel
*
* @param[in] ctx Kmodel object
* @param[in] index Output index
* @param[in] data Output data
* @param[in] size Output data size
*
* @return result
* - 0 Success
* - Other Fail.
*/
int kpu_get_output(kpu_model_context_t *ctx, uint32_t index, uint8_t **data, size_t *size);
/**
* @brief Kpu run kmodel
*
* @param[in] ctx Kmodel object
* @param[in] src Source data
* @param[in] dma_ch Dma channel
* @param[in] done_callback Kpu complete callback
* @param[in] userdata Data of callback
*
* @return result
* - 0 Success
* - Other Fail.
*/
int kpu_run_kmodel(kpu_model_context_t *ctx, const uint8_t *src, dmac_channel_number_t dma_ch, kpu_done_callback_t done_callback, void *userdata);
#endif

View File

@ -34,5 +34,17 @@ struct CameraCfg
int ov2640_init(void);
int ov2640_read_id(uint16_t *manuf_id, uint16_t *device_id);
int SensorConfigure(struct CameraCfg* cfg_info);
void ov2640_jpeg_mode(void);
void ov2640_rgb565_mode(void);
void ov2640_set_auto_exposure(uint8_t level);
void ov2640_set_light_mode(uint8_t mode);
void ov2640_set_color_saturation(uint8_t sat);
void ov2640_set_brightness(uint8_t bright);
void ov2640_set_contrast(uint8_t contrast);
void ov2640_set_special_effects(uint8_t eft);
void ov2640_set_window_size(uint16_t sx,uint16_t sy,uint16_t width,uint16_t height);
uint8_t ov2640_set_image_out_size(uint16_t width,uint16_t height);
uint8_t ov2640_set_image_window_size(uint16_t offx, uint16_t offy, uint16_t width, uint16_t height);
uint8_t ov2640_set_image_size(uint16_t width ,uint16_t height);
#endif /* _OV2640_H */

View File

@ -0,0 +1,15 @@
if BSP_USING_KPU
config KPU_DMA_CH
int "KPU DMA channel number"
default 5
config KPU_BUS_NAME
string "kpu bus name"
default "kpu"
config KPU_DRV_NAME
string "kpu driver name"
default "kpu_drv"
config KPU_DEVICE_NAME
string "kpu device name"
default "kpu_dev"
endif

View File

@ -0,0 +1,4 @@
SRC_FILES := kpu.c connect_kpu.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,170 @@
#include <connect_kpu.h>
#include <kpu.h>
#include <board.h>
#include "bsp.h"
#define LOAD_KMODEL 0xA0
#define RUN_KMODEL 0xA1
#define GET_OUTPUT 0xA2
#define WAIT_FLAG 0xA3
static kpu_model_context_t kpu_task;
static int g_ai_done_flag = 0;
// irq interrupt function
static void ai_done(void *ctx)
{
g_ai_done_flag = 1;
}
struct KpuRegConfigureInfo
{
uint8_t device_addr;
uint16_t reg_addr;
uint8_t reg_value;
};
static uint32 KpuDrvInit(void)
{
x_err_t ret = EOK;
return ret;
}
static uint32 KpuOpen(void *dev)
{
x_err_t ret = EOK;
KpuDrvInit();
return ret;
}
static uint32 KpuClose(void *dev)
{
x_err_t ret = EOK;
return ret;
}
static uint32 KpuDrvConfigure(void *drv, struct BusConfigureInfo *args)
{
x_err_t ret = EOK;
int cmd_type = args->configure_cmd;
KpuOutputBuffer* output_data;
switch (cmd_type)
{
case OPE_INT:
break;
case OPE_CFG:
break;
case LOAD_KMODEL:
kpu_load_kmodel(&kpu_task, args->private_data);
break;
case RUN_KMODEL:
g_ai_done_flag=0;
kpu_run_kmodel(&kpu_task, args->private_data, KPU_DMA_CH, ai_done, NULL);
break;
case GET_OUTPUT:
output_data = (KpuOutputBuffer*)args->private_data;
kpu_get_output(&kpu_task, 0, (uint8_t **)&(output_data->buffer), &(output_data->length));
break;
case WAIT_FLAG:
*((uint8_t*)(args->private_data)) = g_ai_done_flag;
break;
default:
break;
}
return ret;
}
/*manage the kpu device operations*/
static const struct KpuDevDone kpu_dev_done =
{
.dev_open = KpuOpen,
.dev_close = KpuClose,
.dev_write = NONE,
.dev_read = NONE,
};
/*Init kpu bus*/
static int BoardKpuBusInit(struct KpuBus *kpu_bus, struct KpuDriver *kpu_driver)
{
x_err_t ret = EOK;
/*Init the kpu bus */
kpu_bus->private_data = (void *)&kpu_dev_done;
ret = KpuBusInit(kpu_bus, KPU_BUS_NAME);
if (EOK != ret)
{
KPrintf("board_kpu_init KpuBusInit error %d\n", ret);
return ERROR;
}
/*Init the kpu driver*/
kpu_driver->private_data = (void *)&kpu_dev_done;
ret = KpuDriverInit(kpu_driver, KPU_DRV_NAME);
if (EOK != ret)
{
KPrintf("board_kpu_init KpuDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the kpu driver to the kpu bus*/
ret = KpuDriverAttachToBus(KPU_DRV_NAME, KPU_BUS_NAME);
if (EOK != ret)
{
KPrintf("board_kpu_init KpuDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the kpu device to the kpu bus*/
static int BoardKpuDevBend(void)
{
x_err_t ret = EOK;
static struct KpuHardwareDevice kpu_device;
memset(&kpu_device, 0, sizeof(struct KpuHardwareDevice));
kpu_device.kpu_dev_done = &kpu_dev_done;
ret = KpuDeviceRegister(&kpu_device, NONE, KPU_DEVICE_NAME);
if (EOK != ret)
{
KPrintf("board_kpu_init KpuDeviceInit device %s error %d\n", KPU_DEVICE_NAME, ret);
return ERROR;
}
ret = KpuDeviceAttachToBus(KPU_DEVICE_NAME, KPU_BUS_NAME);
if (EOK != ret)
{
KPrintf("board_kpu_init KpuDeviceAttachToBus device %s error %d\n", KPU_DEVICE_NAME, ret);
return ERROR;
}
return ret;
}
int HwKpuInit(void)
{
x_err_t ret = EOK;
static struct KpuBus kpu_bus;
memset(&kpu_bus, 0, sizeof(struct KpuBus));
static struct KpuDriver kpu_driver;
memset(&kpu_driver, 0, sizeof(struct KpuDriver));
kpu_driver.configure = KpuDrvConfigure;
ret = BoardKpuBusInit(&kpu_bus, &kpu_driver);
if (EOK != ret)
{
KPrintf("board_kpu_Init error ret %u\n", ret);
return ERROR;
}
ret = BoardKpuDevBend();
if (EOK != ret)
{
KPrintf("board_kpu_Init error ret %u\n", ret);
return ERROR;
}
return ret;
}

File diff suppressed because it is too large Load Diff

View File

@ -12,13 +12,13 @@ if BSP_USING_SPI1
default "spi1_drv"
config BSP_SPI1_CLK_PIN
int "spi1 clk pin number"
default 6
default 9
config BSP_SPI1_D0_PIN
int "spi1 d0 pin number"
default 8
default 11
config BSP_SPI1_D1_PIN
int "spi1 d1 pin number"
default 7
default 10
menuconfig BSP_SPI1_USING_SS0
bool "SPI1 Enable SS0"
default y
@ -28,7 +28,7 @@ if BSP_USING_SPI1
default "spi1_dev0"
config BSP_SPI1_SS0_PIN
int "spi1 ss0 pin number"
default 9
default 12
menuconfig RESOURCES_SPI_LORA
bool "Using spi lora function"
default n

View File

@ -22,7 +22,6 @@ extern void spi_select_cs(void);
extern void spi_deselete_cs(void);
// global configurations for w5500 tcp connection
const uint32_t socket_tcp = 0;
const uint32_t g_wiznet_buf_size = 2048;
static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11},
@ -269,27 +268,27 @@ uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size,
enum TCP_OPTION opt) {
// assert(buf_size <= g_wiznet_buf_size);
int32_t ret;
switch (getSn_SR(socket_tcp)) {
switch (getSn_SR(sn)) {
case SOCK_CLOSE_WAIT:
wiz_sock_disconnect(socket_tcp);
wiz_sock_disconnect(sn);
break;
case SOCK_CLOSED:
wiz_socket(socket_tcp, Sn_MR_TCP, 5000, 0x00);
wiz_socket(sn, Sn_MR_TCP, 5000, 0x00);
break;
case SOCK_INIT:
KPrintf("[SOCKET CLIENT] sock init.\n");
wiz_sock_connect(socket_tcp, dst_ip, dst_port);
wiz_sock_connect(sn, dst_ip, dst_port);
break;
case SOCK_ESTABLISHED:
if (getSn_IR(socket_tcp) & Sn_IR_CON) {
printf("[SOCKET CLIENT] %d:Connected\r\n", socket_tcp);
setSn_IR(socket_tcp, Sn_IR_CON);
if (getSn_IR(sn) & Sn_IR_CON) {
printf("[SOCKET CLIENT] %d:Connected\r\n", sn);
setSn_IR(sn, Sn_IR_CON);
}
if (opt == SEND_DATA) {
uint32_t sent_size = 0;
ret = wiz_sock_send(socket_tcp, buf, buf_size);
ret = wiz_sock_send(sn, buf, buf_size);
if (ret < 0) {
wiz_sock_close(socket_tcp);
wiz_sock_close(sn);
return ret;
}
} else if (opt == RECV_DATA) {
@ -348,9 +347,9 @@ int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size,
}
if (opt == SEND_DATA) {
uint32_t sent_size = 0;
ret = wiz_sock_send(socket_tcp, buf, buf_size);
ret = wiz_sock_send(sn, buf, buf_size);
if (ret < 0) {
wiz_sock_close(socket_tcp);
wiz_sock_close(sn);
return ret;
}
} else if (opt == RECV_DATA) {

View File

@ -475,6 +475,9 @@ KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/tensorflow
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/tensorflow-lite/tensorflow-lite-for-mcu/source/third_party/gemmlowp #
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/tensorflow-lite/tensorflow-lite-for-mcu/source/third_party/flatbuffers/include #
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/tensorflow-lite/tensorflow-lite-for-mcu/source/third_party/ruy #
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/kpu/k210_yolov2_detect_procedure #
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/kpu/yolov2 #
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/knowing/kpu/yolov2_json #
endif
ifeq ($(CONFIG_LIB_LV),y)
@ -495,6 +498,10 @@ KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protoc
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/melsec #
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/opcua #
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Framework/control/plc_protocol/s7 #
endif
ifeq ($(CONFIG_LIB_USING_CJSON), y)
KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/lib/cJSON
endif

View File

@ -169,3 +169,9 @@ if BSP_USING_CAMERA
bool "Using Camera bus drivers"
default n
endif
if BSP_USING_KPU
config RESOURCES_KPU
bool "Using Kpu bus drivers"
default n
endif

View File

@ -69,4 +69,8 @@ ifeq ($(CONFIG_RESOURCES_CAMERA),y)
SRC_DIR += camera
endif
ifeq ($(CONFIG_RESOURCES_KPU),y)
SRC_DIR += kpu
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -55,6 +55,7 @@ enum BusType_e
TYPE_ADC_BUS,
TYPE_DAC_BUS,
TYPE_CAMERA_BUS,
TYPE_KPU_BUS,
TYPE_BUS_END,
};
@ -82,6 +83,7 @@ enum DevType
TYPE_ADC_DEV,
TYPE_DAC_DEV,
TYPE_CAMERA_DEV,
TYPE_KPU_DEV,
TYPE_DEV_END,
};
@ -109,6 +111,7 @@ enum DriverType_e
TYPE_ADC_DRV,
TYPE_DAC_DRV,
TYPE_CAMERA_DRV,
TYPE_KPU_DRV,
TYPE_DRV_END,
};

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file bus_kpu.h
* @brief define kpu bus and drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-12-19
*/
#ifndef BUS_KPU_H
#define BUS_KPU_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct KpuDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
void *private_data;
};
struct KpuBus
{
struct Bus bus;
void *private_data;
};
/*Register the KPU bus*/
int KpuBusInit(struct KpuBus *kpu_bus, const char *bus_name);
/*Register the KPU driver*/
int KpuDriverInit(struct KpuDriver *kpu_driver, const char *driver_name);
/*Release the KPU device*/
int KpuReleaseBus(struct KpuBus *kpu_bus);
/*Register the KPU driver to the KPU bus*/
int KpuDriverAttachToBus(const char *drv_name, const char *bus_name);
/*Register the driver, manage with the double linklist*/
int KpuDriverRegister(struct Driver *driver);
/*Find the register driver*/
DriverType KpuDriverFind(const char *drv_name, enum DriverType_e drv_type);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file dev_kpu.h
* @brief define kpu dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-12-19
*/
#ifndef DEV_KPU_H
#define DEV_KPU_H
#include <bus.h>
#ifdef __cplusplus
extern "C" {
#endif
struct KpuDataStandard
{
uint16 addr;
uint16 flags;
uint16 len;
uint16 retries;
uint8 *buf;
struct KpuDataStandard *next;
};
struct KpuDevDone
{
uint32 (*dev_open) (void *kpu_device);
uint32 (*dev_close) (void *kpu_device);
uint32 (*dev_write) (void *kpu_device, struct BusBlockWriteParam *msg);
uint32 (*dev_read) (void *kpu_device, struct BusBlockReadParam *msg);
};
struct KpuHardwareDevice
{
struct HardwareDev haldev;
const struct KpuDevDone *kpu_dev_done;
};
/*Register the KPU device*/
int KpuDeviceRegister(struct KpuHardwareDevice *kpu_device, void *kpu_param, const char *device_name);
/*Register the KPU device to the KPU bus*/
int KpuDeviceAttachToBus(const char *dev_name, const char *bus_name);
/*Find the register KPU device*/
HardwareDevType KpuDeviceFind(const char *dev_name, enum DevType dev_type);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -111,4 +111,9 @@ HardwareDevType ObtainConsole(void);
#include <dev_camera.h>
#endif
#ifdef RESOURCES_KPU
#include <bus_kpu.h>
#include <dev_kpu.h>
#endif
#endif

View File

@ -0,0 +1,5 @@
SRC_FILES += dev_kpu.c drv_kpu.c bus_kpu.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file bus_kpu.c
* @brief register kpu bus function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-12-19
*/
#include <bus_kpu.h>
#include <dev_kpu.h>
/*Register the KPU BUS*/
int KpuBusInit(struct KpuBus *kpu_bus, const char *bus_name)
{
NULL_PARAM_CHECK(kpu_bus);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
if (BUS_INSTALL != kpu_bus->bus.bus_state) {
strncpy(kpu_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
kpu_bus->bus.bus_type = TYPE_KPU_BUS;
kpu_bus->bus.bus_state = BUS_INSTALL;
kpu_bus->bus.private_data = kpu_bus->private_data;
ret = BusRegister(&kpu_bus->bus);
if (EOK != ret) {
KPrintf("KpuBusInit BusRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("KpuBusInit BusRegister bus has been register state%u\n", kpu_bus->bus.bus_state);
}
return ret;
}
/*Register the KPU Driver*/
int KpuDriverInit(struct KpuDriver *kpu_driver, const char *driver_name)
{
NULL_PARAM_CHECK(kpu_driver);
NULL_PARAM_CHECK(driver_name);
x_err_t ret = EOK;
if (DRV_INSTALL != kpu_driver->driver.driver_state) {
kpu_driver->driver.driver_type = TYPE_KPU_DRV;
kpu_driver->driver.driver_state = DRV_INSTALL;
strncpy(kpu_driver->driver.drv_name, driver_name, NAME_NUM_MAX);
kpu_driver->driver.private_data = kpu_driver->private_data;
kpu_driver->driver.configure = kpu_driver->configure;
ret = KpuDriverRegister(&kpu_driver->driver);
if (EOK != ret) {
KPrintf("KpuDriverInit DriverRegister error %u\n", ret);
return ret;
}
} else {
KPrintf("KpuDriverInit DriverRegister driver has been register state%u\n", kpu_driver->driver.driver_state);
}
return ret;
}
/*Release the KPU device*/
int KpuReleaseBus(struct KpuBus *kpu_bus)
{
NULL_PARAM_CHECK(kpu_bus);
return BusRelease(&kpu_bus->bus);
}
/*Register the KPU Driver to the KPU BUS*/
int KpuDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct Driver *driver;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("KpuDriverAttachToBus find kpu bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_KPU_BUS == bus->bus_type) {
driver = KpuDriverFind(drv_name, TYPE_KPU_DRV);
if (NONE == driver) {
KPrintf("KpuDriverAttachToBus find kpu driver error!name %s\n", drv_name);
return ERROR;
}
if (TYPE_KPU_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {
KPrintf("KpuDriverAttachToBus DriverRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return ret;
}

View File

@ -0,0 +1,200 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2006-03-13 bernard first version
* 2012-05-15 lgnq modified according bernard's implementation.
* 2012-05-28 bernard code cleanup
* 2012-11-23 bernard fix compiler warning.
* 2013-02-20 bernard use RT_KPU_RB_BUFSZ to define
* the size of ring buffer.
* 2014-07-10 bernard rewrite kpu framework
* 2014-12-31 bernard use open_flag for poll_tx stream mode.
* 2015-05-19 Quintin fix DMA tx mod tx_dma->activated flag !=RT_FALSE BUG
* in open function.
* 2015-11-10 bernard fix the poll rx issue when there is no data.
* 2016-05-10 armink add fifo mode to DMA rx when kpu->config.bufsz != 0.
* 2017-01-19 aubr.cool prevent change kpu rx bufsz when kpu is opened.
* 2017-11-07 JasonJia fix data bits error issue when using tcsetattr.
* 2017-11-15 JasonJia fix poll rx issue when data is full.
* add TCFLSH and FIONREAD support.
* 2018-12-08 Ernest Chen add DMA choice
* 2020-09-14 WillianChan add a line feed to the carriage return character
* when using interrupt tx
*/
/**
* @file dev_kpu.c
* @brief register kpu dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022-12-19
*/
/*************************************************
File name: dev_kpu.c
Description: support kpu dev INT and DMA configuretransfer data
Others: take RT-Thread v4.0.2/components/driver/kpu/kpu.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-24
Author: AIIT XUOS Lab
Modification:
1. support kpu dev register, configure, write and read
2. add bus driver framework support, include INT and DMA mode
*************************************************/
#include <bus_kpu.h>
#include <dev_kpu.h>
static DoubleLinklistType kpudev_linklist;
static uint32 KpuDevOpen(void *dev)
{
NULL_PARAM_CHECK(dev);
x_err_t ret = EOK;
struct KpuHardwareDevice *kpu_dev = (struct KpuHardwareDevice *)dev;
ret = kpu_dev->kpu_dev_done->dev_open(dev);
return EOK;
}
static uint32 KpuDevClose(void *dev)
{
NULL_PARAM_CHECK(dev);
x_err_t ret = EOK;
struct KpuHardwareDevice *kpu_dev = (struct KpuHardwareDevice *)dev;
ret = kpu_dev->kpu_dev_done->dev_close(dev);
return EOK;
}
static uint32 KpuDevWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
x_err_t ret = EOK;
struct KpuHardwareDevice *kpu_dev = (struct KpuHardwareDevice *)dev;
ret = kpu_dev->kpu_dev_done->dev_write(dev,write_param);
return ret;
}
static uint32 KpuDevRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
x_err_t ret = EOK;
struct KpuHardwareDevice *kpu_dev = (struct KpuHardwareDevice *)dev;
ret = kpu_dev->kpu_dev_done->dev_read(dev,read_param);
return EOK;
}
static const struct HalDevDone dev_done =
{
.open = KpuDevOpen,
.close = KpuDevClose,
.write = KpuDevWrite,
.read = KpuDevRead,
};
/*Create the kpu device linklist*/
static void KpuDeviceLinkInit()
{
InitDoubleLinkList(&kpudev_linklist);
}
HardwareDevType KpuDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &kpudev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
}
}
KPrintf("KpuDeviceFind cannot find the %s device.return NULL\n", dev_name);
return NONE;
}
int KpuDeviceRegister(struct KpuHardwareDevice *kpu_device, void *kpu_param, const char *device_name)
{
NULL_PARAM_CHECK(kpu_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (!dev_link_flag) {
KpuDeviceLinkInit();
dev_link_flag = RET_TRUE;
}
if (DEV_INSTALL != kpu_device->haldev.dev_state) {
strncpy(kpu_device->haldev.dev_name, device_name, NAME_NUM_MAX);
kpu_device->haldev.dev_type = TYPE_KPU_DEV;
kpu_device->haldev.dev_state = DEV_INSTALL;
kpu_device->haldev.dev_done = (struct HalDevDone *)&dev_done;
DoubleLinkListInsertNodeAfter(&kpudev_linklist, &(kpu_device->haldev.dev_link));
} else {
KPrintf("KpuDeviceRegister device has been register state%u\n", kpu_device->haldev.dev_state);
}
return ret;
}
int KpuDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
struct HardwareDev *device;
bus = BusFind(bus_name);
if (NONE == bus) {
KPrintf("KpuDeviceAttachToBus find kpu bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_KPU_BUS == bus->bus_type) {
device = KpuDeviceFind(dev_name, TYPE_KPU_DEV);
if (NONE == device) {
KPrintf("KpuDeviceAttachToBus find kpu device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_KPU_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
if (EOK != ret) {
KPrintf("KpuDeviceAttachToBus DeviceRegisterToBus error %u\n", ret);
return ERROR;
}
}
}
return EOK;
}

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file drv_kpu.c
* @brief register kpu drv function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-12-19
*/
#include <bus_kpu.h>
#include <dev_kpu.h>
static DoubleLinklistType kpu_drv_linklist;
/*Create the driver linklist*/
static void KpuDrvLinkInit()
{
InitDoubleLinkList(&kpu_drv_linklist);
}
DriverType KpuDriverFind(const char *drv_name, enum DriverType_e drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &kpu_drv_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
driver = SYS_DOUBLE_LINKLIST_ENTRY(node, struct Driver, driver_link);
if ((!strcmp(driver->drv_name, drv_name)) && (drv_type == driver->driver_type)) {
return driver;
}
}
KPrintf("KpuDriverFind cannot find the %s driver.return NULL\n", drv_name);
return NONE;
}
int KpuDriverRegister(struct Driver *driver)
{
NULL_PARAM_CHECK(driver);
x_err_t ret = EOK;
static x_bool driver_link_flag = RET_FALSE;
if (!driver_link_flag) {
KpuDrvLinkInit();
driver_link_flag = RET_TRUE;
}
DoubleLinkListInsertNodeAfter(&kpu_drv_linklist, &(driver->driver_link));
return ret;
}

View File

@ -28,7 +28,7 @@ static uint32 SdReady(SpiSdDeviceType spi_sd_dev)
NULL_PARAM_CHECK(spi_sd_dev);
uint8 data = 0xFF;
uint8 read;
uint8 read = 0x00;
uint32 start_time;
struct BusBlockWriteParam write_param;
@ -42,7 +42,7 @@ static uint32 SdReady(SpiSdDeviceType spi_sd_dev)
start_time = 0;
do
{
BusDevWriteData(&spi_sd_dev->spi_dev->haldev, &write_param);
// BusDevWriteData(&spi_sd_dev->spi_dev->haldev, &write_param);
BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param);
@ -690,7 +690,7 @@ static uint32 SdHwReadCSD(SpiSdDeviceType spi_sd_dev)
if (0xFE != g_sd_cmd_param.sd_respone_data[1]) {
/*Step2 : SPI write data 0xFF until read 0xFE*/
uint8 data = 0xFF;
uint8 read_spi=0x00;
uint8 read_spi = 0x00;
uint32 start_time;
write_param.buffer = (void *)&data;
@ -702,7 +702,7 @@ static uint32 SdHwReadCSD(SpiSdDeviceType spi_sd_dev)
do
{
BusDevWriteData(&spi_sd_dev->spi_dev->haldev, &write_param);
// BusDevWriteData(&spi_sd_dev->spi_dev->haldev, &write_param);
BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param);
SD_TIMEOUT(start_time, 10 * SPI_SD_TIMEOUT_NUM);
}while(0xFE != read_spi);
@ -768,7 +768,7 @@ static uint32 SdReadSingleBlock(SpiSdDeviceType spi_sd_dev, uint32 id, uint8 *re
/*Step2 : SPI read until 0xFE*/
uint8 data = 0xFF;
uint8 read[2];
uint8 read[2]={0};
uint32 start_time;
write_param.buffer = (void *)&data;
@ -837,7 +837,7 @@ static uint32 SdReadMultiBlock(SpiSdDeviceType spi_sd_dev, uint32 id, const uint
/*Step2 : SPI write data 0xFF until read 0xFE*/
uint32 i = 0;
uint8 data = 0xFF;
uint8 read[2];
uint8 read[2] = {0};
uint32 start_time;
for (i = 0 ; i < block_num ; i ++) {
@ -847,10 +847,9 @@ static uint32 SdReadMultiBlock(SpiSdDeviceType spi_sd_dev, uint32 id, const uint
read_param.size = 1;
start_time = 0;
read[0] = 0;
do
{
BusDevWriteData(&spi_sd_dev->spi_dev->haldev, &write_param);
BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param);
SD_TIMEOUT(start_time, 10 * SPI_SD_TIMEOUT_NUM);
@ -860,12 +859,12 @@ static uint32 SdReadMultiBlock(SpiSdDeviceType spi_sd_dev, uint32 id, const uint
read_param.buffer = (void *)((uint8 *)read_buffer + i * spi_sd_dev->sd_param.block_param.block_size);
read_param.size = spi_sd_dev->sd_param.block_param.block_size;
BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param);
}
/*Step4 : SPI read 2 bytes CRC*/
read_param.buffer = (void *)read;
read_param.size = 2;
BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param);
/*Step4 : SPI read 2 bytes CRC*/
read_param.buffer = (void *)read;
read_param.size = 2;
BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param);
}
/*Step5 : CMD12 stop read*/
g_sd_cmd_param.sd_cmd_type = SD_CMD_12;
@ -922,7 +921,7 @@ static uint32 SdWriteSingleBlock(SpiSdDeviceType spi_sd_dev, uint32 id, const ui
/*Step2 : SPI write data 0xFE*/
uint8 data = 0xFE;
uint8 read;
uint8 read = 0x00;
uint8 write[2] = {0xFF, 0xFF};
write_param.buffer = (void *)&data;
@ -1035,7 +1034,7 @@ static uint32 SdWriteMultiBlock(SpiSdDeviceType spi_sd_dev, uint32 id, const voi
/*Step3 : SPI write data 0xFC*/
uint32 i;
uint8 data = 0xFC;
uint8 read;
uint8 read = 0x00;
uint8 write[2] = {0xFF, 0xFF};
for (i = 0 ; i < block_num; i ++) {
@ -1058,6 +1057,7 @@ static uint32 SdWriteMultiBlock(SpiSdDeviceType spi_sd_dev, uint32 id, const voi
read_param.size = 1;
start_time = 0;
read = 0xFF;
do
{
BusDevReadData(&spi_sd_dev->spi_dev->haldev, &read_param);
@ -1233,7 +1233,6 @@ uint32 SdRead(void *dev, struct BusBlockReadParam *read_param)
KMutexAbandon(spi_sd_dev->spi_dev->haldev.owner_bus->bus_lock);
return ERROR;
}
/*Step2 : read SD block*/
if (1 == block_num) {
ret = SdReadSingleBlock(spi_sd_dev, id, read_buffer);