source: azure_iot_hub_riscv/trunk/app_iothub_client/src/kpu_main.c@ 458

Last change on this file since 458 was 458, checked in by coas-nagasima, 4 years ago

SPIとSerial、KPUの動作を改善

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 15.0 KB
Line 
1/*
2* TOPPERS/ASP Kernel
3* Toyohashi Open Platform for Embedded Real-Time Systems/
4* Advanced Standard Profile Kernel
5*
6* Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7* Toyohashi Univ. of Technology, JAPAN
8* Copyright (C) 2004-2012 by Embedded and Real-Time Systems Laboratory
9* Graduate School of Information Science, Nagoya Univ., JAPAN
10*
11* 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
12* ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13* 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14* (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15* 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16* スコード中に含まれていること.
17* (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18* 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19* 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20* の無保証規定を掲載すること.
21* (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22* 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23* と.
24* (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25* 作権表示,この利用条件および下記の無保証規定を掲載すること.
26* (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27* 報告すること.
28* (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29* 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30* また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31* 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32* 免責すること.
33*
34* 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35* よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36* に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37* アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38* の責任を負わない.
39*
40* $Id: kpu_main.c 2176 2020-08-19 23:50:05Z coas-nagasima $
41*/
42
43#include <kernel.h>
44#include <stdlib.h>
45#include <t_syslog.h>
46#include <t_stdlib.h>
47#include <target_syssvc.h>
48#include "syssvc/serial.h"
49#include "syssvc/syslog.h"
50#include "device.h"
51#include "pinmode.h"
52#include "sipeed_st7789.h"
53#include "sipeed_ov2640.h"
54#include "storagedevice.h"
55#ifdef SDEV_SENSE_ONETIME
56#include "spi_driver.h"
57#include "sddiskio.h"
58#else
59#include "rom_file.h"
60#endif
61#include "kernel_cfg.h"
62#include "kpu_main.h"
63#include "kpu.h"
64#include "region_layer.h"
65
66/*
67* サービスコールのエラーのログ出力
68*/
69Inline void
70svc_perror(const char *file, int_t line, const char *expr, ER ercd)
71{
72 if (ercd < 0) {
73 t_perror(LOG_ERROR, file, line, expr, ercd);
74 }
75}
76
77#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
78
79#define SWAP_32(x) ((x >> 24) | (x >> 8 & 0xff00) | (x << 8 & 0xff0000) | (x << 24))
80
81#ifndef SPI1DMATX_SEM
82#define SPI1DMATX_SEM 0
83#endif
84
85#define CLASS_NUMBER 20
86
87LCD_Handler_t LcdHandle;
88LCD_DrawProp_t DrawProp;
89DVP_Handle_t DvpHandle;
90OV2640_t CameraHandle;
91
92uint8_t sTxBuffer[16];
93
94static uint8_t time_string[12];
95
96static void
97set_value(uint8_t *buf, int value)
98{
99 buf[1] = (value % 10) + '0';
100 buf[0] = (value / 10) + '0';
101}
102
103static void
104set_time(uint8_t *buf, struct tm2 *tm)
105{
106 buf[8] = 0;
107 set_value(&buf[6], tm->tm_sec);
108 buf[5] = ':';
109 set_value(&buf[3], tm->tm_min);
110 buf[2] = ':';
111 set_value(&buf[0], tm->tm_hour);
112}
113
114/*
115* ダイレクトデジタルピン設定
116*/
117void
118pinMode(uint8_t Pin, uint8_t dwMode){
119 int gpionum = gpio_get_gpiohno(Pin, false);
120 GPIO_Init_t init = {0};
121
122 syslog_2(LOG_NOTICE, "## pinMode Pin(%d) gpionum(%d) ##", Pin, gpionum);
123 if(gpionum >= 0){
124 uint8_t function = FUNC_GPIOHS0 + gpionum;
125 fpioa_set_function(Pin, function);
126 switch(dwMode){
127 case INPUT:
128 init.mode = GPIO_MODE_INPUT;
129 init.pull = GPIO_NOPULL;
130 break;
131 case INPUT_PULLDOWN:
132 init.mode = GPIO_MODE_INPUT;
133 init.pull = GPIO_PULLDOWN;
134 break;
135 case INPUT_PULLUP:
136 init.mode = GPIO_MODE_INPUT;
137 init.pull = GPIO_PULLUP;
138 break;
139 case OUTPUT:
140 default:
141 init.mode = GPIO_MODE_OUTPUT;
142 init.pull = GPIO_PULLDOWN;
143 break;
144 }
145 gpio_setup(TADR_GPIOHS_BASE, &init, (uint8_t)gpionum);
146 }
147 return ;
148}
149
150void digitalWrite(uint8_t Pin, int dwVal);
151
152#if (CLASS_NUMBER > 1)
153typedef struct
154{
155 char *str;
156 uint16_t color;
157 uint16_t height;
158 uint16_t width;
159} class_lable_t;
160
161class_lable_t class_lable[CLASS_NUMBER] =
162{
163 {"aeroplane", ST7789_GREEN},
164 {"bicycle", ST7789_GREEN},
165 {"bird", ST7789_GREEN},
166 {"boat", ST7789_GREEN},
167 {"bottle", 0xF81F},
168 {"bus", ST7789_GREEN},
169 {"car", ST7789_GREEN},
170 {"cat", ST7789_GREEN},
171 {"chair", 0xFD20},
172 {"cow", ST7789_GREEN},
173 {"diningtable", ST7789_GREEN},
174 {"dog", ST7789_GREEN},
175 {"horse", ST7789_GREEN},
176 {"motorbike", ST7789_GREEN},
177 {"person", 0xF800},
178 {"pottedplant", ST7789_GREEN},
179 {"sheep", ST7789_GREEN},
180 {"sofa", ST7789_GREEN},
181 {"train", ST7789_GREEN},
182 {"tvmonitor", 0xF9B6}
183};
184
185static uint32_t lable_string_draw_ram[115 * 16 * 8 / 2];
186#endif
187extern const uint8_t model_data[];
188kpu_model_context_t g_task;
189static region_layer_t detect_rl;
190
191volatile uint8_t g_ai_done_flag;
192
193void ai_done(void *ctx)
194{
195 g_ai_done_flag = 2;
196}
197
198#define ANCHOR_NUM 5
199float g_anchor[ANCHOR_NUM * 2] = {1.08, 1.19, 3.42, 4.41, 6.63, 11.38, 9.42, 5.11, 16.62, 10.52};
200
201static void drawboxes(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2, uint32_t class, float prob)
202{
203 if (x1 >= 320)
204 x1 = 319;
205 if (x2 >= 320)
206 x2 = 319;
207 if (y1 >= 240)
208 y1 = 239;
209 if (y2 >= 240)
210 y2 = 239;
211
212#if (CLASS_NUMBER > 1)
213 DrawProp.TextColor = class_lable[class].color;
214 lcd_drawRect(&DrawProp, x1, y1, x2-x1, y2-y1);
215 DrawProp.TextColor = ST7789_WHITE;
216 DrawProp.BackColor = class_lable[class].color;
217 DrawProp.pFont = &Font12;
218 lcd_DisplayStringAt(&DrawProp, x1 + 1, y1 + 1, class_lable[class].str, LEFT_MODE);
219#else
220 lcd_drawRect(&DrawProp, x1, y1, x2, y2, 2, ST7789_RED);
221#endif
222}
223
224/*
225* メインタスク
226*/
227void kpu_task(intptr_t exinf)
228{
229 SPI_Init_t Init;
230 SPI_Handle_t *hspi;
231 LCD_Handler_t *hlcd;
232 OV2640_t *hcmr;
233 DVP_Handle_t *hdvp;
234 ER_UINT ercd;
235 uint32_t i;
236 struct tm2 time;
237 unsigned long atmp;
238#ifdef SDEV_SENSE_ONETIME
239 StorageDevice_t *psdev;
240 SDCARD_Handler_t *hsd = NULL;
241#else
242 uint32_t esize, fsize, headlen;
243 uint8_t *addr;
244#endif
245
246 SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
247 syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
248
249 pinMode(LED_PIN, OUTPUT);
250
251 select_spi0_dvp_mode(1);
252
253#ifdef SDEV_SENSE_ONETIME
254 pinMode(SPI_SS_PIN, OUTPUT);
255 digitalWrite(SPI_SS_PIN, HIGH);
256#else /* USE ROMFILE */
257 rom_file_init();
258 esize = 1*1024*1024;
259 addr = (uint8_t *)romfont;
260 while(esize > 4){
261 fsize = (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
262 if((fsize & 3) != 0 || fsize < 16 || fsize > esize)
263 break;
264 for(i = 0 ; i < 28 ; i++){
265 if(addr[i+4] == 0)
266 break;
267 }
268 if(i >= 28)
269 break;
270 if(i < 12)
271 headlen = 16;
272 else
273 headlen = 32;
274 if(create_rom_file((const char *)(addr+4), (uintptr_t)(addr+headlen), fsize-headlen) < 0)
275 break;
276 addr += fsize;
277 esize -= fsize;
278 }
279#endif
280
281 hcmr = &CameraHandle;
282 hcmr->frameSize = FRAMESIZE_QVGA;
283 hcmr->pixFormat = PIXFORMAT_RGB565;
284 ov2640_getResolition(hcmr, FRAMESIZE_QVGA);
285 hcmr->_resetPoliraty = ACTIVE_HIGH;
286 hcmr->_pwdnPoliraty = ACTIVE_HIGH;
287 hcmr->_slaveAddr = 0x00;
288 hcmr->_dataBuffer = NULL;
289 hcmr->_aiBuffer = NULL;
290
291 // just support RGB565 and YUV442 on k210
292
293 // Initialize the camera bus, 8bit reg
294 hdvp = &DvpHandle;
295 hcmr->hdvp = hdvp;
296 hdvp->Init.Freq = 24000000;
297 hdvp->Init.Width = hcmr->_width;
298 hdvp->Init.Height = hcmr->_height;
299 hdvp->Init.Format = DVP_FORMAT_RGB;
300 hdvp->Init.BurstMode = DVP_BURST_ENABLE;
301 hdvp->Init.AutoMode = DVP_AUTOMODE_DISABLE;
302 hdvp->Init.GMMlen = 4;
303
304 hdvp->Init.num_sccb_reg = 8;
305 hdvp->Init.CMosPClkPin = 47;
306 hdvp->Init.CMosXClkPin = 46;
307 hdvp->Init.CMosHRefPin = 45;
308 hdvp->Init.CMosPwDnPin = 44;
309 hdvp->Init.CMosVSyncPin = 43;
310 hdvp->Init.CMosRstPin = 42;
311 hdvp->Init.SccbSClkPin = 41;
312 hdvp->Init.SccbSdaPin = 40;
313 hdvp->Init.IntNo = INTNO_DVP;
314 syslog_1(LOG_NOTICE, "## DvpHandle[%08x] ##", &DvpHandle);
315
316 syslog_3(LOG_NOTICE, "## hcmr->_width(%d) hcmr->_height(%d) size[%08x] ##", hcmr->_width, hcmr->_height, (hcmr->_width * hcmr->_height * 2));
317 atmp = (unsigned long)malloc(hcmr->_width * hcmr->_height * 2 + 64); //RGB565
318 hcmr->_dataBuffer = (uint32_t *)((atmp + 63) & ~63);
319 if(hcmr->_dataBuffer == NULL){
320 hcmr->_width = 0;
321 hcmr->_height = 0;
322 syslog_0(LOG_ERROR, "Can't allocate _dataBuffer !");
323 slp_tsk();
324 }
325 atmp = (unsigned long)malloc(hcmr->_width * hcmr->_height * 3 + 128); //RGB888
326 hcmr->_aiBuffer = (uint32_t *)((atmp + 127) & ~127);
327 if(hcmr->_aiBuffer == NULL){
328 hcmr->_width = 0;
329 hcmr->_height = 0;
330 free(hcmr->_dataBuffer);
331 hcmr->_dataBuffer = NULL;
332 syslog_0(LOG_ERROR, "Can't allocate _aiBuffer !");
333 slp_tsk();
334 }
335 syslog_2(LOG_NOTICE, "## hcmr->_dataBuffer[%08x] hcmr->_aiBuffer[%08x] ##", hcmr->_dataBuffer, hcmr->_aiBuffer);
336 atmp = (unsigned long)hcmr->_aiBuffer - IOMEM;
337 hdvp->Init.RedAddr = (uint32_t)atmp;
338 atmp = (unsigned long)hcmr->_aiBuffer + hcmr->_width * hcmr->_height - IOMEM;
339 hdvp->Init.GreenAddr = (uint32_t)atmp;
340 atmp = (unsigned long)hcmr->_aiBuffer + hcmr->_width * hcmr->_height * 2 - IOMEM;
341 hdvp->Init.BlueAddr = (uint32_t)atmp;
342 atmp = (unsigned long)hcmr->_dataBuffer - IOMEM;
343 hdvp->Init.RGBAddr = (uint32_t)atmp;
344 dvp_init(hdvp);
345
346 if(ov2640_sensor_ov_detect(hcmr) == E_OK){
347 syslog_0(LOG_NOTICE, "find ov sensor !");
348 }
349 else if(ov2640_sensro_gc_detect(hcmr) == E_OK){
350 syslog_0(LOG_NOTICE, "find gc3028 !");
351 }
352 if(ov2640_reset(hcmr) != E_OK){
353 syslog_0(LOG_ERROR, "ov2640 reset error !");
354 slp_tsk();
355 }
356 if(ov2640_set_pixformat(hcmr) != E_OK){
357 syslog_0(LOG_ERROR, "set pixformat error !");
358 slp_tsk();
359 }
360 if(ov2640_set_framesize(hcmr) != E_OK){
361 syslog_0(LOG_ERROR, "set frame size error !");
362 slp_tsk();
363 }
364 if(ov2640_setInvert(hcmr, false) != E_OK){
365 syslog_0(LOG_ERROR, "set invert error !");
366 slp_tsk();
367 }
368 syslog_1(LOG_NOTICE, "OV2640 id(%d)", ov2640_id(hcmr));
369
370 Init.WorkMode = SPI_WORK_MODE_2;
371 Init.FrameFormat = SPI_FF_OCTAL;
372 Init.DataSize = 8;
373 Init.Prescaler = 15000000;
374 Init.SignBit = 0;
375 Init.InstLength = 8;
376 Init.AddrLength = 0;
377 Init.WaitCycles = 0;
378 Init.IATransMode = SPI_AITM_AS_FRAME_FORMAT;
379 Init.SclkPin = SIPEED_ST7789_SCLK_PIN;
380 Init.MosiPin = -1;
381 Init.MisoPin = -1;
382 Init.SsPin = SIPEED_ST7789_SS_PIN;
383 Init.SsNo = SIPEED_ST7789_SS;
384 Init.TxDMAChannel = -1;
385 Init.RxDMAChannel = -1;
386 Init.semid = SPI1TRN_SEM;
387 Init.semlock = SPI1LOCK_SEM;
388 Init.semdmaid = SPI1DMATX_SEM;
389 hspi = spi_init(SPI_PORTID, &Init);
390 if(hspi == NULL){
391 syslog_0(LOG_ERROR, "SPI INIT ERROR");
392 slp_tsk();
393 }
394
395 hlcd = &LcdHandle;
396 hlcd->hspi = hspi;
397// hlcd->spi_lock= SPI1LOCK_SEM;
398 hlcd->dir = DIR_YX_LRUD;
399 hlcd->dcx_pin = SIPEED_ST7789_DCX_PIN;
400 hlcd->rst_pin = SIPEED_ST7789_RST_PIN;
401 hlcd->cs_sel = SIPEED_ST7789_SS;
402 hlcd->rst_no = SIPEED_ST7789_RST_GPIONUM;
403 hlcd->dcx_no = SIPEED_ST7789_DCX_GPIONUM;
404 DrawProp.hlcd = hlcd;
405 lcd_init(hlcd);
406 syslog_2(LOG_NOTICE, "width(%d) height(%d)", hlcd->_width, hlcd->_height);
407
408 DrawProp.BackColor = ST7789_WHITE;
409 DrawProp.TextColor = ST7789_BLACK;
410 lcd_fillScreen(&DrawProp);
411
412#ifdef SDEV_SENSE_ONETIME
413 Init.WorkMode = SPI_WORK_MODE_0;
414 Init.FrameFormat = SPI_FF_STANDARD;
415 Init.DataSize = 8;
416 Init.Prescaler = 5000000;
417 Init.SignBit = 0;
418 Init.InstLength = 0;
419 Init.AddrLength = 0;
420 Init.WaitCycles = 0;
421 Init.IATransMode = SPI_AITM_STANDARD;
422 Init.SclkPin = SPI_SCK_PIN;
423 Init.MosiPin = SPI_MOSI_PIN;
424 Init.MisoPin = SPI_MISO_PIN;
425 Init.SsPin = -1;
426 Init.SsNo = -1;
427 Init.TxDMAChannel = -1;
428 Init.RxDMAChannel = SPI_DMA1_CH;
429 Init.semid = SPI2TRN_SEM;
430 Init.semlock = SPI2LOCK_SEM;
431 Init.semdmaid = SPI2DMATX_SEM;
432 hspi = spi_init(SPICARD_PORTID, &Init);
433 if(hspi == NULL){
434 syslog_0(LOG_ERROR, "SPI-CARD INIT ERROR");
435 slp_tsk();
436 }
437 sdcard_setspi2(SPISDCARD_PORTID, hspi, SPI_SS_PIN);
438
439 /*
440 * SD-CARD SPI通信設定
441 */
442 for(i = 0 ; i < 10 ; i++)
443 sTxBuffer[i] = 0xff;
444 if((ercd = spi_core_transmit(hspi, -1, (uint8_t*)sTxBuffer, 10)) != E_OK){
445 /* Transfer error in transmission process */
446 syslog_1(LOG_NOTICE, "## call Error_Handler(2)(%d) ##", ercd);
447 }
448#if SPI_WAIT_TIME == 0
449 if((ercd = spi_wait(hspi, 100)) != E_OK){
450 syslog_0(LOG_NOTICE, "## call Error_Handler(3) ##");
451 }
452#endif
453 dly_tsk(100);
454 SDMSence_task(0);
455 psdev = SDMGetStorageDevice(SDCARD_DEVNO);
456 hsd = (SDCARD_Handler_t *)psdev->_sdev_local[1];
457 if(hsd == NULL)
458 syslog_0(LOG_ERROR, "SD-CARD INITAIL ERROR !");
459#endif
460 if ((ercd = kpu_init(&g_task)) != E_OK) {
461 syslog_0(LOG_ERROR, "kpu init error");
462 slp_tsk();
463 }
464
465 if (kpu_load_kmodel(&g_task, model_data) != 0) {
466 syslog_0(LOG_ERROR, "kmodel init error");
467 slp_tsk();
468 }
469
470 detect_rl.anchor_number = ANCHOR_NUM;
471 detect_rl.anchor = g_anchor;
472 detect_rl.threshold = 0.7;
473 detect_rl.nms_value = 0.3;
474 if (region_layer_init(&detect_rl, 10, 7, 125, 320, 240) != 0) {
475 syslog_0(LOG_ERROR, "region layer init error");
476 slp_tsk();
477 }
478
479 bool_t camok = true;
480 if((ercd = ov2640_activate(hcmr, true)) != E_OK){
481 syslog_2(LOG_NOTICE, "ov2640 activate error result(%d) id(%d) ##", ercd, ov2640_id(hcmr));
482 camok = false;
483 }
484
485 int tmo = 0;
486 g_ai_done_flag = 0;
487 while (camok) {
488 if (g_ai_done_flag == 0) {
489 ercd = ov2640_snapshot(hcmr);
490 if (ercd != E_OK) {
491 camok = false;
492 continue;
493 }
494 g_ai_done_flag = 1;
495
496 /* start to calculate */
497 atmp = (unsigned long)hcmr->_aiBuffer - IOMEM;
498 kpu_run_kmodel(&g_task, (const uint8_t *)atmp, AI_DMA_CH, ai_done, NULL);
499 }
500
501 if (g_ai_done_flag == 1) {
502 tmo++;
503 if (tmo >= 10) {
504 tmo = 0;
505 g_ai_done_flag = 0;
506 }
507 else {
508 dly_tsk(1);
509 }
510 continue;
511 }
512 else if (g_ai_done_flag == 2) {
513 g_ai_done_flag = 0;
514 float *output;
515 size_t output_size;
516 kpu_get_output(&g_task, 0, &output, &output_size);
517 detect_rl.input = output;
518
519 /* start region layer */
520 region_layer_run(&detect_rl, NULL);
521 }
522
523 lcd_drawPicture(hlcd, 0, 0, hcmr->_width, hcmr->_height, (uint16_t *)hcmr->_dataBuffer);
524
525 /* draw boxs */
526 region_layer_draw_boxes(&detect_rl, drawboxes);
527 }
528 ov2640_activate(hcmr, false);
529
530 syslog_0(LOG_NOTICE, "## STOP ##");
531 slp_tsk();
532 syslog(LOG_NOTICE, "Sample program ends.");
533 SVC_PERROR(ext_ker());
534 assert(0);
535}
Note: See TracBrowser for help on using the repository browser.