add lcd and spi for edu_riscv64 board

This commit is contained in:
Wang_Weigen 2022-10-25 14:26:33 +08:00
parent db2faeeba6
commit 166f88fd46
23 changed files with 3660 additions and 76 deletions

View File

@ -1,4 +1,4 @@
SRC_FILES := lv_init.c lv_demo.c lv_demo_calendar.c
SRC_FILES += lv_sensor_info.c lv_sensor_update_info.c lv_sensor_info_update_demo.c
# SRC_FILES += lv_sensor_info.c lv_sensor_update_info.c lv_sensor_info_update_demo.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -39,7 +39,7 @@ static void event_handler(lv_event_t * e)
void lv_demo_calendar(void)
{
lv_obj_t * calendar = lv_calendar_create(lv_scr_act());
lv_obj_set_size(calendar, 800, 480);//lv_obj_set_size(calendar, 800, 480);
lv_obj_set_size(calendar, 320, 320);//lv_obj_set_size(calendar, 800, 480);
lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 0);
lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);

View File

@ -15,23 +15,23 @@
/**
* @file board.c
* @brief support aiit-riscv64-board init configure and start-up
* @brief support edu-riscv64 board init configure and start-up
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
* @date 2022-10-25
*/
/*************************************************
File name: board.c
Description: support aiit-riscv64-board init configure and driver/task/... init
Description: support edu-riscv64 board init configure and driver/task/... init
Others: https://canaan-creative.com/developer
History:
1. Date: 2021-04-25
1. Date: 2022-10-25
Author: AIIT XUOS Lab
Modification:
1. support aiit-riscv64-board InitBoardHardware
2. support aiit-riscv64-board Kd233Start
3. support aiit-riscv64-board shell cmd, include reboot, shutdown
1. support edu-riscv64 board InitBoardHardware
2. support edu-riscv64 board Kd233Start
3. support edu-riscv64 board shell cmd, include reboot, shutdown
*************************************************/
#include <board.h>

View File

@ -10,21 +10,21 @@
/**
* @file drv_io_config.c
* @brief support aiit-riscv64-board io configure
* @brief support edu-riscv64 board io configure
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
* @date 2022-10-25
*/
/*************************************************
File name: drv_io_config.c
Description: support aiit-riscv64-board io configure
Description: support edu-riscv64 board io configure
Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_io_config.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
1. Date: 2022-10-25
Author: AIIT XUOS Lab
Modification: support aiit-riscv64-board io configure
Modification: support edu-riscv64 board io configure
*************************************************/
#include <xizi.h>

View File

@ -15,21 +15,21 @@
/**
* @file connect_lcd.h
* @brief define aiit-riscv64-board lcd function
* @brief define edu-riscv64 board lcd function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
* @date 2022-10-25
*/
/*************************************************
File name: connect_lcd.h
Description: define aiit-riscv64-board lcd function
Description: define edu-riscv64 board lcd function
Others: https://canaan-creative.com/developer
History:
1. Date: 2021-04-25
1. Date: 2022-10-25
Author: AIIT XUOS Lab
Modification:
1. add aiit-riscv64-board lcd function
1. add edu-riscv64 board lcd function
*************************************************/
#ifndef CONNECT_LCD_H

View File

@ -12,10 +12,10 @@
/**
* @file connect_spi.h
* @brief define aiit-riscv64-board spi function and struct
* @brief define edu-riscv64 board spi function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
* @date 2022-10-25
*/
#ifndef CONNECT_SPI_H

View File

@ -9,21 +9,21 @@
/**
* @file graphic.h
* @brief define aiit-riscv64-board lcd operation
* @brief define edu-riscv64 board lcd operation
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
* @date 2022-10-25
*/
/*************************************************
File name: graphic.h
Description: define aiit-riscv64-board lcd operation
Description: define edu-riscv64 board lcd operation
Others: take RT-Thread v4.0.2/include/rtdef.h for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
1. Date: 2022-10-25
Author: AIIT XUOS Lab
Modification: add aiit-riscv64-board lcd configure and operation function
Modification: add edu-riscv64 board lcd configure and operation function
*************************************************/
#ifndef GRAPHIC_H

View File

@ -19,7 +19,7 @@
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
* @date 2022-10-25
*/
#ifndef __HARDWARE_SPI_H__

View File

@ -58,6 +58,8 @@ extern int IoConfigInit(void);
extern int HwI2cInit(void);
extern int HwTouchInit(void);
extern int HwCh376Init(void);
extern int HwLcdInit(void);
extern int HwSpiInit(void);
#ifdef FS_CH376
#include <iot-vfs.h>
@ -170,7 +172,12 @@ struct InitSequenceDesc _board_init[] =
#ifdef BSP_USING_I2C
{ "hw_i2c", HwI2cInit },
#endif
#ifdef BSP_USING_SPI
{ "hw_spi", HwSpiInit },
#endif
#ifdef BSP_USING_LCD
{ "hw_lcd", HwLcdInit },
#endif
#ifdef BSP_USING_USB
{ "hw_usb", HwCh376Init},
#endif

View File

@ -1,63 +1,80 @@
menuconfig BSP_USING_CH376
bool "Using CH376 device"
default n
select FS_VFS
select FS_CH376
if BSP_USING_CH376
source "$BSP_DIR/third_party_driver/ch376/Kconfig"
endif
bool "Using CH376 device"
default n
select FS_VFS
select FS_CH376
if BSP_USING_CH376
source "$BSP_DIR/third_party_driver/ch376/Kconfig"
endif
menuconfig BSP_USING_SPI
bool "Using SPI device"
default n
select RESOURCES_SPI
select BSP_USING_DMA
if BSP_USING_SPI
source "$BSP_DIR/third_party_driver/spi/Kconfig"
endif
menuconfig BSP_USING_LCD
bool "Using LCD device"
default n
select BSP_USING_SPI
select RESOURCES_LCD
if BSP_USING_LCD
source "$BSP_DIR/third_party_driver/lcd/Kconfig"
endif
menuconfig BSP_USING_DMA
bool "Using DMA device"
default y
if BSP_USING_DMA
source "$BSP_DIR/third_party_driver/dma/Kconfig"
endif
bool "Using DMA device"
default y
if BSP_USING_DMA
source "$BSP_DIR/third_party_driver/dma/Kconfig"
endif
menuconfig BSP_USING_GPIO
bool "Using GPIO device"
default y
select RESOURCES_PIN
if BSP_USING_GPIO
source "$BSP_DIR/third_party_driver/gpio/Kconfig"
endif
bool "Using GPIO device"
default y
select RESOURCES_PIN
if BSP_USING_GPIO
source "$BSP_DIR/third_party_driver/gpio/Kconfig"
endif
menuconfig BSP_USING_I2C
bool "Using I2C device"
default n
select RESOURCES_I2C
if BSP_USING_I2C
source "$BSP_DIR/third_party_driver/i2c/Kconfig"
endif
bool "Using I2C device"
default n
select RESOURCES_I2C
if BSP_USING_I2C
source "$BSP_DIR/third_party_driver/i2c/Kconfig"
endif
menuconfig BSP_USING_TOUCH
bool "Using TOUCH device"
default n
select RESOURCES_TOUCH
select BSP_USING_I2C
if BSP_USING_TOUCH
source "$BSP_DIR/third_party_driver/touch/Kconfig"
endif
bool "Using TOUCH device"
default n
select BSP_USING_I2C
select RESOURCES_TOUCH
if BSP_USING_TOUCH
source "$BSP_DIR/third_party_driver/touch/Kconfig"
endif
menuconfig BSP_USING_PLIC
bool "Using PLIC device"
default y
if BSP_USING_PLIC
source "$BSP_DIR/third_party_driver/plic/Kconfig"
endif
bool "Using PLIC device"
default y
if BSP_USING_PLIC
source "$BSP_DIR/third_party_driver/plic/Kconfig"
endif
menuconfig BSP_USING_SYSCLOCK
bool "Using SYSCLOCK device"
default y
if BSP_USING_SYSCLOCK
source "$BSP_DIR/third_party_driver/sys_clock/Kconfig"
endif
bool "Using SYSCLOCK device"
default y
if BSP_USING_SYSCLOCK
source "$BSP_DIR/third_party_driver/sys_clock/Kconfig"
endif
menuconfig BSP_USING_UART
bool "Using UART device"
default y
select RESOURCES_SERIAL
if BSP_USING_UART
source "$BSP_DIR/third_party_driver/uart/Kconfig"
endif
bool "Using UART device"
default y
select RESOURCES_SERIAL
if BSP_USING_UART
source "$BSP_DIR/third_party_driver/uart/Kconfig"
endif

View File

@ -12,6 +12,10 @@ ifeq ($(CONFIG_BSP_USING_GPIO),y)
SRC_DIR += gpio
endif
ifeq ($(CONFIG_BSP_USING_SPI),y)
SRC_DIR += spi
endif
ifeq ($(CONFIG_BSP_USING_I2C),y)
SRC_DIR += i2c
endif
@ -32,4 +36,8 @@ ifeq ($(CONFIG_BSP_USING_UART),y)
SRC_DIR += uart
endif
ifeq ($(CONFIG_BSP_USING_LCD),y)
SRC_DIR += lcd
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -46,7 +46,8 @@ static struct io_config
#ifdef BSP_USING_LCD
IOCONFIG(BSP_LCD_CS_PIN, FUNC_SPI0_SS0),
IOCONFIG(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK),
IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(LCD_DC_PIN)),
IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(FPIOA_LCD_DC)),
IOCONFIG(BSP_LCD_RST_PIN, HS_GPIO(FPIOA_LCD_RST)),
#endif
#ifdef BSP_USING_SPI1

View File

@ -0,0 +1,52 @@
/* 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.
*/
/**
* @file connect_lcd.h
* @brief define aiit-riscv64-board lcd function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: connect_lcd.h
Description: define aiit-riscv64-board lcd function
Others: https://canaan-creative.com/developer
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. add aiit-riscv64-board lcd function
*************************************************/
#ifndef CONNECT_LCD_H
#define CONNECT_LCD_H
#include <device.h>
#include "hardware_spi.h"
#include <sysctl.h>
#ifdef BSP_USING_TOUCH
#include "connect_touch.h"
#endif
void DrvLcdClear(uint16_t color);
void LcdDrawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color);
void LcdDrawRectangle(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color);
void LcdDrawCircle(uint16 x0,uint16 y0,uint8 r,uint16 color);
int HwLcdInit(void);
#endif

View File

@ -0,0 +1,36 @@
/*
* 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_spi.h
* @brief define aiit-riscv64-board spi function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef CONNECT_SPI_H
#define CONNECT_SPI_H
#include <device.h>
#ifdef __cplusplus
extern "C" {
#endif
int HwSpiInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
/**
* @file graphic.h
* @brief define aiit-riscv64-board lcd operation
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: graphic.h
Description: define aiit-riscv64-board lcd operation
Others: take RT-Thread v4.0.2/include/rtdef.h for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification: add aiit-riscv64-board lcd configure and operation function
*************************************************/
#ifndef GRAPHIC_H
#define GRAPIHC_H
#include <xizi.h>
#define GRAPHIC_CTRL_RECT_UPDATE 0
#define GRAPHIC_CTRL_POWERON 1
#define GRAPHIC_CTRL_POWEROFF 2
#define GRAPHIC_CTRL_GET_INFO 3
#define GRAPHIC_CTRL_SET_MODE 4
#define GRAPHIC_CTRL_GET_EXT 5
enum
{
PIXEL_FORMAT_MONO = 0,
PIXEL_FORMAT_GRAY4,
PIXEL_FORMAT_GRAY16,
PIXEL_FORMAT_RGB332,
PIXEL_FORMAT_RGB444,
PIXEL_FORMAT_RGB565 ,
PIXEL_FORMAT_RGB565P,
PIXEL_FORMAT_BGR565 = PIXEL_FORMAT_RGB565P,
PIXEL_FORMAT_RGB666,
PIXEL_FORMAT_RGB888,
PIXEL_FORMAT_ARGB888,
PIXEL_FORMAT_ABGR888,
PIXEL_FORMAT_ARGB565,
PIXEL_FORMAT_ALPHA,
PIXEL_FORMAT_COLOR,
};
struct DeviceLcdInfo
{
uint8 pixel_format;
uint8 bits_per_pixel;
uint16 reserved;
uint16 width;
uint16 height;
uint8 *framebuffer;
};
struct DeviceRectInfo
{
uint16 x;
uint16 y;
uint16 width;
uint16 height;
};
struct DeviceGraphicDone
{
void (*set_pixel) (const char *pixel, int x, int y);
void (*get_pixel) (char *pixel, int x, int y);
void (*draw_hline) (const char *pixel, int x1, int x2, int y);
void (*draw_vline) (const char *pixel, int x, int y1, int y2);
void (*blit_line) (const char *pixel, int x, int y, x_size_t size);
};
#define GraphixDone(device) ((struct DeviceGraphicDone *)(device->UserData))
#endif

View File

@ -0,0 +1,494 @@
/* 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.
*/
/**
* @file hardware_spi.h
* @brief add from Canaan k210 SDK
* https://canaan-creative.com/developer
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef __HARDWARE_SPI_H__
#define __HARDWARE_SPI_H__
#include "dmac.h"
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* clang-format off */
typedef struct _spi
{
/* SPI Control Register 0 (0x00)*/
volatile uint32_t ctrlr0;
/* SPI Control Register 1 (0x04)*/
volatile uint32_t ctrlr1;
/* SPI Enable Register (0x08)*/
volatile uint32_t ssienr;
/* SPI Microwire Control Register (0x0c)*/
volatile uint32_t mwcr;
/* SPI Slave Enable Register (0x10)*/
volatile uint32_t ser;
/* SPI Baud Rate Select (0x14)*/
volatile uint32_t baudr;
/* SPI Transmit FIFO Threshold Level (0x18)*/
volatile uint32_t txftlr;
/* SPI Receive FIFO Threshold Level (0x1c)*/
volatile uint32_t rxftlr;
/* SPI Transmit FIFO Level Register (0x20)*/
volatile uint32_t txflr;
/* SPI Receive FIFO Level Register (0x24)*/
volatile uint32_t rxflr;
/* SPI Status Register (0x28)*/
volatile uint32_t sr;
/* SPI Interrupt Mask Register (0x2c)*/
volatile uint32_t imr;
/* SPI Interrupt Status Register (0x30)*/
volatile uint32_t isr;
/* SPI Raw Interrupt Status Register (0x34)*/
volatile uint32_t risr;
/* SPI Transmit FIFO Overflow Interrupt Clear Register (0x38)*/
volatile uint32_t txoicr;
/* SPI Receive FIFO Overflow Interrupt Clear Register (0x3c)*/
volatile uint32_t rxoicr;
/* SPI Receive FIFO Underflow Interrupt Clear Register (0x40)*/
volatile uint32_t rxuicr;
/* SPI Multi-Master Interrupt Clear Register (0x44)*/
volatile uint32_t msticr;
/* SPI Interrupt Clear Register (0x48)*/
volatile uint32_t icr;
/* SPI DMA Control Register (0x4c)*/
volatile uint32_t dmacr;
/* SPI DMA Transmit Data Level (0x50)*/
volatile uint32_t dmatdlr;
/* SPI DMA Receive Data Level (0x54)*/
volatile uint32_t dmardlr;
/* SPI Identification Register (0x58)*/
volatile uint32_t idr;
/* SPI DWC_ssi component version (0x5c)*/
volatile uint32_t ssic_version_id;
/* SPI Data Register 0-36 (0x60 -- 0xec)*/
volatile uint32_t dr[36];
/* SPI RX Sample Delay Register (0xf0)*/
volatile uint32_t rx_sample_delay;
/* SPI SPI Control Register (0xf4)*/
volatile uint32_t spi_ctrlr0;
/* reserved (0xf8)*/
volatile uint32_t resv;
/* SPI XIP Mode bits (0xfc)*/
volatile uint32_t xip_mode_bits;
/* SPI XIP INCR transfer opcode (0x100)*/
volatile uint32_t xip_incr_inst;
/* SPI XIP WRAP transfer opcode (0x104)*/
volatile uint32_t xip_wrap_inst;
/* SPI XIP Control Register (0x108)*/
volatile uint32_t xip_ctrl;
/* SPI XIP Slave Enable Register (0x10c)*/
volatile uint32_t xip_ser;
/* SPI XIP Receive FIFO Overflow Interrupt Clear Register (0x110)*/
volatile uint32_t xrxoicr;
/* SPI XIP time out register for continuous transfers (0x114)*/
volatile uint32_t xip_cnt_time_out;
volatile uint32_t endian;
} __attribute__((packed, aligned(4))) spi_t;
/* clang-format on */
typedef enum _spi_device_num
{
SPI_DEVICE_0,
SPI_DEVICE_1,
SPI_DEVICE_2,
SPI_DEVICE_3,
SPI_DEVICE_MAX,
} spi_device_num_t;
typedef enum _spi_work_mode
{
SPI_WORK_MODE_0,
SPI_WORK_MODE_1,
SPI_WORK_MODE_2,
SPI_WORK_MODE_3,
} spi_work_mode_t;
typedef enum _spi_frame_format
{
SPI_FF_STANDARD,
SPI_FF_DUAL,
SPI_FF_QUAD,
SPI_FF_OCTAL
} spi_frame_format_t;
typedef enum _spi_instruction_address_trans_mode
{
SPI_AITM_STANDARD,
SPI_AITM_ADDR_STANDARD,
SPI_AITM_AS_FRAME_FORMAT
} spi_instruction_address_trans_mode_t;
typedef enum _spi_transfer_mode
{
SPI_TMOD_TRANS_RECV,
SPI_TMOD_TRANS,
SPI_TMOD_RECV,
SPI_TMOD_EEROM
} spi_transfer_mode_t;
typedef enum _spi_transfer_width
{
SPI_TRANS_CHAR = 0x1,
SPI_TRANS_SHORT = 0x2,
SPI_TRANS_INT = 0x4,
} spi_transfer_width_t;
typedef enum _spi_chip_select
{
SPI_CHIP_SELECT_0,
SPI_CHIP_SELECT_1,
SPI_CHIP_SELECT_2,
SPI_CHIP_SELECT_3,
SPI_CHIP_SELECT_MAX,
} spi_chip_select_t;
typedef enum
{
WRITE_CONFIG,
READ_CONFIG,
WRITE_DATA_BYTE,
READ_DATA_BYTE,
WRITE_DATA_BLOCK,
READ_DATA_BLOCK,
} spi_slave_command_e;
typedef struct
{
uint8_t cmd;
uint8_t err;
uint32_t addr;
uint32_t len;
} spi_slave_command_t;
typedef enum
{
IDLE,
COMMAND,
TRANSFER,
} spi_slave_status_e;
typedef int (*spi_slave_receive_callback_t)(void *ctx);
typedef struct _spi_slave_instance
{
uint8_t int_pin;
uint8_t ready_pin;
dmac_channel_number_t dmac_channel;
uint8_t dfs;
uint8_t slv_oe;
uint8_t work_mode;
size_t data_bit_length;
volatile spi_slave_status_e status;
volatile spi_slave_command_t command;
volatile uint8_t *config_ptr;
uint32_t config_len;
spi_slave_receive_callback_t callback;
} spi_slave_instance_t;
typedef struct _spi_data_t
{
dmac_channel_number_t tx_channel;
dmac_channel_number_t rx_channel;
uint32_t *tx_buf;
size_t tx_len;
uint32_t *rx_buf;
size_t rx_len;
spi_transfer_mode_t TransferMode;
bool fill_mode;
} spi_data_t;
extern volatile spi_t *const spi[4];
/**
* @brief Set spi configuration
*
* @param[in] spi_num Spi bus number
* @param[in] mode Spi mode
* @param[in] frame_format Spi frame format
* @param[in] data_bit_length Spi data bit length
* @param[in] endian 0:little-endian 1:big-endian
*
* @return Void
*/
void spi_init(spi_device_num_t spi_num, spi_work_mode_t work_mode, spi_frame_format_t frame_format,
size_t data_bit_length, uint32_t endian);
/**
* @brief Set multiline configuration
*
* @param[in] spi_num Spi bus number
* @param[in] instruction_length Instruction length
* @param[in] address_length Address length
* @param[in] wait_cycles Wait cycles
* @param[in] instruction_address_trans_mode Spi transfer mode
*
*/
void spi_init_non_standard(spi_device_num_t spi_num, uint32_t instruction_length, uint32_t address_length,
uint32_t wait_cycles, spi_instruction_address_trans_mode_t instruction_address_trans_mode);
/**
* @brief Spi send data
*
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] CmdBuff Spi command buffer point
* @param[in] CmdLen Spi command length
* @param[in] tx_buff Spi transmit buffer point
* @param[in] tx_len Spi transmit buffer length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_send_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff,
size_t CmdLen, const uint8_t *tx_buff, size_t tx_len);
/**
* @brief Spi receive data
*
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] CmdBuff Spi command buffer point
* @param[in] CmdLen Spi command length
* @param[in] rx_buff Spi receive buffer point
* @param[in] rx_len Spi receive buffer length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_receive_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff,
size_t CmdLen, uint8_t *rx_buff, size_t rx_len);
/**
* @brief Spi special receive data
*
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] CmdBuff Spi command buffer point
* @param[in] CmdLen Spi command length
* @param[in] rx_buff Spi receive buffer point
* @param[in] rx_len Spi receive buffer length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_receive_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff,
size_t CmdLen, uint8_t *rx_buff, size_t rx_len);
/**
* @brief Spi special send data
*
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] CmdBuff Spi command buffer point
* @param[in] CmdLen Spi command length
* @param[in] tx_buff Spi transmit buffer point
* @param[in] tx_len Spi transmit buffer length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_send_data_multiple(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff,
size_t CmdLen, const uint8_t *tx_buff, size_t tx_len);
/**
* @brief Spi send data by dma
*
* @param[in] channel_num Dmac channel number
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] CmdBuff Spi command buffer point
* @param[in] CmdLen Spi command length
* @param[in] tx_buff Spi transmit buffer point
* @param[in] tx_len Spi transmit buffer length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_send_data_standard_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num,
spi_chip_select_t chip_select,
const uint8_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len);
/**
* @brief Spi receive data by dma
*
* @param[in] w_channel_num Dmac write channel number
* @param[in] r_channel_num Dmac read channel number
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] CmdBuff Spi command buffer point
* @param[in] CmdLen Spi command length
* @param[in] rx_buff Spi receive buffer point
* @param[in] rx_len Spi receive buffer length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_receive_data_standard_dma(dmac_channel_number_t dma_send_channel_num,
dmac_channel_number_t dma_receive_channel_num,
spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *CmdBuff,
size_t CmdLen, uint8_t *rx_buff, size_t rx_len);
/**
* @brief Spi special send data by dma
*
* @param[in] channel_num Dmac channel number
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] CmdBuff Spi command buffer point
* @param[in] CmdLen Spi command length
* @param[in] tx_buff Spi transmit buffer point
* @param[in] tx_len Spi transmit buffer length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_send_data_multiple_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num,
spi_chip_select_t chip_select,
const uint32_t *CmdBuff, size_t CmdLen, const uint8_t *tx_buff, size_t tx_len);
/**
* @brief Spi special receive data by dma
*
* @param[in] dma_send_channel_num Dmac write channel number
* @param[in] dma_receive_channel_num Dmac read channel number
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] CmdBuff Spi command buffer point
* @param[in] CmdLen Spi command length
* @param[in] rx_buff Spi receive buffer point
* @param[in] rx_len Spi receive buffer length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_receive_data_multiple_dma(dmac_channel_number_t dma_send_channel_num,
dmac_channel_number_t dma_receive_channel_num,
spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint32_t *CmdBuff,
size_t CmdLen, uint8_t *rx_buff, size_t rx_len);
/**
* @brief Spi fill dma
*
* @param[in] channel_num Dmac channel number
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] tx_buff Spi command buffer point
* @param[in] tx_len Spi command length
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_fill_data_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num, spi_chip_select_t chip_select,
const uint32_t *tx_buff, size_t tx_len);
/**
* @brief Spi normal send by dma
*
* @param[in] channel_num Dmac channel number
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] tx_buff Spi transmit buffer point
* @param[in] tx_len Spi transmit buffer length
* @param[in] stw Spi transfer width
*
* @return Result
* - 0 Success
* - Other Fail
*/
void spi_send_data_normal_dma(dmac_channel_number_t channel_num, spi_device_num_t spi_num,
spi_chip_select_t chip_select,
const void *tx_buff, size_t tx_len, spi_transfer_width_t spi_transfer_width);
/**
* @brief Spi normal send by dma
*
* @param[in] spi_num Spi bus number
* @param[in] spi_clk Spi clock rate
*
* @return The real spi clock rate
*/
uint32_t spi_set_clk_rate(spi_device_num_t spi_num, uint32_t spi_clk);
/**
* @brief Spi full duplex send receive data by dma
*
* @param[in] dma_send_channel_num Dmac write channel number
* @param[in] dma_receive_channel_num Dmac read channel number
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] tx_buf Spi send buffer
* @param[in] tx_len Spi send buffer length
* @param[in] rx_buf Spi receive buffer
* @param[in] rx_len Spi receive buffer length
*
*/
void spi_dup_send_receive_data_dma(dmac_channel_number_t dma_send_channel_num,
dmac_channel_number_t dma_receive_channel_num,
spi_device_num_t spi_num, spi_chip_select_t chip_select,
const uint8_t *tx_buf, size_t tx_len, uint8_t *rx_buf, size_t rx_len);
/**
* @brief Set spi slave configuration
*
* @param[in] int_pin SPI master starts sending data interrupt.
* @param[in] ready_pin SPI slave ready.
* @param[in] dmac_channel Dmac channel number for block.
* @param[in] data_bit_length Spi data bit length
* @param[in] data SPI slave device data buffer.
* @param[in] len The length of SPI slave device data buffer.
* @param[in] callback Callback of spi slave.
*
* @return Void
*/
void spi_slave_config(uint8_t int_pin, uint8_t ready_pin, dmac_channel_number_t dmac_channel, size_t data_bit_length, uint8_t *data, uint32_t len, spi_slave_receive_callback_t callback);
/**
* @brief Spi handle transfer data operations
*
* @param[in] spi_num Spi bus number
* @param[in] chip_select Spi chip select
* @param[in] data Spi transfer data information
* @param[in] cb Spi DMA callback
*
*/
void spi_handle_data_dma(spi_device_num_t spi_num, spi_chip_select_t chip_select, spi_data_t data, plic_interrupt_t *cb);
#ifdef __cplusplus
}
#endif
#endif /* __HARDWARE_SPI_H__ */

View File

@ -0,0 +1,36 @@
if BSP_USING_LCD
config LCD_BUS_NAME
string "lcd bus name"
default "lcd"
config LCD_DRV_NAME
string "lcd bus driver name"
default "lcd_drv"
config LCD_DEVICE_NAME
string "lcd bus device name"
default "lcd_dev"
config BSP_LCD_CS_PIN
int "CS pin number of 8080 interface"
default 37
config BSP_LCD_WR_PIN
int "WR pin number of 8080 interface"
default 38
config BSP_LCD_DC_PIN
int "DC pin number of 8080 interface"
default 39
config BSP_LCD_RST_PIN
int "RST pin number of 8080 interface"
default 36
config FPIOA_LCD_DC
int "DC FPIOA number of 8080 interface"
default 9
config FPIOA_LCD_RST
int "RST FPIOA number of 8080 interface"
default 10
config BSP_LCD_X_MAX
int "LCD Height"
default 320
config BSP_LCD_Y_MAX
int "LCD Width"
default 320
endif

View File

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

View File

@ -0,0 +1,704 @@
/* 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.
*/
/**
* @file connect_lcd.c
* @brief support aiit-riscv64-board lcd function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: connect_lcd.c
Description: support aiit-riscv64-board lcd configure and lcd bus register function
Others: https://canaan-creative.com/developer
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. support aiit-riscv64-board lcd configure, write and read
2. support aiit-riscv64-board lcd bus device and driver register
*************************************************/
#include <connect_lcd.h>
#include <board.h>
#include <drv_io_config.h>
#include <font.h>
#include <fpioa.h>
#include <gpiohs.h>
#include <graphic.h>
#define NO_OPERATION 0x00
#define SOFTWARE_RESET 0x01
#define READ_ID 0x04
#define READ_STATUS 0x09
#define READ_POWER_MODE 0x0A
#define READ_MADCTL 0x0B
#define READ_PIXEL_FORMAT 0x0C
#define READ_IMAGE_FORMAT 0x0D
#define READ_SIGNAL_MODE 0x0E
#define READ_SELT_DIAG_RESULT 0x0F
#define SLEEP_ON 0x10
#define SLEEP_OFF 0x11
#define PARTIAL_DISPALY_ON 0x12
#define NORMAL_DISPALY_ON 0x13
#define INVERSION_DISPALY_OFF 0x20
#define INVERSION_DISPALY_ON 0x21
#define GAMMA_SET 0x26
#define DISPALY_OFF 0x28
#define DISPALY_ON 0x29
#define HORIZONTAL_ADDRESS_SET 0x2A
#define VERTICAL_ADDRESS_SET 0x2B
#define MEMORY_WRITE 0x2C
#define COLOR_SET 0x2D
#define MEMORY_READ 0x2E
#define PARTIAL_AREA 0x30
#define VERTICAL_SCROL_DEFINE 0x33
#define TEAR_EFFECT_LINE_OFF 0x34
#define TEAR_EFFECT_LINE_ON 0x35
#define MEMORY_ACCESS_CTL 0x36
#define VERTICAL_SCROL_S_ADD 0x37
#define IDLE_MODE_OFF 0x38
#define IDLE_MODE_ON 0x39
#define PIXEL_FORMAT_SET 0x3A
#define WRITE_MEMORY_CONTINUE 0x3C
#define READ_MEMORY_CONTINUE 0x3E
#define SET_TEAR_SCANLINE 0x44
#define GET_SCANLINE 0x45
#define WRITE_BRIGHTNESS 0x51
#define READ_BRIGHTNESS 0x52
#define WRITE_CTRL_DISPALY 0x53
#define READ_CTRL_DISPALY 0x54
#define WRITE_BRIGHTNESS_CTL 0x55
#define READ_BRIGHTNESS_CTL 0x56
#define WRITE_MIN_BRIGHTNESS 0x5E
#define READ_MIN_BRIGHTNESS 0x5F
#define READ_ID1 0xDA
#define READ_ID2 0xDB
#define READ_ID3 0xDC
#define RGB_IF_SIGNAL_CTL 0xB0
#define NORMAL_FRAME_CTL 0xB1
#define IDLE_FRAME_CTL 0xB2
#define PARTIAL_FRAME_CTL 0xB3
#define INVERSION_CTL 0xB4
#define BLANK_PORCH_CTL 0xB5
#define DISPALY_FUNCTION_CTL 0xB6
#define ENTRY_MODE_SET 0xB7
#define BACKLIGHT_CTL1 0xB8
#define BACKLIGHT_CTL2 0xB9
#define BACKLIGHT_CTL3 0xBA
#define BACKLIGHT_CTL4 0xBB
#define BACKLIGHT_CTL5 0xBC
#define BACKLIGHT_CTL7 0xBE
#define BACKLIGHT_CTL8 0xBF
#define POWER_CTL1 0xC0
#define POWER_CTL2 0xC1
#define VCOM_CTL1 0xC5
#define VCOM_CTL2 0xC7
#define NV_MEMORY_WRITE 0xD0
#define NV_MEMORY_PROTECT_KEY 0xD1
#define NV_MEMORY_STATUS_READ 0xD2
#define READ_ID4 0xD3
#define POSITIVE_GAMMA_CORRECT 0xE0
#define NEGATIVE_GAMMA_CORRECT 0xE1
#define DIGITAL_GAMMA_CTL1 0xE2
#define DIGITAL_GAMMA_CTL2 0xE3
#define INTERFACE_CTL 0xF6
typedef enum _lcd_dir
{
DIR_XY_RLUD = 0x00,
DIR_YX_RLUD = 0x20,
DIR_XY_LRUD = 0x40,
DIR_YX_LRUD = 0x60,
DIR_XY_RLDU = 0x80,
DIR_YX_RLDU = 0xA0,
DIR_XY_LRDU = 0xC0,
DIR_YX_LRDU = 0xE0,
DIR_XY_MASK = 0x20,
DIR_MASK = 0xE0,
} lcd_dir_t;
#define LCD_SPI_CHANNEL SPI_DEVICE_0
#define LCD_SPI_CHIP_SELECT SPI_CHIP_SELECT_0
typedef struct Lcd8080Device
{
struct LcdBus lcd_bus;
struct DeviceLcdInfo lcd_info;
int spi_channel;
int cs;
int dc_pin;
int dma_channel;
} * Lcd8080DeviceType;
Lcd8080DeviceType aiit_lcd ;
static void DrvLcdCmd(uint8 cmd)
{
gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_LOW);
spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
spi_init_non_standard(aiit_lcd->spi_channel/*spi num*/, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, &cmd, 1, SPI_TRANS_CHAR);
}
static void DrvLcdDataByte(uint8 *data_buf, uint32 length)
{
gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH);
spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
spi_init_non_standard(aiit_lcd->spi_channel, 8 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_CHAR);
}
static void DrvLcdDataHalfWord(uint16 *data_buf, uint32 length)
{
gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH);
spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0);
spi_init_non_standard(aiit_lcd->spi_channel, 16 /*instrction length*/, 0 /*address length*/, 0 /*wait cycles*/,
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_SHORT);
}
static void DrvLcdDataWord(uint32 *data_buf, uint32 length)
{
gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH);
/*spi num Polarity and phase mode Multi-line mode Data bit width little endian */
spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0);
/* spi num instrction length address length wait cycles spi address trans mode*/
spi_init_non_standard(aiit_lcd->spi_channel, 0 , 32, 0 ,SPI_AITM_AS_FRAME_FORMAT );
/*dma channel spi num chip_selete tx_buff tx_len spi_trans_data_width */
spi_send_data_normal_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, data_buf, length, SPI_TRANS_INT);
}
static void DrvLcdHwInit(Lcd8080DeviceType lcd)
{
gpiohs_set_drive_mode(lcd->dc_pin, GPIO_DM_OUTPUT);
gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH);
spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
spi_set_clk_rate(lcd->spi_channel, 25000000);
}
static void DrvLcdSetDirection(lcd_dir_t dir)
{
#if !BOARD_LICHEEDAN
dir |= 0x08;
#endif
if (dir & DIR_XY_MASK) {
aiit_lcd->lcd_info.width = BSP_LCD_Y_MAX;
aiit_lcd->lcd_info.height = BSP_LCD_X_MAX;
} else {
aiit_lcd->lcd_info.width = BSP_LCD_X_MAX;
aiit_lcd->lcd_info.height = BSP_LCD_Y_MAX;
}
DrvLcdCmd(MEMORY_ACCESS_CTL);
DrvLcdDataByte((uint8 *)&dir, 1);
}
static void DrvLcdSetArea(uint16 x1, uint16 y1, uint16 x2, uint16 y2)
{
uint8 data[4] = {0};
data[0] = (uint8)(x1 >> 8);
data[1] = (uint8)(x1);
data[2] = (uint8)(x2 >> 8);
data[3] = (uint8)(x2);
DrvLcdCmd(HORIZONTAL_ADDRESS_SET);
DrvLcdDataByte(data, 4);
data[0] = (uint8)(y1 >> 8);
data[1] = (uint8)(y1);
data[2] = (uint8)(y2 >> 8);
data[3] = (uint8)(y2);
DrvLcdCmd(VERTICAL_ADDRESS_SET);
DrvLcdDataByte(data, 4);
DrvLcdCmd(MEMORY_WRITE);
}
static void DrvLcdSetPixel(uint16_t x, uint16_t y, uint16_t color)
{
DrvLcdSetArea(x, y, x, y);
DrvLcdDataHalfWord(&color, 1);
}
static void DrvLcdSetPixelDot(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2,void* color)
{
uint32 size = 0;
size = (x2- x1 + 1)*(y2 - y1 + 1);
DrvLcdSetArea(x1, y1, x2, y2);
DrvLcdDataHalfWord(color, size);
}
void LcdShowChar(uint16 x,uint16 y,uint8 num,uint8 size,uint16 color,uint16 back_color)
{
uint8 temp,t1,t;
uint16 y0=y;
uint8 csize=(size/8+((size%8)?1:0))*(size/2);
num=num-' ';
for (t = 0;t < csize;t ++) {
if (size==12)
temp=asc2_1206[num][t]; //1206
else if (size==16)
temp=asc2_1608[num][t]; //1608
else if (size==24)
temp=asc2_2412[num][t]; //2412
else if (size==32)
temp=asc2_3216[num][t]; //3216
else
return;
for(t1 = 0;t1 < 8;t1 ++) {
if (temp&0x80)
DrvLcdSetPixel(x,y,color);
else
DrvLcdSetPixel(x,y,back_color);
temp<<=1;
y++;
if(y>=aiit_lcd->lcd_info.height)
return;
if ((y-y0) == size) {
y=y0;
x++;
if(x>=aiit_lcd->lcd_info.width)
return;
break;
}
}
}
}
void LcdShowString(uint16_t x,uint16_t y,uint16_t width,uint16_t height,uint8 size,uint8 *p,uint16_t color,uint16_t back_color)
{
uint16_t x0 = x;
width += x;
height += y;
while ((*p<='~')&&(*p>=' ')) {
if (x>=width) {
x=x0;
y+=size;
}
if(y>=height)
break;
LcdShowChar(x,y,*p,size,color,back_color);
x += size/2;
p++;
}
}
/*
* clear lcd by color
* para color
* return none
*/
void DrvLcdClear(uint16 color)
{
uint32 data = ((uint32)color << 16) | (uint32)color;
DrvLcdSetArea(0, 0, aiit_lcd->lcd_info.width - 1, aiit_lcd->lcd_info.height - 1);
gpiohs_set_pin(aiit_lcd->dc_pin, GPIO_PV_HIGH);
spi_init(aiit_lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0);
spi_init_non_standard(aiit_lcd->spi_channel,
0 /*instrction length*/,
32 /*address length */,
0 /*wait cycles */,
SPI_AITM_AS_FRAME_FORMAT );
spi_fill_data_dma(aiit_lcd->dma_channel, aiit_lcd->spi_channel, aiit_lcd->cs, (const uint32_t *)&data, aiit_lcd->lcd_info.width * aiit_lcd->lcd_info.height / 2);
}
static void DrvLcdRectUpdate(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height)
{
static uint16 * rect_buffer = NONE;
if (!rect_buffer) {
rect_buffer = x_malloc(aiit_lcd->lcd_info.height * aiit_lcd->lcd_info.width * (aiit_lcd->lcd_info.bits_per_pixel / 8));
if (!rect_buffer) {
return;
}
}
if (x1 == 0 && y1 == 0 && width == aiit_lcd->lcd_info.width && height == aiit_lcd->lcd_info.height) {
DrvLcdSetArea(x1, y1, x1 + width - 1, y1 + height - 1);
DrvLcdDataWord((uint32 *)aiit_lcd->lcd_info.framebuffer, width * height / (aiit_lcd->lcd_info.bits_per_pixel / 8));
} else {
DrvLcdSetArea(x1, y1, x1 + width - 1, y1 + height - 1);
DrvLcdDataWord((uint32 *)rect_buffer, width * height / 2);
}
}
x_err_t DrvLcdInit(Lcd8080DeviceType dev)
{
x_err_t ret = EOK;
aiit_lcd = (Lcd8080DeviceType)dev;
uint8 data = 0;
if (!aiit_lcd)
{
return -ERROR;
}
DrvLcdHwInit(aiit_lcd);
/* reset LCD */
DrvLcdCmd(SOFTWARE_RESET);
MdelayKTask(100);
/* Enter normal status */
DrvLcdCmd(SLEEP_OFF);
MdelayKTask(100);
/* pixel format rgb565 */
DrvLcdCmd(PIXEL_FORMAT_SET);
data = 0x55;
DrvLcdDataByte(&data, 1);
/* set direction */
DrvLcdSetDirection(DIR_YX_RLUD);
aiit_lcd->lcd_info.framebuffer = x_malloc(aiit_lcd->lcd_info.height * aiit_lcd->lcd_info.width * (aiit_lcd->lcd_info.bits_per_pixel / 8));
CHECK(aiit_lcd->lcd_info.framebuffer);
/*display on*/
DrvLcdCmd(DISPALY_ON);
return ret;
}
static uint32 drv_lcd_control(void* drv, struct BusConfigureInfo *configure_info)
{
x_err_t ret = EOK;
struct LcdDriver *lcddrv = (struct LcdDriver *)drv;
struct DeviceRectInfo* rect_info;
NULL_PARAM_CHECK(drv);
switch (configure_info->configure_cmd)
{
case GRAPHIC_CTRL_RECT_UPDATE:
rect_info = (struct DeviceRectInfo*)configure_info->private_data;
if(!rect_info)
{
SYS_ERR("GRAPHIC_CTRL_RECT_UPDATE error args");
return -ERROR;
}
DrvLcdRectUpdate(rect_info->x, rect_info->y, rect_info->width, rect_info->height);
break;
case GRAPHIC_CTRL_POWERON:
/* Todo: power on */
ret = -ENONESYS;
break;
case GRAPHIC_CTRL_POWEROFF:
/* Todo: power off */
ret = -ENONESYS;
break;
case GRAPHIC_CTRL_GET_INFO:
*(struct DeviceLcdInfo *)configure_info->private_data = aiit_lcd->lcd_info;
break;
case GRAPHIC_CTRL_SET_MODE:
ret = -ENONESYS;
break;
case GRAPHIC_CTRL_GET_EXT:
ret = -ENONESYS;
break;
default:
SYS_ERR("drv_lcd_control cmd: %d", configure_info->configure_cmd);
break;
}
return ret;
}
void ClearHandwriting (void)
{
//clear the lcd
DrvLcdClear(WHITE);
LcdShowString(10, 10, 100, 24, 24, "RST ", RED, WHITE);
}
#ifdef CONFIG_TOUCH
void HandTest(unsigned short *x_pos, unsigned short *y_pos)
{
float x1,y1;
TpReadXy(x_pos,y_pos); //address
float a = 12.1875,b = 16.25;
x1 = 320 - (*x_pos)/a +10;
y1 = (* y_pos)/b;
if ((*x_pos> 500)&&(*y_pos<500)) {
ClearHandwriting();
} else {
DrvLcdSetPixel(x1, y1, RED);
DrvLcdSetPixel(x1+1, y1, RED);
DrvLcdSetPixel(x1-1, y1, RED);
DrvLcdSetPixel(x1, y1+1, RED);
DrvLcdSetPixel(x1, y1-1, RED);
DrvLcdSetPixel(x1+1, y1+1, RED);
DrvLcdSetPixel(x1-1, y1-1, RED);
DrvLcdSetPixel(x1+1, y1-1, RED);
DrvLcdSetPixel(x1-1, y1+1, RED);
}
}
#endif
static uint32 LcdWrite(void *dev, struct BusBlockWriteParam *write_param)
{
if (write_param == NONE) {
return -ERROR;
}
LcdWriteParam * show = (LcdWriteParam *)write_param->buffer;
// KPrintf("DEBUG TYPE %d X1:%d X2:%d Y1:%d Y2:%d\n",show->type,show->pixel_info.x_startpos, show->pixel_info.x_endpos,show->pixel_info.y_startpos, show->pixel_info.y_endpos);
if(0 == show->type) //output string
{
LcdShowString(show->string_info.x_pos,show->string_info.y_pos,show->string_info.width,show->string_info.height,show->string_info.font_size,show->string_info.addr,show->string_info.font_color,show->string_info.back_color);
return EOK;
}
else if(1 == show->type) //output dot
{
// DrvLcdSetPixel(show->pixel_info.x_pos, show->pixel_info.y_pos, show->pixel_info.pixel_color);
DrvLcdSetPixelDot(show->pixel_info.x_startpos,show->pixel_info.y_startpos, show->pixel_info.x_endpos, show->pixel_info.y_endpos,show->pixel_info.pixel_color);
return EOK;
}
else
{
return -ERROR;
}
}
uint32 DrvLcdClearDone(void * dev, struct BusConfigureInfo *configure_info)
{
uint16 color = 0;
color =(uint16)(configure_info->configure_cmd |0x0000ffff );
DrvLcdClear( color);
return 0;
}
const struct LcdDevDone lcd_dev_done =
{
.open = NONE,
.close = NONE,
.write = LcdWrite,
.read = NONE
};
static int BoardLcdBusInit(struct LcdBus * lcd_bus, struct LcdDriver * lcd_driver,const char *bus_name, const char *drv_name)
{
x_err_t ret = EOK;
/*Init the lcd bus */
ret = LcdBusInit( lcd_bus, bus_name);
if (EOK != ret) {
KPrintf("Board_lcd_init LcdBusInit error %d\n", ret);
return -ERROR;
}
/*Init the lcd driver*/
ret = LcdDriverInit( lcd_driver, drv_name);
if (EOK != ret) {
KPrintf("Board_LCD_init LcdDriverInit error %d\n", ret);
return -ERROR;
}
/*Attach the lcd driver to the lcd bus*/
ret = LcdDriverAttachToBus(drv_name, bus_name);
if (EOK != ret) {
KPrintf("Board_LCD_init LcdDriverAttachToBus error %d\n", ret);
return -ERROR;
}
return ret;
}
/*Attach the lcd device to the lcd bus*/
static int BoardLcdDevBend(struct LcdHardwareDevice *lcd_device, void *param, const char *bus_name, const char *dev_name)
{
x_err_t ret = EOK;
ret = LcdDeviceRegister(lcd_device, NONE, dev_name);
if (EOK != ret) {
KPrintf("Board_LCD_init LcdDeviceInit device %s error %d\n", dev_name, ret);
return -ERROR;
}
ret = LcdDeviceAttachToBus(dev_name, bus_name);
if (EOK != ret) {
KPrintf("Board_LCD_init LcdDeviceAttachToBus device %s error %d\n", dev_name, ret);
return -ERROR;
}
return ret;
}
int HwLcdInit(void)
{
x_err_t ret = EOK;
static struct LcdDriver lcd_driver;
memset(&lcd_driver, 0, sizeof(struct LcdDriver));
Lcd8080DeviceType lcd_dev = (Lcd8080DeviceType )x_malloc(sizeof( struct Lcd8080Device));
if (!lcd_dev)
{
return -ERROR;
}
memset(lcd_dev, 0, sizeof(struct Lcd8080Device));
// FpioaSetFunction(BSP_LCD_DC_PIN, FUNC_GPIOHS9); //DC order/data
// FpioaSetFunction(BSP_LCD_BL_PIN, FUNC_GPIOHS10); //BL
// FpioaSetFunction(BSP_LCD_CS_PIN, FUNC_SPI0_SS0); //chip select
// FpioaSetFunction(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK); //clk
lcd_dev->cs = SPI_CHIP_SELECT_0;
lcd_dev->dc_pin = FPIOA_LCD_DC;
lcd_dev->dma_channel = DMAC_CHANNEL0;
lcd_dev->spi_channel = SPI_DEVICE_0;
lcd_dev->lcd_info.bits_per_pixel = 16;
lcd_dev->lcd_info.pixel_format = PIXEL_FORMAT_BGR565;
sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18);
sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V18);
sysctl_set_spi0_dvp_data(1); //open the lcd interface with spi0
lcd_driver.configure = &drv_lcd_control;
ret = BoardLcdBusInit(&lcd_dev->lcd_bus, &lcd_driver, LCD_BUS_NAME, LCD_DRV_NAME); //init lcd bus
if (EOK != ret)
{
KPrintf("Board_lcd_Init error ret %u\n", ret);
x_free(lcd_dev);
return -ERROR;
}
static struct LcdHardwareDevice lcd_device;
memset(&lcd_device, 0, sizeof(struct LcdHardwareDevice));
lcd_device.dev_done = &(lcd_dev_done);
ret = BoardLcdDevBend(&lcd_device, NONE, LCD_BUS_NAME, LCD_DEVICE_NAME); //init lcd device
if (EOK != ret)
{
KPrintf("BoardLcdDevBend error ret %u\n", ret);
x_free(lcd_dev);
return -ERROR;
}
gpiohs_set_drive_mode(FPIOA_LCD_RST, GPIO_DM_OUTPUT);
gpiohs_set_pin(FPIOA_LCD_RST, GPIO_PV_LOW);
MdelayKTask(100);
gpiohs_set_pin(FPIOA_LCD_RST, GPIO_PV_HIGH);
MdelayKTask(100);
KPrintf("LCD driver inited ...\r\n");
DrvLcdInit(lcd_dev);
return ret;
}
//x1,y1:start
//x2,y2:end
void LcdDrawLine(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color)
{
uint16 t;
int xerr = 0, yerr = 0, delta_x, delta_y, distance;
int incx,incy,uRow,uCol;
delta_x = x2 - x1;
delta_y = y2 - y1;
uRow = x1;
uCol = y1;
if(delta_x>0)
incx = 1;
else if(delta_x==0)
incx = 0;
else {
incx = -1;
delta_x = -delta_x;
}
if(delta_y>0)
incy = 1;
else if(delta_y==0)
incy = 0;
else {
incy= -1;
delta_y = -delta_y;
}
if (delta_x>delta_y)
distance=delta_x;
else
distance=delta_y;
for(t = 0;t <= distance+1;t ++ ) {
DrvLcdSetPixel(uRow,uCol,color);
xerr += delta_x ;
yerr += delta_y ;
if (xerr>distance) {
xerr-=distance;
uRow+=incx;
}
if (yerr>distance) {
yerr-=distance;
uCol+=incy;
}
}
}
void LcdDrawRectangle(uint16 x1, uint16 y1, uint16 x2, uint16 y2,uint16 color)
{
LcdDrawLine(x1,y1,x2,y1,color);
LcdDrawLine(x1,y1,x1,y2,color);
LcdDrawLine(x1,y2,x2,y2,color);
LcdDrawLine(x2,y1,x2,y2,color);
}
void LcdDrawCircle(uint16 x0,uint16 y0,uint8 r,uint16 color)
{
int a,b;
int di;
a = 0;
b = r;
di = 3-(r<<1);
while(a <= b) {
DrvLcdSetPixel(x0+a,y0-b,color); //5
DrvLcdSetPixel(x0+b,y0-a,color); //0
DrvLcdSetPixel(x0+b,y0+a,color); //4
DrvLcdSetPixel(x0+a,y0+b,color); //6
DrvLcdSetPixel(x0-a,y0+b,color); //1
DrvLcdSetPixel(x0-b,y0+a,color);
DrvLcdSetPixel(x0-a,y0-b,color); //2
DrvLcdSetPixel(x0-b,y0-a,color); //7
a++;
//Bresenham
if(di<0)
di += 4*a+6;
else {
di += 10+4*(a-b);
b--;
}
}
}

View File

@ -0,0 +1,125 @@
config BSP_USING_SPI1
bool "Using spi1 "
default y
if BSP_USING_SPI1
config SPI_BUS_NAME_1
string "spi bus 1 name"
default "spi1"
config SPI_1_DRV_NAME
string "spi bus 1 driver name"
default "spi1_drv"
config BSP_SPI1_CLK_PIN
int "spi1 clk pin number"
default 6
config BSP_SPI1_D0_PIN
int "spi1 d0 pin number"
default 8
config BSP_SPI1_D1_PIN
int "spi1 d1 pin number"
default 7
menuconfig BSP_SPI1_USING_SS0
bool "SPI1 Enable SS0"
default y
if BSP_SPI1_USING_SS0
config SPI_1_DEVICE_NAME_0
string "spi bus 1 device 0 name"
default "spi1_dev0"
config BSP_SPI1_SS0_PIN
int "spi1 ss0 pin number"
default 9
menuconfig RESOURCES_SPI_LORA
bool "Using spi lora function"
default n
if RESOURCES_SPI_LORA
config SX12XX_DEVICE_NAME
string "SX1278 lora device name"
default "spi1_lora"
config SX12XX_DEVICE_RST_PIN
int
default 10
config SX12XX_DEVICE_DO0_PIN
int
default 10
config SX12XX_DEVICE_DO1_PIN
int
default 10
config SX12XX_DEVICE_DO2_PIN
int
default 10
config SX12XX_DEVICE_DO3_PIN
int
default 10
config SX12XX_DEVICE_DO4_PIN
int
default 10
config SX12XX_DEVICE_DO5_PIN
int
default 10
endif
endif
menuconfig BSP_SPI1_USING_SS1
bool "SPI1 Enable SS1"
default y
if BSP_SPI1_USING_SS1
config SPI_1_DEVICE_NAME_1
string "spi bus 1 device 1 name"
default "spi1_dev1"
config BSP_SPI1_SS1_PIN
int "spi1 ss1 pin number"
default 33
endif
menuconfig BSP_SPI1_USING_SS2
bool "SPI1 Enable SS2"
default n
if BSP_SPI1_USING_SS2
config SPI_1_DEVICE_NAME_2
string "spi bus 1 device 2 name"
default "spi1_dev2"
config BSP_SPI1_SS2_PIN
int "spi1 ss2 pin number"
default 26
endif
menuconfig BSP_SPI1_USING_SS3
bool "SPI1 Enable SS3"
default n
if BSP_SPI1_USING_SS3
config SPI_1_DEVICE_NAME_3
string "spi bus 1 device 3 name"
default "spi1_dev3"
config BSP_SPI1_SS3_PIN
int "spi1 ss3 pin number"
default 27
endif
endif
config BSP_USING_TP
bool "Using LCD touch "
default n
if BSP_USING_TP
config BSP_TP_SCK_PIN
int "TP SCK pin number"
default 42
config BSP_TP_NCS_PIN
int "TP NCS pin number"
default 43
config BSP_TP_MISO_PIN
int "TP MISO pin number"
default 44
config BSP_TP_IRQ_PIN
int "TP IRQ pin number"
default 45
config BSP_TP_MOSI_PIN
int "TP MOSI pin number"
default 46
endif

View File

@ -0,0 +1,9 @@
SRC_FILES := connect_spi.c hardware_spi.c
ifeq ($(CONFIG_RESOURCES_SPI_LORA),y)
SRC_DIR += third_party_spi_lora
SRC_FILES += connect_lora_spi.c
endif
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,475 @@
/*
* Copyright (c) 2020 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-18 ZYH first version
*/
/**
* @file connect_spi.c
* @brief support aiit-riscv64-board spi function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: connect_spi.c
Description: support aiit-riscv64-board spi configure and spi bus register function
Others: take RT-Thread v4.0.2/bsp/k210/driver/drv_spi.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. support aiit-riscv64-board spi configure, write and read
2. support aiit-riscv64-board spi bus device and driver register
*************************************************/
#include <connect_spi.h>
#include <dmac.h>
#include <drv_io_config.h>
#include <gpiohs.h>
#include <hardware_spi.h>
#include <string.h>
#include <sysctl.h>
#include <utils.h>
#ifdef BSP_SPI1_USING_SS0
#define SPI_DEVICE_SLAVE_ID_0 0
#endif
#ifdef BSP_SPI1_USING_SS1
#define SPI_DEVICE_SLAVE_ID_1 1
#endif
#ifdef BSP_SPI1_USING_SS2
#define SPI_DEVICE_SLAVE_ID_2 2
#endif
#ifdef BSP_SPI1_USING_SS3
#define SPI_DEVICE_SLAVE_ID_3 3
#endif
static volatile spi_t *const spi_instance[4] =
{
(volatile spi_t *)SPI0_BASE_ADDR,
(volatile spi_t *)SPI1_BASE_ADDR,
(volatile spi_t *)SPI_SLAVE_BASE_ADDR,
(volatile spi_t *)SPI3_BASE_ADDR
};
void __spi_set_tmod(uint8_t spi_num, uint32_t tmod)
{
CHECK(spi_num < SPI_DEVICE_MAX);
volatile spi_t *spi_handle = spi[spi_num];
uint8_t tmod_offset = 0;
switch(spi_num)
{
case 0:
case 1:
case 2:
tmod_offset = 8;
break;
case 3:
default:
tmod_offset = 10;
break;
}
set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset);
}
/*Init the spi sdk intetface */
static uint32 SpiSdkInit(struct SpiDriver *spi_drv)
{
NULL_PARAM_CHECK(spi_drv);
uint8 cs_gpio_pin, cs_select_id;
uint32 max_frequency;
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data);
cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
cs_select_id = dev_param->spi_slave_param->spi_cs_select_id;
gpiohs_set_drive_mode(cs_select_id, GPIO_DM_OUTPUT);//Set the cs pin as output
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);//set the cs gpio high
spi_init(dev_param->spi_dma_param->spi_master_id,
dev_param->spi_master_param->spi_work_mode & SPI_MODE_3,
dev_param->spi_master_param->spi_frame_format,
dev_param->spi_master_param->spi_data_bit_width,
dev_param->spi_master_param->spi_data_endian);
max_frequency = (dev_param->spi_master_param->spi_maxfrequency < SPI_MAX_CLOCK) ? dev_param->spi_master_param->spi_maxfrequency : SPI_MAX_CLOCK;
uint32 real_freq = spi_set_clk_rate(dev_param->spi_dma_param->spi_master_id, max_frequency);
return EOK;
}
static uint32 SpiSdkCfg(struct SpiDriver *spi_drv, struct SpiMasterParam *spi_param)
{
NULL_PARAM_CHECK(spi_drv);
NULL_PARAM_CHECK(spi_param);
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data);
dev_param->spi_master_param = spi_param;
dev_param->spi_master_param->spi_work_mode = dev_param->spi_master_param->spi_work_mode & SPI_MODE_MASK;
dev_param->spi_master_param->spi_frame_format = SPI_FF_STANDARD;
return EOK;
}
/*Configure the spi device param, make sure struct (configure_info->private_data) = (SpiMasterParam)*/
static uint32 SpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
struct SpiDriver *spi_drv = (struct SpiDriver *)drv;
struct SpiMasterParam *spi_param;
switch (configure_info->configure_cmd)
{
case OPE_INT:
ret = SpiSdkInit(spi_drv);
break;
case OPE_CFG:
spi_param = (struct SpiMasterParam *)configure_info->private_data;
ret = SpiSdkCfg(spi_drv, spi_param);
break;
default:
break;
}
return ret;
}
static uint32 SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
{
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
uint8 device_id = dev_param->spi_slave_param->spi_slave_id;
uint8 device_master_id = dev_param->spi_dma_param->spi_master_id;
uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
while (NONE != spi_datacfg)
{
uint32_t * tx_buff = NONE;
int i;
x_ubase dummy = 0xFFFFFFFFU;
__spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV);
if (spi_datacfg->spi_chip_select) {
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW);
}
if (spi_datacfg->length) {
spi_instance[device_master_id]->dmacr = 0x3;
spi_instance[device_master_id]->ssienr = 0x01;
sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2);
sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id* 2);
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
if (!spi_datacfg->tx_buff) {
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
} else {
tx_buff = x_malloc(spi_datacfg->length * 4);
if (!tx_buff) {
goto transfer_done;
}
for (i = 0; i < spi_datacfg->length; i++) {
tx_buff[i] = ((uint8_t *)spi_datacfg->tx_buff)[i];
}
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, tx_buff, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
}
spi_instance[device_master_id]->ser = 1U << dev_param->spi_slave_param->spi_cs_select_id;
dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel);
dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel);
spi_instance[device_master_id]->ser = 0x00;
spi_instance[device_master_id]->ssienr = 0x00;
transfer_done:
if (tx_buff) {
x_free(tx_buff);
}
}
if (spi_datacfg->spi_cs_release) {
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);
}
spi_datacfg = spi_datacfg->next;
}
return EOK;
}
static uint32 SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
{
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_dev->haldev.private_data);
uint32 spi_read_length = 0;;
uint8 device_id = dev_param->spi_slave_param->spi_slave_id;
uint8 device_master_id = dev_param->spi_dma_param->spi_master_id;
uint8 cs_gpio_pin = dev_param->spi_slave_param->spi_cs_gpio_pin;
while (NONE != spi_datacfg)
{
uint32_t * rx_buff = NONE;
int i;
x_ubase dummy = 0xFFFFFFFFU;
__spi_set_tmod(device_master_id, SPI_TMOD_TRANS_RECV);
if (spi_datacfg->spi_chip_select) {
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_LOW);
}
if (spi_datacfg->length) {
spi_instance[device_master_id]->dmacr = 0x3;
spi_instance[device_master_id]->ssienr = 0x01;
sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_txchannel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + device_master_id * 2);
sysctl_dma_select(dev_param->spi_dma_param->spi_dmac_rxchannel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + device_master_id* 2);
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_txchannel, &dummy, (void *)(&spi_instance[device_master_id]->dr[0]), DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
if (!spi_datacfg->rx_buff) {
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), &dummy, DMAC_ADDR_NOCHANGE, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
} else {
rx_buff = x_calloc(spi_datacfg->length * 4, 1);
if(!rx_buff)
{
goto transfer_done;
}
dmac_set_single_mode(dev_param->spi_dma_param->spi_dmac_rxchannel, (void *)(&spi_instance[device_master_id]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, spi_datacfg->length);
}
spi_instance[device_master_id]->ser = 1U << dev_param->spi_slave_param->spi_cs_select_id;
dmac_wait_done(dev_param->spi_dma_param->spi_dmac_txchannel);
dmac_wait_done(dev_param->spi_dma_param->spi_dmac_rxchannel);
spi_instance[device_master_id]->ser = 0x00;
spi_instance[device_master_id]->ssienr = 0x00;
if (spi_datacfg->rx_buff) {
for (i = 0; i < spi_datacfg->length; i++) {
((uint8_t *)spi_datacfg->rx_buff)[i] = (uint8_t)rx_buff[i];
}
}
transfer_done:
if (rx_buff) {
x_free(rx_buff);
}
}
if (spi_datacfg->spi_cs_release) {
gpiohs_set_pin(cs_gpio_pin, GPIO_PV_HIGH);
}
spi_read_length += spi_datacfg->length;
spi_datacfg = spi_datacfg->next;
}
return spi_read_length;
}
/*manage the spi device operations*/
static const struct SpiDevDone spi_dev_done =
{
.dev_open = NONE,
.dev_close = NONE,
.dev_write = SpiWriteData,
.dev_read = SpiReadData,
};
static int BoardSpiBusInit(struct SpiBus *spi_bus, struct SpiDriver *spi_driver)
{
x_err_t ret = EOK;
/*Init the spi bus */
ret = SpiBusInit(spi_bus, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiBusInit error %d\n", ret);
return ERROR;
}
/*Init the spi driver*/
ret = SpiDriverInit(spi_driver, SPI_1_DRV_NAME);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the spi driver to the spi bus*/
ret = SpiDriverAttachToBus(SPI_1_DRV_NAME, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the spi device to the spi bus*/
static int BoardSpiDevBend(struct SpiDmaParam *spi_initparam)
{
x_err_t ret = EOK;
#ifdef BSP_SPI1_USING_SS0
static struct SpiHardwareDevice spi_device0;
memset(&spi_device0, 0, sizeof(struct SpiHardwareDevice));
static struct SpiSlaveParam spi_slaveparam0;
memset(&spi_slaveparam0, 0, sizeof(struct SpiSlaveParam));
spi_slaveparam0.spi_slave_id = SPI_DEVICE_SLAVE_ID_0;
spi_slaveparam0.spi_cs_gpio_pin = SPI1_CS0_PIN;
spi_slaveparam0.spi_cs_select_id = SPI_CHIP_SELECT_0;
spi_device0.spi_param.spi_dma_param = spi_initparam;
spi_device0.spi_param.spi_slave_param = &spi_slaveparam0;
spi_device0.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi_device0, (void *)(&spi_device0.spi_param), SPI_1_DEVICE_NAME_0);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_0, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_0, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_0, ret);
return ERROR;
}
#endif
#ifdef BSP_SPI1_USING_SS1
static struct SpiHardwareDevice spi_device1;
memset(&spi_device1, 0, sizeof(struct SpiHardwareDevice));
static struct SpiSlaveParam spi_slaveparam1;
memset(&spi_slaveparam1, 0, sizeof(struct SpiSlaveParam));
spi_slaveparam1.spi_slave_id = SPI_DEVICE_SLAVE_ID_1;
spi_slaveparam1.spi_cs_gpio_pin = SPI1_CS1_PIN;
spi_slaveparam1.spi_cs_select_id = SPI_CHIP_SELECT_1;
spi_device1.spi_param.spi_dma_param = spi_initparam;
spi_device1.spi_param.spi_slave_param = &spi_slaveparam1;
spi_device1.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi_device1, (void *)(&spi_device1.spi_param), SPI_1_DEVICE_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_1, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_1, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_1, ret);
return ERROR;
}
#endif
#ifdef BSP_SPI1_USING_SS2
static struct SpiHardwareDevice spi_device2;
memset(&spi_device2, 0, sizeof(struct SpiHardwareDevice));
spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_2] = SPI_DEVICE_SLAVE_ID_2;
spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_2] = SPI1_CS2_PIN;
spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_2] = SPI_CHIP_SELECT_2;
spi_device2.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi_device2, (void *)(&spi_device2.spi_param), SPI_1_DEVICE_NAME_2);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_2, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_2, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_2, ret);
return ERROR;
}
#endif
#ifdef BSP_SPI1_USING_SS3
static struct SpiHardwareDevice spi_device3;
memset(&spi_device3, 0, sizeof(struct SpiHardwareDevice));
spi_initparam->spi_slave_id[SPI_DEVICE_SLAVE_ID_3] = SPI_DEVICE_SLAVE_ID_3;
spi_initparam->spi_cs_gpio_pin[SPI_DEVICE_SLAVE_ID_3] = SPI1_CS3_PIN;
spi_initparam->spi_cs_select_id[SPI_DEVICE_SLAVE_ID_3] = SPI_CHIP_SELECT_3;
spi_device3.spi_dev_done = &(spi_dev_done);
ret = SpiDeviceRegister(&spi_device3, (void *)(&spi_device3.spi_param), SPI_1_DEVICE_NAME_3);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceInit device %s error %d\n", SPI_1_DEVICE_NAME_3, ret);
return ERROR;
}
ret = SpiDeviceAttachToBus(SPI_1_DEVICE_NAME_3, SPI_BUS_NAME_1);
if (EOK != ret) {
KPrintf("Board_Spi_init SpiDeviceAttachToBus device %s error %d\n", SPI_1_DEVICE_NAME_3, ret);
return ERROR;
}
#endif
return ret;
}
/*RISC-V 64 BOARD SPI INIT*/
int HwSpiInit(void)
{
x_err_t ret = EOK;
static struct SpiDmaParam spi_initparam;
memset(&spi_initparam, 0, sizeof(struct SpiDmaParam));
#ifdef BSP_USING_SPI1
static struct SpiBus spi_bus;
memset(&spi_bus, 0, sizeof(struct SpiBus));
static struct SpiDriver spi_driver;
memset(&spi_driver, 0, sizeof(struct SpiDriver));
spi_initparam.spi_master_id = SPI_DEVICE_1;
spi_initparam.spi_dmac_txchannel = DMAC_CHANNEL1;
spi_initparam.spi_dmac_rxchannel = DMAC_CHANNEL2;
spi_driver.configure = &(SpiDrvConfigure);
ret = BoardSpiBusInit(&spi_bus, &spi_driver);
if (EOK != ret) {
KPrintf("Board_Spi_Init error ret %u\n", ret);
return ERROR;
}
ret = BoardSpiDevBend(&spi_initparam);
if (EOK != ret) {
KPrintf("Board_Spi_Init error ret %u\n", ret);
return ERROR;
}
#endif
return ret;
}

File diff suppressed because it is too large Load Diff