mirror of
https://github.com/pine64/bl_iot_sdk.git
synced 2024-10-01 12:32:14 +00:00
Add sample of sdk_app_spi
This commit is contained in:
parent
397aef0e6d
commit
db12f7c305
32
customer_app/sdk_app_spi/Makefile
Normal file
32
customer_app/sdk_app_spi/Makefile
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := sdk_app_spi
|
||||
PROJECT_PATH := $(abspath .)
|
||||
PROJECT_BOARD := evb
|
||||
export PROJECT_PATH PROJECT_BOARD
|
||||
#CONFIG_TOOLPREFIX :=
|
||||
|
||||
-include ./proj_config.mk
|
||||
|
||||
ifeq ($(origin BL60X_SDK_PATH), undefined)
|
||||
BL60X_SDK_PATH_GUESS ?= $(shell pwd)
|
||||
BL60X_SDK_PATH ?= $(BL60X_SDK_PATH_GUESS)/../..
|
||||
$(info ****** Please SET BL60X_SDK_PATH ******)
|
||||
$(info ****** Trying SDK PATH [$(BL60X_SDK_PATH)])
|
||||
endif
|
||||
|
||||
COMPONENTS_BLSYS := bltime blfdt blmtd bloop loopadc looprt loopset
|
||||
COMPONENTS_VFS := romfs
|
||||
|
||||
INCLUDE_COMPONENTS += freertos_riscv_ram bl602 bl602_std hal_drv vfs yloop utils cli blog blog_testc
|
||||
INCLUDE_COMPONENTS += easyflash4
|
||||
INCLUDE_COMPONENTS += $(COMPONENTS_NETWORK)
|
||||
INCLUDE_COMPONENTS += $(COMPONENTS_BLSYS)
|
||||
INCLUDE_COMPONENTS += $(COMPONENTS_VFS)
|
||||
INCLUDE_COMPONENTS += $(PROJECT_NAME)
|
||||
|
||||
include $(BL60X_SDK_PATH)/make_scripts_riscv/project.mk
|
||||
|
3
customer_app/sdk_app_spi/genromap
Normal file
3
customer_app/sdk_app_spi/genromap
Normal file
@ -0,0 +1,3 @@
|
||||
#!/bin/sh
|
||||
make CONFIG_CHIP_NAME=BL602 CONFIG_LINK_ROM=1 CONFIG_BT_MESH=1 CONFIG_BT_SETTINGS=1 CONFIG_BLE_TP_SERVER=1 -j
|
||||
exit $?
|
40
customer_app/sdk_app_spi/proj_config.mk
Normal file
40
customer_app/sdk_app_spi/proj_config.mk
Normal file
@ -0,0 +1,40 @@
|
||||
#
|
||||
#compiler flag config domain
|
||||
#
|
||||
#CONFIG_TOOLPREFIX :=
|
||||
#CONFIG_OPTIMIZATION_LEVEL_RELEASE := 1
|
||||
#CONFIG_M4_SOFTFP := 1
|
||||
|
||||
#
|
||||
#board config domain
|
||||
#
|
||||
CONFIG_BOARD_FLASH_SIZE := 2
|
||||
|
||||
#firmware config domain
|
||||
#
|
||||
|
||||
#set CONFIG_ENABLE_ACP to 1 to enable ACP, set to 0 or comment this line to disable
|
||||
#CONFIG_ENABLE_ACP:=1
|
||||
CONFIG_BL_IOT_FW_AP:=1
|
||||
CONFIG_BL_IOT_FW_AMPDU:=0
|
||||
CONFIG_BL_IOT_FW_AMSDU:=0
|
||||
CONFIG_BL_IOT_FW_P2P:=0
|
||||
CONFIG_ENABLE_PSM_RAM:=1
|
||||
#CONFIG_ENABLE_CAMERA:=1
|
||||
#CONFIG_ENABLE_BLSYNC:=1
|
||||
#CONFIG_ENABLE_VFS_SPI:=1
|
||||
CONFIG_ENABLE_VFS_ROMFS:=1
|
||||
|
||||
# set easyflash env psm size, only support 4K、8K、16K options
|
||||
CONFIG_ENABLE_PSM_EF_SIZE:=16K
|
||||
|
||||
CONFIG_FREERTOS_TICKLESS_MODE:=0
|
||||
|
||||
CONFIG_BT:=0
|
||||
CONFIG_WIFI:=0
|
||||
|
||||
#blog enable components format :=blog_testc cli vfs helper
|
||||
LOG_ENABLED_COMPONENTS:=blog_testc hal_drv loopset looprt bloop blestack
|
||||
|
||||
CONFIG_BL602_USE_ROM_DRIVER:=1
|
||||
|
26
customer_app/sdk_app_spi/sdk_app_spi/bouffalo.mk
Normal file
26
customer_app/sdk_app_spi/sdk_app_spi/bouffalo.mk
Normal file
@ -0,0 +1,26 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
||||
include $(BL60X_SDK_PATH)/components/network/ble/ble_common.mk
|
||||
|
||||
ifeq ($(CONFIG_ENABLE_PSM_RAM),1)
|
||||
CPPFLAGS += -DCONF_USER_ENABLE_PSRAM
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ENABLE_CAMERA),1)
|
||||
CPPFLAGS += -DCONF_USER_ENABLE_CAMERA
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ENABLE_BLSYNC),1)
|
||||
CPPFLAGS += -DCONF_USER_ENABLE_BLSYNC
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ENABLE_VFS_SPI),1)
|
||||
CPPFLAGS += -DCONF_USER_ENABLE_VFS_SPI
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ENABLE_VFS_ROMFS),1)
|
||||
CPPFLAGS += -DCONF_USER_ENABLE_VFS_ROMFS
|
||||
endif
|
169
customer_app/sdk_app_spi/sdk_app_spi/demo.c
Normal file
169
customer_app/sdk_app_spi/sdk_app_spi/demo.c
Normal file
@ -0,0 +1,169 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <cli.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <queue.h>
|
||||
#include <timers.h>
|
||||
|
||||
#include <vfs_err.h>
|
||||
#include <vfs_register.h>
|
||||
#include <vfs.h>
|
||||
#include <hal/soc/uart.h>
|
||||
#include <device/vfs_uart.h>
|
||||
#include <device/vfs_spi.h>
|
||||
|
||||
#include <blog.h>
|
||||
#include <bl_dma.h>
|
||||
|
||||
#define TRANSFER_SIZE 5111
|
||||
|
||||
|
||||
static void init_buf(uint8_t *buf, int size)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < TRANSFER_SIZE; i++) {
|
||||
buf[i] = i % 256;
|
||||
}
|
||||
}
|
||||
|
||||
void demo_spi_master(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
int a = 0;
|
||||
int spi_dev = -1;
|
||||
int ret;
|
||||
|
||||
uint8_t *pbuf0_tx = NULL;
|
||||
uint8_t *pbuf0_rx = NULL;
|
||||
struct spi_ioc_transfer *pxfer = NULL;
|
||||
|
||||
spi_dev = aos_open("/dev/spi0", 0);
|
||||
blog_info("start open spi_dev = %d.\r\n", spi_dev);
|
||||
if (spi_dev < 0) {
|
||||
blog_error("start open spi_dev = %d.\r\n", spi_dev);
|
||||
return;
|
||||
}
|
||||
|
||||
pbuf0_tx = bl_dma_mem_malloc(TRANSFER_SIZE);
|
||||
pbuf0_rx = bl_dma_mem_malloc(TRANSFER_SIZE);
|
||||
printf("pbuf0_tx = %p pbuf0_rx = %p \r\n", pbuf0_tx, pbuf0_rx);
|
||||
pxfer = (struct spi_ioc_transfer*)bl_dma_mem_malloc(2 * (sizeof(struct spi_ioc_transfer)));
|
||||
|
||||
if ((!pbuf0_tx) || (!pbuf0_rx) || (!pxfer)) {
|
||||
blog_error("mem err.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
init_buf(pbuf0_tx, TRANSFER_SIZE);
|
||||
memset(pbuf0_rx, 0x00, TRANSFER_SIZE);
|
||||
|
||||
pxfer[0].tx_buf = (uint32_t)pbuf0_tx;
|
||||
pxfer[0].rx_buf = (uint32_t)pbuf0_rx;
|
||||
pxfer[0].len = TRANSFER_SIZE;
|
||||
a = aos_ioctl(spi_dev, IOCTL_SPI_IOC_MESSAGE(1), (unsigned long)&pxfer[0]);
|
||||
if (a != 0) {
|
||||
blog_error("ERROR: SPI WRITE FAILURE\n");
|
||||
}
|
||||
|
||||
ret = memcmp(pbuf0_tx, pbuf0_rx, TRANSFER_SIZE);
|
||||
if (ret == 0) {
|
||||
printf("data corrcet \r\n");
|
||||
} else {
|
||||
printf("data error \r\n");
|
||||
}
|
||||
|
||||
bl_dma_mem_free(pbuf0_tx);
|
||||
bl_dma_mem_free(pbuf0_rx);
|
||||
bl_dma_mem_free(pxfer);
|
||||
aos_close(spi_dev);
|
||||
}
|
||||
|
||||
void demo_spi_slave(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
int a = 0;
|
||||
int spi_dev = -1;
|
||||
int ret;
|
||||
|
||||
uint8_t *pbuf0_tx = NULL;
|
||||
uint8_t *pbuf0_rx = NULL;
|
||||
struct spi_ioc_transfer *pxfer = NULL;
|
||||
|
||||
spi_dev = aos_open("/dev/spi0", 0);
|
||||
blog_info("start open spi_dev = %d.\r\n", spi_dev);
|
||||
if (spi_dev < 0) {
|
||||
blog_error("start open spi_dev = %d.\r\n", spi_dev);
|
||||
return;
|
||||
}
|
||||
|
||||
pbuf0_tx = bl_dma_mem_malloc(TRANSFER_SIZE);
|
||||
pbuf0_rx = bl_dma_mem_malloc(TRANSFER_SIZE);
|
||||
printf("pbuf0_tx = %p pbuf0_rx = %p \r\n", pbuf0_tx, pbuf0_rx);
|
||||
pxfer = (struct spi_ioc_transfer*)bl_dma_mem_malloc(2 * (sizeof(struct spi_ioc_transfer)));
|
||||
|
||||
if ((!pbuf0_tx) || (!pbuf0_rx) || (!pxfer)) {
|
||||
blog_error("mem err.\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
init_buf(pbuf0_tx, TRANSFER_SIZE);
|
||||
memset(pbuf0_rx, 0x00, TRANSFER_SIZE);
|
||||
|
||||
pxfer[0].tx_buf = (uint32_t)pbuf0_tx;
|
||||
pxfer[0].rx_buf = (uint32_t)pbuf0_rx;
|
||||
pxfer[0].len = TRANSFER_SIZE;
|
||||
a = aos_ioctl(spi_dev, IOCTL_SPI_IOC_MESSAGE(1), (unsigned long)&pxfer[0]);
|
||||
if (a != 0) {
|
||||
blog_error("ERROR: SPI WRITE FAILURE\n");
|
||||
}
|
||||
|
||||
ret = memcmp(pbuf0_tx, pbuf0_rx, TRANSFER_SIZE);
|
||||
if (ret == 0) {
|
||||
printf("data corrcet \r\n");
|
||||
} else {
|
||||
printf("data error \r\n");
|
||||
}
|
||||
|
||||
vPortFree(pbuf0_tx);
|
||||
vPortFree(pbuf0_rx);
|
||||
vPortFree(pxfer);
|
||||
aos_close(spi_dev);
|
||||
}
|
||||
|
||||
void spi_loop_master(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < 100; i++) {
|
||||
demo_spi_master(NULL, 1, 1, NULL);
|
||||
vTaskDelay(3000);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void spi_loop_slave(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
int i = 0;
|
||||
for (i = 0; i < 100; i++) {
|
||||
demo_spi_slave(NULL, 1, 1, NULL);
|
||||
vTaskDelay(200);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const static struct cli_command cmds_user[] STATIC_CLI_CMD_ATTRIBUTE = {
|
||||
{"test_slave", "spi test slave", demo_spi_slave},
|
||||
{"test_master", "spi test master", demo_spi_master},
|
||||
{"test_loop_master", "loop test master", spi_loop_master},
|
||||
{"test_loop_slave", "loop test slave", spi_loop_slave},
|
||||
};
|
||||
|
||||
int spi_cli_init(void)
|
||||
{
|
||||
// static command(s) do NOT need to call aos_cli_register_command(s) to register.
|
||||
// However, calling aos_cli_register_command(s) here is OK but is of no effect as cmds_user are included in cmds list.
|
||||
// XXX NOTE: Calling this *empty* function is necessary to make cmds_user in this file to be kept in the final link.
|
||||
//return aos_cli_register_commands(cmds_user, sizeof(cmds_user)/sizeof(cmds_user[0]));
|
||||
return 0;
|
||||
}
|
6
customer_app/sdk_app_spi/sdk_app_spi/demo.h
Normal file
6
customer_app/sdk_app_spi/sdk_app_spi/demo.h
Normal file
@ -0,0 +1,6 @@
|
||||
#ifndef __DEMO_H__
|
||||
#define __DEMO_H__
|
||||
|
||||
int spi_cli_init(void);
|
||||
|
||||
#endif
|
595
customer_app/sdk_app_spi/sdk_app_spi/main.c
Normal file
595
customer_app/sdk_app_spi/sdk_app_spi/main.c
Normal file
@ -0,0 +1,595 @@
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <timers.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <vfs.h>
|
||||
#include <aos/kernel.h>
|
||||
#include <aos/yloop.h>
|
||||
#include <event_device.h>
|
||||
#include <cli.h>
|
||||
|
||||
#include <bl602_glb.h>
|
||||
#include <bl602_hbn.h>
|
||||
|
||||
#include <bl_sys.h>
|
||||
#include <bl_uart.h>
|
||||
#include <bl_chip.h>
|
||||
#include <bl_wifi.h>
|
||||
#include <bl_sec.h>
|
||||
#include <bl_cks.h>
|
||||
#include <bl_irq.h>
|
||||
#include <bl_timer.h>
|
||||
#include <bl_dma.h>
|
||||
#include <bl_gpio_cli.h>
|
||||
#include <bl_wdt_cli.h>
|
||||
#include <hal_uart.h>
|
||||
#include <hal_sys.h>
|
||||
#include <hal_gpio.h>
|
||||
#include <hal_hbn.h>
|
||||
#include <hal_boot2.h>
|
||||
#include <hal_board.h>
|
||||
#include <hal_button.h>
|
||||
#include <looprt.h>
|
||||
#include <loopset.h>
|
||||
#include <bl_sys_time.h>
|
||||
#include <bl_romfs.h>
|
||||
#include <fdt.h>
|
||||
|
||||
#include <utils_log.h>
|
||||
#include <libfdt.h>
|
||||
#include <blog.h>
|
||||
#include <hal_spi.h>
|
||||
#include "demo.h"
|
||||
|
||||
|
||||
#define TASK_PRIORITY_FW ( 30 )
|
||||
#define mainHELLO_TASK_PRIORITY ( 20 )
|
||||
#define UART_ID_2 (2)
|
||||
#define WIFI_AP_PSM_INFO_SSID "conf_ap_ssid"
|
||||
#define WIFI_AP_PSM_INFO_PASSWORD "conf_ap_psk"
|
||||
#define WIFI_AP_PSM_INFO_PMK "conf_ap_pmk"
|
||||
#define WIFI_AP_PSM_INFO_BSSID "conf_ap_bssid"
|
||||
#define WIFI_AP_PSM_INFO_CHANNEL "conf_ap_channel"
|
||||
#define WIFI_AP_PSM_INFO_IP "conf_ap_ip"
|
||||
#define WIFI_AP_PSM_INFO_MASK "conf_ap_mask"
|
||||
#define WIFI_AP_PSM_INFO_GW "conf_ap_gw"
|
||||
#define WIFI_AP_PSM_INFO_DNS1 "conf_ap_dns1"
|
||||
#define WIFI_AP_PSM_INFO_DNS2 "conf_ap_dns2"
|
||||
#define WIFI_AP_PSM_INFO_IP_LEASE_TIME "conf_ap_ip_lease_time"
|
||||
#define WIFI_AP_PSM_INFO_GW_MAC "conf_ap_gw_mac"
|
||||
#define CLI_CMD_AUTOSTART1 "cmd_auto1"
|
||||
#define CLI_CMD_AUTOSTART2 "cmd_auto2"
|
||||
|
||||
extern uint8_t _heap_start;
|
||||
extern uint8_t _heap_size; // @suppress("Type cannot be resolved")
|
||||
extern uint8_t _heap_wifi_start;
|
||||
extern uint8_t _heap_wifi_size; // @suppress("Type cannot be resolved")
|
||||
static HeapRegion_t xHeapRegions[] =
|
||||
{
|
||||
{ &_heap_start, (unsigned int) &_heap_size}, //set on runtime
|
||||
{ &_heap_wifi_start, (unsigned int) &_heap_wifi_size },
|
||||
{ NULL, 0 }, /* Terminates the array. */
|
||||
{ NULL, 0 } /* Terminates the array. */
|
||||
};
|
||||
|
||||
void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName )
|
||||
{
|
||||
puts("Stack Overflow checked\r\n");
|
||||
while (1) {
|
||||
/*empty here*/
|
||||
}
|
||||
}
|
||||
|
||||
void vApplicationMallocFailedHook(void)
|
||||
{
|
||||
printf("Memory Allocate Failed. Current left size is %d bytes\r\n",
|
||||
xPortGetFreeHeapSize()
|
||||
);
|
||||
while (1) {
|
||||
/*empty here*/
|
||||
}
|
||||
}
|
||||
|
||||
void vApplicationIdleHook(void)
|
||||
{
|
||||
__asm volatile(
|
||||
" wfi "
|
||||
);
|
||||
/*empty*/
|
||||
}
|
||||
|
||||
static void proc_hellow_entry(void *pvParameters)
|
||||
{
|
||||
vTaskDelay(500);
|
||||
|
||||
while (1) {
|
||||
printf("%s: RISC-V rv32imafc\r\n", __func__);
|
||||
vTaskDelay(10000);
|
||||
}
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
static void cmd_exception_load(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
bl_irq_exception_trigger(BL_IRQ_EXCEPTION_TYPE_LOAD_MISALIGN, (void*)0x22008001);
|
||||
}
|
||||
|
||||
static void cmd_exception_l_illegal(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
bl_irq_exception_trigger(BL_IRQ_EXCEPTION_TYPE_ACCESS_ILLEGAL, (void*)0x00200000);
|
||||
}
|
||||
|
||||
static void cmd_exception_store(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
bl_irq_exception_trigger(BL_IRQ_EXCEPTION_TYPE_STORE_MISALIGN, (void*)0x22008001);
|
||||
}
|
||||
|
||||
static void cmd_exception_illegal_ins(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
bl_irq_exception_trigger(BL_IRQ_EXCEPTION_TYPE_ILLEGAL_INSTRUCTION, (void*)0x22008001);
|
||||
}
|
||||
|
||||
static void cmd_logen(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
bl_sys_logall_enable();
|
||||
}
|
||||
|
||||
static void cmd_logdis(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
bl_sys_logall_disable();
|
||||
}
|
||||
|
||||
static void cmd_load0w(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
volatile uint32_t v = 0;
|
||||
|
||||
/* backtrace */
|
||||
v = *(volatile uint32_t *)0;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
TEST_OP_GET32 = 0,
|
||||
TEST_OP_GET16,
|
||||
TEST_OP_SET32 = 256,
|
||||
TEST_OP_SET16,
|
||||
TEST_OP_MAX = 0x7FFFFFFF
|
||||
} test_op_t;
|
||||
static __attribute__ ((noinline)) uint32_t misaligned_acc_test(void *ptr, test_op_t op, uint32_t v)
|
||||
{
|
||||
uint32_t res = 0;
|
||||
|
||||
switch (op) {
|
||||
case TEST_OP_GET32:
|
||||
res = *(volatile uint32_t *)ptr;
|
||||
break;
|
||||
case TEST_OP_GET16:
|
||||
res = *(volatile uint16_t *)ptr;
|
||||
break;
|
||||
case TEST_OP_SET32:
|
||||
*(volatile uint32_t *)ptr = v;
|
||||
break;
|
||||
case TEST_OP_SET16:
|
||||
*(volatile uint16_t *)ptr = v;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void test_align(uint32_t buf)
|
||||
{
|
||||
volatile uint32_t testv[4] = {0};
|
||||
uint32_t t1 = 0;
|
||||
uint32_t t2 = 0;
|
||||
uint32_t t3 = 0;
|
||||
uint32_t i = 0;
|
||||
volatile uint32_t reg = buf;
|
||||
|
||||
portDISABLE_INTERRUPTS();
|
||||
|
||||
/* test get 32 */
|
||||
__asm volatile ("nop":::"memory");
|
||||
t1 = *(volatile uint32_t*)0x4000A52C;
|
||||
// 3*n + 5
|
||||
testv[0] = *(volatile uint32_t *)(reg + 0 * 8 + 1);
|
||||
t2 = *(volatile uint32_t*)0x4000A52C;
|
||||
// 3*n + 1
|
||||
testv[1] = *(volatile uint32_t *)(reg + 1 * 8 + 0);
|
||||
t3 = *(volatile uint32_t*)0x4000A52C;
|
||||
log_info("testv[0] = %08lx, testv[1] = %08lx\r\n", testv[0], testv[1]);
|
||||
log_info("time_us = %ld & %ld ---> %d\r\n", (t2 - t1), (t3 - t2), (t2 - t1)/(t3 - t2));
|
||||
|
||||
/* test get 16 */
|
||||
__asm volatile ("nop":::"memory");
|
||||
t1 = bl_timer_now_us();
|
||||
for (i = 0; i < 1 * 1000 * 1000; i++) {
|
||||
testv[0] = misaligned_acc_test((void *)(reg + 2 * 8 + 1), TEST_OP_GET16, 0);
|
||||
}
|
||||
t2 = bl_timer_now_us();
|
||||
for (i = 0; i < 1 * 1000 * 1000; i++) {
|
||||
testv[1] = misaligned_acc_test((void *)(reg + 3 * 8 + 0), TEST_OP_GET16, 0);
|
||||
}
|
||||
t3 = bl_timer_now_us();
|
||||
log_info("testv[0] = %08lx, testv[1] = %08lx\r\n", testv[0], testv[1]);
|
||||
log_info("time_us = %ld & %ld ---> %d\r\n", (t2 - t1), (t3 - t2), (t2 - t1)/(t3 - t2));
|
||||
|
||||
/* test set 32 */
|
||||
__asm volatile ("nop":::"memory");
|
||||
t1 = bl_timer_now_us();
|
||||
for (i = 0; i < 1 * 1000 * 1000; i++) {
|
||||
misaligned_acc_test((void *)(reg + 4 * 8 + 1), TEST_OP_SET32, 0x44332211);
|
||||
}
|
||||
t2 = bl_timer_now_us();
|
||||
for (i = 0; i < 1 * 1000 * 1000; i++) {
|
||||
misaligned_acc_test((void *)(reg + 5 * 8 + 0), TEST_OP_SET32, 0x44332211);
|
||||
}
|
||||
t3 = bl_timer_now_us();
|
||||
log_info("time_us = %ld & %ld ---> %d\r\n", (t2 - t1), (t3 - t2), (t2 - t1)/(t3 - t2));
|
||||
|
||||
/* test set 16 */
|
||||
__asm volatile ("nop":::"memory");
|
||||
t1 = bl_timer_now_us();
|
||||
for (i = 0; i < 1 * 1000 * 1000; i++) {
|
||||
misaligned_acc_test((void *)(reg + 6 * 8 + 1), TEST_OP_SET16, 0x6655);
|
||||
}
|
||||
t2 = bl_timer_now_us();
|
||||
for (i = 0; i < 1 * 1000 * 1000; i++) {
|
||||
misaligned_acc_test((void *)(reg + 7 * 8 + 0), TEST_OP_SET16, 0x6655);
|
||||
}
|
||||
t3 = bl_timer_now_us();
|
||||
log_info("time_us = %ld & %ld ---> %d\r\n", (t2 - t1), (t3 - t2), (t2 - t1)/(t3 - t2));
|
||||
|
||||
portENABLE_INTERRUPTS();
|
||||
}
|
||||
|
||||
void test_misaligned_access(void) __attribute__((optimize("O0")));
|
||||
void test_misaligned_access(void)// __attribute__((optimize("O0")))
|
||||
{
|
||||
#define TEST_V_LEN (32)
|
||||
__attribute__ ((aligned(16))) volatile unsigned char test_vector[TEST_V_LEN] = {0};
|
||||
int i = 0;
|
||||
volatile uint32_t v = 0;
|
||||
uint32_t addr = (uint32_t)test_vector;
|
||||
volatile char *pb = (volatile char *)test_vector;
|
||||
register float a asm("fa0") = 0.0f;
|
||||
register float b asm("fa1") = 0.5f;
|
||||
|
||||
for (i = 0; i < TEST_V_LEN; i ++)
|
||||
test_vector[i] = i;
|
||||
|
||||
addr += 1; // offset 1
|
||||
__asm volatile ("nop");
|
||||
v = *(volatile uint16_t *)(addr); // 0x0201
|
||||
__asm volatile ("nop");
|
||||
printf("%s: v=%8lx, should be 0x0201\r\n", __func__, v);
|
||||
__asm volatile ("nop");
|
||||
*(volatile uint16_t *)(addr) = 0x5aa5;
|
||||
__asm volatile ("nop");
|
||||
__asm volatile ("nop");
|
||||
v = *(volatile uint16_t *)(addr); // 0x5aa5
|
||||
__asm volatile ("nop");
|
||||
printf("%s: v=%8lx, should be 0x5aa5\r\n", __func__, v);
|
||||
|
||||
addr += 4; // offset 5
|
||||
__asm volatile ("nop");
|
||||
v = *(volatile uint32_t *)(addr); //0x08070605
|
||||
__asm volatile ("nop");
|
||||
printf("%s: v=%8lx, should be 0x08070605\r\n", __func__, v);
|
||||
__asm volatile ("nop");
|
||||
*(volatile uint32_t *)(addr) = 0xa5aa55a5;
|
||||
__asm volatile ("nop");
|
||||
__asm volatile ("nop");
|
||||
v = *(volatile uint32_t *)(addr); // 0xa5aa55a5
|
||||
__asm volatile ("nop");
|
||||
printf("%s: v=%8lx, should be 0xa5aa55a5\r\n", __func__, v);
|
||||
|
||||
pb[0x11] = 0x00;
|
||||
pb[0x12] = 0x00;
|
||||
pb[0x13] = 0xc0;
|
||||
pb[0x14] = 0x3f;
|
||||
|
||||
addr += 12; // offset 0x11
|
||||
__asm volatile ("nop");
|
||||
a = *(float *)(addr);
|
||||
__asm volatile ("nop");
|
||||
v = a * 4.0f; /* should be 6 */
|
||||
__asm volatile ("nop");
|
||||
__asm volatile ("nop");
|
||||
printf("%s: v=%8lx, should be 0x6\r\n", __func__, v);
|
||||
b = v / 12.0f;
|
||||
__asm volatile ("nop");
|
||||
addr += 4; // offset 0x15
|
||||
*(float *)(addr) = b;
|
||||
__asm volatile ("nop");
|
||||
v = *(volatile uint32_t *)(addr); // 0x3f000000
|
||||
__asm volatile ("nop");
|
||||
printf("%s: v=%8lx, should be 0x3f000000\r\n", __func__, v);
|
||||
}
|
||||
|
||||
static void cmd_align(char *buf, int len, int argc, char **argv)
|
||||
{
|
||||
char *testbuf = NULL;
|
||||
int i = 0;
|
||||
|
||||
log_info("align test start.\r\n");
|
||||
test_misaligned_access();
|
||||
|
||||
testbuf = aos_malloc(64);
|
||||
if (!testbuf) {
|
||||
log_error("mem error.\r\n");
|
||||
}
|
||||
|
||||
memset(testbuf, 0xEE, 1024);
|
||||
for (i = 0; i < 32; i++) {
|
||||
testbuf[i] = i;
|
||||
}
|
||||
test_align((uint32_t)(testbuf));
|
||||
|
||||
log_buf(testbuf, 64);
|
||||
aos_free(testbuf);
|
||||
|
||||
log_info("align test end.\r\n");
|
||||
}
|
||||
|
||||
const static struct cli_command cmds_user[] STATIC_CLI_CMD_ATTRIBUTE = {
|
||||
{ "exception_load", "exception load test", cmd_exception_load},
|
||||
{ "exception_l_illegal", "exception load test", cmd_exception_l_illegal},
|
||||
{ "exception_store", "exception store test", cmd_exception_store},
|
||||
{ "exception_inst_illegal", "exception illegal instruction", cmd_exception_illegal_ins},
|
||||
/*TCP/IP network test*/
|
||||
{"logen", "logen", cmd_logen},
|
||||
{"logdis", "logdis", cmd_logdis},
|
||||
{"load0w", "load word from 0", cmd_load0w},
|
||||
{"aligntc", "align case test", cmd_align},
|
||||
};
|
||||
|
||||
static void _cli_init()
|
||||
{
|
||||
bl_sys_time_cli_init();
|
||||
blfdt_cli_init();
|
||||
bl_wdt_cli_init();
|
||||
bl_gpio_cli_init();
|
||||
looprt_test_cli_init();
|
||||
}
|
||||
|
||||
static int get_dts_addr(const char *name, uint32_t *start, uint32_t *off)
|
||||
{
|
||||
uint32_t addr = hal_board_get_factory_addr();
|
||||
const void *fdt = (const void *)addr;
|
||||
uint32_t offset;
|
||||
|
||||
if (!name || !start || !off) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
offset = fdt_subnode_offset(fdt, 0, name);
|
||||
if (offset <= 0) {
|
||||
log_error("%s NULL.\r\n", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*start = (uint32_t)fdt;
|
||||
*off = offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __opt_feature_init(void)
|
||||
{
|
||||
#ifdef CONF_USER_ENABLE_VFS_ROMFS
|
||||
romfs_register();
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int test_lcd_base(void);
|
||||
static void aos_loop_proc(void *pvParameters)
|
||||
{
|
||||
int fd_console;
|
||||
uint32_t fdt = 0, offset = 0;
|
||||
static StackType_t proc_stack_looprt[512];
|
||||
static StaticTask_t proc_task_looprt;
|
||||
|
||||
/*Init bloop stuff*/
|
||||
looprt_start(proc_stack_looprt, 512, &proc_task_looprt);
|
||||
loopset_led_hook_on_looprt();
|
||||
|
||||
// easyflash_init();
|
||||
vfs_init();
|
||||
vfs_device_init();
|
||||
|
||||
/* uart */
|
||||
#if 1
|
||||
if (0 == get_dts_addr("uart", &fdt, &offset)) {
|
||||
vfs_uart_init(fdt, offset);
|
||||
}
|
||||
#else
|
||||
vfs_uart_init_simple_mode(0, 7, 16, 2 * 1000 * 1000, "/dev/ttyS0");
|
||||
#endif
|
||||
|
||||
if (0 == get_dts_addr("spi", &fdt, &offset)) {
|
||||
vfs_spi_fdt_init(fdt, offset);
|
||||
|
||||
}
|
||||
|
||||
__opt_feature_init();
|
||||
aos_loop_init();
|
||||
|
||||
fd_console = aos_open("/dev/ttyS0", 0);
|
||||
if (fd_console >= 0) {
|
||||
printf("Init CLI with event Driven\r\n");
|
||||
aos_cli_init(0);
|
||||
aos_poll_read_fd(fd_console, aos_cli_event_cb_read_get(), (void*)0x12345678);
|
||||
_cli_init();
|
||||
}
|
||||
|
||||
spi_cli_init();
|
||||
aos_loop_run();
|
||||
|
||||
puts("------------------------------------------\r\n");
|
||||
puts("+++++++++Critical Exit From Loop++++++++++\r\n");
|
||||
puts("******************************************\r\n");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)
|
||||
{
|
||||
/* If the buffers to be provided to the Idle task are declared inside this
|
||||
function then they must be declared static - otherwise they will be allocated on
|
||||
the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xIdleTaskTCB;
|
||||
static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Idle task's
|
||||
state will be stored. */
|
||||
*ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Idle task's stack. */
|
||||
*ppxIdleTaskStackBuffer = uxIdleTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
|
||||
Note that, as the array is necessarily of type StackType_t,
|
||||
configMINIMAL_STACK_SIZE is specified in words, not bytes. */
|
||||
*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
|
||||
}
|
||||
|
||||
/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
|
||||
application must provide an implementation of vApplicationGetTimerTaskMemory()
|
||||
to provide the memory that is used by the Timer service task. */
|
||||
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, StackType_t **ppxTimerTaskStackBuffer, uint32_t *pulTimerTaskStackSize)
|
||||
{
|
||||
/* If the buffers to be provided to the Timer task are declared inside this
|
||||
function then they must be declared static - otherwise they will be allocated on
|
||||
the stack and so not exists after this function exits. */
|
||||
static StaticTask_t xTimerTaskTCB;
|
||||
static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];
|
||||
|
||||
/* Pass out a pointer to the StaticTask_t structure in which the Timer
|
||||
task's state will be stored. */
|
||||
*ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
|
||||
|
||||
/* Pass out the array that will be used as the Timer task's stack. */
|
||||
*ppxTimerTaskStackBuffer = uxTimerTaskStack;
|
||||
|
||||
/* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
|
||||
Note that, as the array is necessarily of type StackType_t,
|
||||
configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
|
||||
*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
|
||||
}
|
||||
|
||||
void user_vAssertCalled(void) __attribute__ ((weak, alias ("vAssertCalled")));
|
||||
void vAssertCalled(void)
|
||||
{
|
||||
volatile uint32_t ulSetTo1ToExitFunction = 0;
|
||||
|
||||
taskDISABLE_INTERRUPTS();
|
||||
while( ulSetTo1ToExitFunction != 1 ) {
|
||||
__asm volatile( "NOP" );
|
||||
}
|
||||
}
|
||||
|
||||
static void _dump_boot_info(void)
|
||||
{
|
||||
char chip_feature[40];
|
||||
const char *banner;
|
||||
|
||||
puts("Booting BL602 Chip...\r\n");
|
||||
|
||||
/*Display Banner*/
|
||||
if (0 == bl_chip_banner(&banner)) {
|
||||
puts(banner);
|
||||
}
|
||||
puts("\r\n");
|
||||
/*Chip Feature list*/
|
||||
puts("\r\n");
|
||||
puts("------------------------------------------------------------\r\n");
|
||||
puts("RISC-V Core Feature:");
|
||||
bl_chip_info(chip_feature);
|
||||
puts(chip_feature);
|
||||
puts("\r\n");
|
||||
|
||||
puts("Build Version: ");
|
||||
puts(BL_SDK_VER); // @suppress("Symbol is not resolved")
|
||||
puts("\r\n");
|
||||
|
||||
puts("Build Version: ");
|
||||
puts(BL_SDK_VER); // @suppress("Symbol is not resolved")
|
||||
puts("\r\n");
|
||||
|
||||
puts("PHY Version: ");
|
||||
puts(BL_SDK_PHY_VER); // @suppress("Symbol is not resolved")
|
||||
puts("\r\n");
|
||||
|
||||
puts("RF Version: ");
|
||||
puts(BL_SDK_RF_VER); // @suppress("Symbol is not resolved")
|
||||
puts("\r\n");
|
||||
|
||||
puts("Build Date: ");
|
||||
puts(__DATE__);
|
||||
puts("\r\n");
|
||||
puts("Build Time: ");
|
||||
puts(__TIME__);
|
||||
puts("\r\n");
|
||||
puts("------------------------------------------------------------\r\n");
|
||||
|
||||
}
|
||||
|
||||
static void system_init(void)
|
||||
{
|
||||
blog_init();
|
||||
bl_irq_init();
|
||||
bl_sec_init();
|
||||
bl_sec_test();
|
||||
hal_boot2_init();
|
||||
bl_dma_init();
|
||||
|
||||
/* board config is set after system is init*/
|
||||
hal_board_cfg(0);
|
||||
}
|
||||
|
||||
static void system_thread_init()
|
||||
{
|
||||
/*nothing here*/
|
||||
}
|
||||
|
||||
|
||||
void bfl_main()
|
||||
{
|
||||
static StackType_t aos_loop_proc_stack[1024];
|
||||
static StaticTask_t aos_loop_proc_task;
|
||||
static StackType_t proc_hellow_stack[512];
|
||||
static StaticTask_t proc_hellow_task;
|
||||
|
||||
|
||||
bl_sys_early_init();
|
||||
|
||||
/*Init UART In the first place*/
|
||||
bl_uart_init(0, 16, 7, 255, 255, 2 * 1000 * 1000);
|
||||
puts("Starting bl602 now....\r\n");
|
||||
|
||||
bl_sys_init();
|
||||
|
||||
_dump_boot_info();
|
||||
|
||||
vPortDefineHeapRegions(xHeapRegions);
|
||||
printf("Heap %u@%p, %u@%p\r\n",
|
||||
(unsigned int)&_heap_size, &_heap_start,
|
||||
(unsigned int)&_heap_wifi_size, &_heap_wifi_start
|
||||
);
|
||||
|
||||
system_init();
|
||||
system_thread_init();
|
||||
|
||||
puts("[OS] Starting proc_hellow_entry task...\r\n");
|
||||
xTaskCreateStatic(proc_hellow_entry, (char*)"hellow", 512, NULL, 15, proc_hellow_stack, &proc_hellow_task);
|
||||
puts("[OS] Starting aos_loop_proc task...\r\n");
|
||||
xTaskCreateStatic(aos_loop_proc, (char*)"event_loop", 1024, NULL, 15, aos_loop_proc_stack, &aos_loop_proc_task);
|
||||
puts("[OS] Starting TCP/IP Stack...\r\n");
|
||||
|
||||
puts("[OS] Starting OS Scheduler...\r\n");
|
||||
vTaskStartScheduler();
|
||||
}
|
527
customer_app/sdk_app_spi/sdk_app_spi/tft_lcd.c
Normal file
527
customer_app/sdk_app_spi/sdk_app_spi/tft_lcd.c
Normal file
@ -0,0 +1,527 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tft_lcd.c
|
||||
* @version V1.0
|
||||
* @date
|
||||
* @brief This file is the peripheral case c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2019 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "tft_lcd.h"
|
||||
#include "bl602_glb.h"
|
||||
#include "bl602_spi.h"
|
||||
|
||||
/** @addtogroup BL602_Peripheral_Case
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TFT_LCD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup TFT_LCD_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group TFT_LCD_Private_Macros */
|
||||
|
||||
/** @defgroup TFT_LCD_Private_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group TFT_LCD_Private_Types */
|
||||
|
||||
/** @defgroup TFT_LCD_Private_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group TFT_LCD_Private_Variables */
|
||||
|
||||
/** @defgroup TFT_LCD_Global_Variables
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group TFT_LCD_Global_Variables */
|
||||
|
||||
/** @defgroup TFT_LCD_Private_Fun_Declaration
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group TFT_LCD_Private_Fun_Declaration */
|
||||
|
||||
/** @defgroup TFT_LCD_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group TFT_LCD_Private_Functions */
|
||||
|
||||
/** @defgroup TFT_LCD_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD write command
|
||||
*
|
||||
* @param command: Command to write
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_WR_Cmd(uint8_t command)
|
||||
{
|
||||
CS1_LOW;
|
||||
DC_LOW;
|
||||
SPI_Enable(SPI_ID,SPI_WORK_MODE_MASTER);
|
||||
SPI_Send_8bits(SPI_ID,&command,1,SPI_TIMEOUT_DISABLE);
|
||||
SPI_Disable(SPI_ID,SPI_WORK_MODE_MASTER);
|
||||
CS1_HIGH;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD write 8-bit data
|
||||
*
|
||||
* @param data: 8-bit data to write
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_WR_Byte(uint8_t data)
|
||||
{
|
||||
CS1_LOW;
|
||||
DC_HIGH;
|
||||
SPI_Enable(SPI_ID,SPI_WORK_MODE_MASTER);
|
||||
SPI_Send_8bits(SPI_ID,&data,1,SPI_TIMEOUT_DISABLE);
|
||||
SPI_Disable(SPI_ID,SPI_WORK_MODE_MASTER);
|
||||
CS1_HIGH;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD write 16-bit data
|
||||
*
|
||||
* @param data: 16-bit data to write
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_WR_HalfWord(uint16_t data)
|
||||
{
|
||||
CS1_LOW;
|
||||
DC_HIGH;
|
||||
SPI_Enable(SPI_ID,SPI_WORK_MODE_MASTER);
|
||||
SPI_Send_16bits(SPI_ID,&data,1,SPI_TIMEOUT_DISABLE);
|
||||
SPI_Disable(SPI_ID,SPI_WORK_MODE_MASTER);
|
||||
CS1_HIGH;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD write 32-bit data
|
||||
*
|
||||
* @param data: 32-bit data to write
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_WR_Word(uint32_t data)
|
||||
{
|
||||
CS1_LOW;
|
||||
DC_HIGH;
|
||||
SPI_Enable(SPI_ID,SPI_WORK_MODE_MASTER);
|
||||
SPI_Send_32bits(SPI_ID,&data,1,SPI_TIMEOUT_DISABLE);
|
||||
SPI_Disable(SPI_ID,SPI_WORK_MODE_MASTER);
|
||||
CS1_HIGH;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD set address
|
||||
*
|
||||
* @param x1: Coordinate x start
|
||||
* @param y1: Coordinate y start
|
||||
* @param x2: Coordinate x end
|
||||
* @param y2: Coordinate y end
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_Set_Addr(uint32_t x1,uint32_t y1,uint32_t x2,uint32_t y2)
|
||||
{
|
||||
LCD_WR_Cmd(0x2a);
|
||||
LCD_WR_Word(x2<<24 | (x2<<8&0xff0000) | (x1<<8&0xff00) | (x1>>8&0xff));
|
||||
|
||||
LCD_WR_Cmd(0x2b);
|
||||
LCD_WR_Word(y2<<24 | (y2<<8&0xff0000) | (y1<<8&0xff00) | (y1>>8&0xff));
|
||||
|
||||
LCD_WR_Cmd(0x2C);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief SPI LCD init
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_Init(void)
|
||||
{
|
||||
/* Reset */
|
||||
RES_LOW;
|
||||
BL602_Delay_MS(20);
|
||||
RES_HIGH;
|
||||
BL602_Delay_MS(20);
|
||||
|
||||
LCD_WR_Cmd(0x11); /* Exit sleep */
|
||||
BL602_Delay_MS(60);
|
||||
|
||||
LCD_WR_Cmd(0xcf);
|
||||
LCD_WR_HalfWord(0xd900);
|
||||
LCD_WR_Byte(0X30);
|
||||
|
||||
LCD_WR_Cmd(0xed);
|
||||
LCD_WR_Word(0x81120364);
|
||||
|
||||
LCD_WR_Cmd(0xe8);
|
||||
LCD_WR_HalfWord(0x1085);
|
||||
LCD_WR_Byte(0x78);
|
||||
|
||||
LCD_WR_Cmd(0xcb);
|
||||
LCD_WR_Word(0x34002c39);
|
||||
LCD_WR_Byte(0x02);
|
||||
|
||||
LCD_WR_Cmd(0xf7);
|
||||
LCD_WR_Byte(0x20);
|
||||
|
||||
LCD_WR_Cmd(0xea);
|
||||
LCD_WR_HalfWord(0x0000);
|
||||
|
||||
LCD_WR_Cmd(0xc0); /* Power control */
|
||||
LCD_WR_Byte(0x23); /* VRH[5:0] */
|
||||
LCD_WR_Cmd(0xc1); /* Power control */
|
||||
LCD_WR_Byte(0x12); /* SAP[2:0];BT[3:0] */
|
||||
LCD_WR_Cmd(0xc2);
|
||||
LCD_WR_Byte(0x11);
|
||||
LCD_WR_Cmd(0xC5); /* VCM control */
|
||||
LCD_WR_HalfWord(0x3040);
|
||||
LCD_WR_Cmd(0xc7); /* VCM control2 */
|
||||
LCD_WR_Byte(0xa9);
|
||||
LCD_WR_Cmd(0x3a);
|
||||
LCD_WR_Byte(0x55);
|
||||
LCD_WR_Cmd(0x36); /* Memory Access Control */
|
||||
LCD_WR_Byte(0x08);
|
||||
LCD_WR_Cmd(0xb1); /* Frame Rate Control */
|
||||
LCD_WR_HalfWord(0x1800);
|
||||
LCD_WR_Cmd(0xb6); /* Display Function Control */
|
||||
LCD_WR_HalfWord(0xa20a);
|
||||
LCD_WR_Cmd(0xf2); /* 3Gamma Function Disable */
|
||||
LCD_WR_Byte(0x00);
|
||||
LCD_WR_Cmd(0xf7);
|
||||
LCD_WR_Byte(0x20);
|
||||
LCD_WR_Cmd(0x26); /* Gamma curve selected */
|
||||
LCD_WR_Byte(0x01);
|
||||
LCD_WR_Cmd(0xe0); /* Set Gamma */
|
||||
LCD_WR_Word(0x0b23241f);
|
||||
LCD_WR_Word(0xd850080f);
|
||||
LCD_WR_Word(0x000a083b);
|
||||
LCD_WR_HalfWord(0x0000);
|
||||
LCD_WR_Byte(0x00);
|
||||
LCD_WR_Cmd(0Xe1); /* Set Gamma */
|
||||
LCD_WR_Word(0x041c1b00);
|
||||
LCD_WR_Word(0x272f0710);
|
||||
LCD_WR_Word(0x0f150744);
|
||||
LCD_WR_HalfWord(0x3f3f);
|
||||
LCD_WR_Byte(0x1f);
|
||||
LCD_WR_Cmd(0x29); /* Display on */
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD clear display
|
||||
*
|
||||
* @param color: Color to fill
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_Clear(uint16_t color)
|
||||
{
|
||||
uint16_t i,j;
|
||||
LCD_Set_Addr(0,0,LCD_W-1,LCD_H-1);
|
||||
for(i=0;i<LCD_W;i++){
|
||||
for (j=0;j<LCD_H;j++){
|
||||
LCD_WR_HalfWord(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD draw a point
|
||||
*
|
||||
* @param x: Coordinate x
|
||||
* @param y: Coordinate y
|
||||
* @param color: Color of the point
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color)
|
||||
{
|
||||
LCD_Set_Addr(x,y,x,y);
|
||||
LCD_WR_HalfWord(color);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD draw line
|
||||
*
|
||||
* @param x1: Coordinate x start
|
||||
* @param y1: Coordinate y start
|
||||
* @param x2: Coordinate x end
|
||||
* @param y2: Coordinate y end
|
||||
* @param color: Color of the line
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_DrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
|
||||
{
|
||||
int xVariation,yVariation,temp;
|
||||
int absX,absY,i;
|
||||
xVariation = x2-x1;
|
||||
yVariation = y2-y1;
|
||||
absX = ABS32(xVariation);
|
||||
absY = ABS32(yVariation);
|
||||
|
||||
if(absX > absY){
|
||||
for(i=0;i<absX+1;i++){
|
||||
temp = yVariation*100/absX*i/100;
|
||||
if(xVariation>0){
|
||||
LCD_DrawPoint(x1+i,y1+temp,color);
|
||||
}else{
|
||||
LCD_DrawPoint(x1-i,y1+temp,color);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(i=0;i<absY+1;i++){
|
||||
temp = xVariation*100/absY*i/100;
|
||||
if(yVariation>0){
|
||||
LCD_DrawPoint(x1+temp,y1+i,color);
|
||||
}else{
|
||||
LCD_DrawPoint(x1+temp,y1-i,color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD draw rectangle
|
||||
*
|
||||
* @param x1: Coordinate x start
|
||||
* @param y1: Coordinate y start
|
||||
* @param x2: Coordinate x end
|
||||
* @param y2: Coordinate y end
|
||||
* @param color: Color of the rectangle
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_DrawRectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
|
||||
{
|
||||
LCD_DrawLine(x1,y1,x2,y1,color);
|
||||
LCD_DrawLine(x2,y1,x2,y2,color);
|
||||
LCD_DrawLine(x2,y2,x1,y2,color);
|
||||
LCD_DrawLine(x1,y2,x1,y1,color);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD draw circle
|
||||
*
|
||||
* @param x: Center coordinate x
|
||||
* @param y: Center coordinate y
|
||||
* @param r: Radius
|
||||
* @param color: Color of the circle
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_DrawCircle(uint16_t x,uint16_t y,uint16_t r,uint16_t color)
|
||||
{
|
||||
int a = 0,b;
|
||||
int di;
|
||||
b = r;
|
||||
di = 3-(r<<1);
|
||||
while(a <= b)
|
||||
{
|
||||
LCD_DrawPoint(x-b,y-a,color);
|
||||
LCD_DrawPoint(x+b,y-a,color);
|
||||
LCD_DrawPoint(x-a,y+b,color);
|
||||
LCD_DrawPoint(x-b,y-a,color);
|
||||
LCD_DrawPoint(x-a,y-b,color);
|
||||
LCD_DrawPoint(x+b,y+a,color);
|
||||
LCD_DrawPoint(x+a,y-b,color);
|
||||
LCD_DrawPoint(x+a,y+b,color);
|
||||
LCD_DrawPoint(x-b,y+a,color);
|
||||
a++;
|
||||
if(di<0){
|
||||
di += 4*a+6;
|
||||
}else{
|
||||
di += 10+4*(a-b);
|
||||
b--;
|
||||
}
|
||||
LCD_DrawPoint(x+a,y+b,color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD fill the area with color
|
||||
*
|
||||
* @param x1: Coordinate x start
|
||||
* @param y1: Coordinate y start
|
||||
* @param x2: Coordinate x end
|
||||
* @param y2: Coordinate y end
|
||||
* @param color: Color to fill
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_DrawArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color)
|
||||
{
|
||||
uint16_t i,j;
|
||||
LCD_Set_Addr(x1,y1,x2,y2);
|
||||
for(i=y1;i<=y2;i++)
|
||||
{
|
||||
for(j=x1;j<=x2;j++)LCD_WR_HalfWord(color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD draw picture
|
||||
*
|
||||
* @param x1: Coordinate x start
|
||||
* @param y1: Coordinate y start
|
||||
* @param x2: Coordinate x end
|
||||
* @param y2: Coordinate y end
|
||||
* @param picture: Color array of the picture
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_DrawPicture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t* picture)
|
||||
{
|
||||
uint32_t i;
|
||||
LCD_Set_Addr(x1,y1,x2,y2);
|
||||
for(i=0;i<ABS16((x2-x1+1)*(y2-y1+1));i++)
|
||||
{
|
||||
LCD_WR_HalfWord(picture[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD use uart to receive picture data and send to display
|
||||
*
|
||||
* @param x1: Coordinate x start
|
||||
* @param y1: Coordinate y start
|
||||
* @param x2: Coordinate x end
|
||||
* @param y2: Coordinate y end
|
||||
* @param uartId: Color array of the picture
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_UartDrawPicture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,UART_ID_Type uartId)
|
||||
{
|
||||
uint32_t rxLen = 0,i;
|
||||
uint32_t recvCnt = 0;
|
||||
uint8_t uartRxBuf[UART_RX_FIFO_SIZE] = {0};
|
||||
LCD_Set_Addr(x1,y1,x2,y2);
|
||||
|
||||
UART_Enable(uartId,UART_RX);
|
||||
|
||||
while(rxLen < 2*(x2-x1+1)*(y2-y1+1)){
|
||||
while((recvCnt=UART_GetRxFifoCount(uartId)) == 0){}
|
||||
rxLen += UART_ReceiveData(uartId,uartRxBuf,recvCnt);
|
||||
for(i=0;i<recvCnt;i++){
|
||||
LCD_WR_Byte(uartRxBuf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
UART_Disable(uartId,UART_RX);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************//**
|
||||
* @brief LCD draw a 32*32 chinese character in lattice mode
|
||||
*
|
||||
* @param x: Coordinate x
|
||||
* @param y: Coordinate y
|
||||
* @param character: Array of the character
|
||||
* @param bColor: Color of the background
|
||||
* @param cColor: Color of the character
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
*******************************************************************************/
|
||||
void LCD_DrawChinese(uint16_t x,uint16_t y,uint8_t* character,uint16_t bColor,uint16_t cColor)
|
||||
{
|
||||
uint8_t i,j;
|
||||
LCD_Set_Addr(x,y,x+31,y+31);
|
||||
for(j=0;j<128;j++)
|
||||
{
|
||||
for(i=0;i<8;i++)
|
||||
{
|
||||
if((*character&(1<<i)) != 0)
|
||||
{
|
||||
LCD_WR_HalfWord(cColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD_WR_HalfWord(bColor);
|
||||
}
|
||||
}
|
||||
character++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*@} end of group TFT_LCD_Public_Functions */
|
||||
|
||||
/*@} end of group TFT_LCD */
|
||||
|
||||
/*@} end of group BL602_Peripheral_Case */
|
120
customer_app/sdk_app_spi/sdk_app_spi/tft_lcd.h
Normal file
120
customer_app/sdk_app_spi/sdk_app_spi/tft_lcd.h
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tft_lcd.h
|
||||
* @version V1.0
|
||||
* @date
|
||||
* @brief This file is the peripheral case header file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2020 Bouffalo Lab</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Bouffalo Lab nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#ifndef __TFT_LCD_H__
|
||||
#define __TFT_LCD_H__
|
||||
|
||||
#include "bl602_common.h"
|
||||
#include "bl602_uart.h"
|
||||
|
||||
/** @addtogroup BL602_Peripheral_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup TFT_LCD
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup TFT_LCD_Public_Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group TFT_LCD_Public_Types */
|
||||
|
||||
/** @defgroup TFT_LCD_Public_Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*@} end of group TFT_LCD_Public_Constants */
|
||||
|
||||
/** @defgroup TFT_LCD_Public_Macros
|
||||
* @{
|
||||
*/
|
||||
#define SPI_ID SPI_ID_0
|
||||
#define CS1 GLB_GPIO_PIN_2
|
||||
#define CLK GLB_GPIO_PIN_11
|
||||
#define MOSI GLB_GPIO_PIN_0
|
||||
#define MISO GLB_GPIO_PIN_1
|
||||
#define RES GLB_GPIO_PIN_4
|
||||
#define DC GLB_GPIO_PIN_12
|
||||
#define CS2 GLB_GPIO_PIN_15
|
||||
#define CS1_HIGH GLB_GPIO_Write(CS1,1)
|
||||
#define CS1_LOW GLB_GPIO_Write(CS1,0)
|
||||
#define RES_HIGH GLB_GPIO_Write(RES,1)
|
||||
#define RES_LOW GLB_GPIO_Write(RES,0)
|
||||
#define DC_HIGH GLB_GPIO_Write(DC,1)
|
||||
#define DC_LOW GLB_GPIO_Write(DC,0)
|
||||
#define CS2_HIGH GLB_GPIO_Write(CS2,1)
|
||||
#define CS2_LOW GLB_GPIO_Write(CS2,0)
|
||||
#define LCD_W 240 /* LCD width */
|
||||
#define LCD_H 320 /* LCD height */
|
||||
/* Turn 24-bit RGB color to 16-bit */
|
||||
#define RGB(r,g,b) (((r>>3)<<3|(g>>5)|(g>>2)<<13|(b>>3)<<8)&0xffff)
|
||||
/* Calculate 32-bit or 16-bit absolute value */
|
||||
#define ABS32(value) ((value^(value>>31))-(value>>31))
|
||||
#define ABS16(value) ((value^(value>>15))-(value>>15))
|
||||
|
||||
/*@} end of group TFT_LCD_Public_Macros */
|
||||
|
||||
/** @defgroup TFT_LCD_Public_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Tft_lcd Functions
|
||||
*/
|
||||
void LCD_WR_Cmd(uint8_t command);
|
||||
void LCD_WR_Byte(uint8_t data);
|
||||
void LCD_WR_HalfWord(uint16_t data);
|
||||
void LCD_WR_Word(uint32_t data);
|
||||
void LCD_Set_Addr(uint32_t x1,uint32_t y1,uint32_t x2,uint32_t y2);
|
||||
void LCD_Init(void);
|
||||
void LCD_Clear(uint16_t color);
|
||||
void LCD_DrawPoint(uint16_t x,uint16_t y,uint16_t color);
|
||||
void LCD_DrawLine(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color);
|
||||
void LCD_DrawRectangle(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color);
|
||||
void LCD_DrawCircle(uint16_t x,uint16_t y,uint16_t r,uint16_t color);
|
||||
void LCD_DrawArea(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t color);
|
||||
void LCD_DrawPicture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,uint16_t* picture);
|
||||
void LCD_UartDrawPicture(uint16_t x1,uint16_t y1,uint16_t x2,uint16_t y2,UART_ID_Type uartId);
|
||||
void LCD_DrawChinese(uint16_t x,uint16_t y,uint8_t* character,uint16_t bColor,uint16_t cColor);
|
||||
|
||||
/*@} end of group TFT_LCD_Public_Functions */
|
||||
|
||||
/*@} end of group TFT_LCD */
|
||||
|
||||
/*@} end of group BL602_Peripheral_Driver */
|
||||
|
||||
#endif /* __TFT_LCD_H__ */
|
Loading…
Reference in New Issue
Block a user