Ubiquitous/RT-Thread_Fusion_XiUOS:change name from RT_Thread to RT-Thread_Fusion_XiUOS

This commit is contained in:
chunyexixiaoyu
2022-03-30 18:18:18 +08:00
parent 658feff666
commit 5a0ffaf193
624 changed files with 13 additions and 13 deletions
@@ -0,0 +1,284 @@
menu "Board Drivers Config"
config BSP_USING_UART_HS
bool "Enable High Speed UART"
default y
menu "General Purpose UARTs"
menuconfig BSP_USING_UART1
bool "Enable UART1"
default n
if BSP_USING_UART1
config BSP_UART1_TXD_PIN
int "uart1 TXD pin number"
default 20
config BSP_UART1_RXD_PIN
int "uart1 RXD pin number"
default 21
config BSP_UART1_RTS_PIN
int "uart1 RTS pin number (-1 for not used)"
default -1
config BSP_UART1_CTS_PIN
int "uart1 CTS pin number (-1 for not used)"
default -1
endif
menuconfig BSP_USING_UART2
bool "Enable UART2"
default n
if BSP_USING_UART2
config BSP_UART2_TXD_PIN
int "uart2 TXD pin number"
default 28
config BSP_UART2_RXD_PIN
int "uart2 RXD pin number"
default 27
config BSP_UART2_RTS_PIN
int "uart2 RTS pin number (-1 for not used)"
default -1
config BSP_UART2_CTS_PIN
int "uart2 CTS pin number (-1 for not used)"
default -1
endif
menuconfig BSP_USING_UART3
bool "Enable UART3"
default n
if BSP_USING_UART3
config BSP_UART3_TXD_PIN
int "uart3 TXD pin number"
default 22
config BSP_UART3_RXD_PIN
int "uart3 RXD pin number"
default 23
config BSP_UART3_RTS_PIN
int "uart3 RTS pin number (-1 for not used)"
default -1
config BSP_UART3_CTS_PIN
int "uart3 CTS pin number (-1 for not used)"
default -1
endif
endmenu
config BSP_USING_I2C1
bool "Enable I2C1 (GPIO0/1)"
select RT_USING_I2C
default n
menuconfig BSP_USING_SPI1
bool "Enable SPI1"
select RT_USING_SPI
default n
if BSP_USING_SPI1
config BSP_USING_SPI1_AS_QSPI
bool
default n
config BSP_SPI1_CLK_PIN
int "spi1 clk pin number"
default 27
config BSP_SPI1_D0_PIN
int "spi1 d0 pin number"
default 28
config BSP_SPI1_D1_PIN
int "spi1 d1 pin number"
default 26
if BSP_USING_SPI1_AS_QSPI
config BSP_SPI1_D2_PIN
int "spi1 d2 pin number"
default 32
config BSP_SPI1_D3_PIN
int "spi1 d3 pin number"
default 33
endif
menuconfig BSP_SPI1_USING_SS0
bool "SPI1 Enable SS0(spi10 dev)"
default n
if BSP_SPI1_USING_SS0
config BSP_SPI1_SS0_PIN
int "spi1 ss0 pin number"
default 29
endif
menuconfig BSP_SPI1_USING_SS1
bool "SPI1 Enable SS1(spi11 dev)"
default n
if BSP_SPI1_USING_SS1
config BSP_SPI1_SS1_PIN
int "spi1 ss1 pin number"
default 8
endif
menuconfig BSP_SPI1_USING_SS2
bool "SPI1 Enable SS2(spi12 dev)"
default n
if BSP_SPI1_USING_SS2
config BSP_SPI1_SS2_PIN
int "spi1 ss2 pin number"
default 26
endif
menuconfig BSP_SPI1_USING_SS3
bool "SPI1 Enable SS3(spi13 dev)"
default n
if BSP_SPI1_USING_SS3
config BSP_SPI1_SS3_PIN
int "spi1 ss3 pin number"
default 27
endif
endif
menuconfig BSP_USING_LCD
bool "Enable LCD on SPI0"
default n
if BSP_USING_LCD
config BSP_LCD_CS_PIN
int "CS pin number of 8080 interface"
default 36
config BSP_LCD_WR_PIN
int "WR pin number of 8080 interface"
default 39
config BSP_LCD_DC_PIN
int "DC pin number of 8080 interface"
default 38
config BSP_LCD_RST_PIN
int "RESET pin number of 8080 interface (-1 for not used)"
default 37
config BSP_LCD_BACKLIGHT_PIN
int "Backlight control pin number (-1 for not used)"
default -1
choice
prompt "backlight active polarity"
default BSP_LCD_BACKLIGHT_ACTIVE_LOW
config BSP_LCD_BACKLIGHT_ACTIVE_LOW
bool "lcd backlight on low level"
config BSP_LCD_BACKLIGHT_ACTIVE_HIGH
bool "lcd_backlight on high level"
endchoice
config BSP_LCD_CLK_FREQ
int "Lcd max clk frequency"
default 15000000
choice
prompt "lcd scan direction"
default BSP_BOARD_KD233
config BSP_BOARD_KD233
bool "board_kd233 lcd scan: DIR_YX_RLUD"
config BSP_BOARD_K210_OPENMV_TEST
bool "board_k210_openmv lcd scan: DIR_YX_LRUD"
config BSP_BOARD_USER
bool "board_user: user defined."
endchoice
config BSP_LCD_X_MAX
int "LCD Height"
default 240
config BSP_LCD_Y_MAX
int "LCD Width"
default 320
endif
menuconfig BSP_USING_SDCARD
bool "Enable SDCARD (spi1(ss0))"
select BSP_USING_SPI1
select BSP_SPI1_USING_SS0
select RT_USING_DFS
select RT_USING_DFS_ELMFAT
select RT_USING_SPI_MSD
default n
menuconfig BSP_USING_DVP
bool "Enable DVP(camera)"
default n
if BSP_USING_DVP
comment "The default pin assignment is based on the Maix Duino K210 development board"
config BSP_DVP_SCCB_SDA_PIN
int "SCCB SDA pin number for camera"
default 40
config BSP_DVP_SCCB_SCLK_PIN
int "SCCB SCLK pin number for camera"
default 41
config BSP_DVP_CMOS_RST_PIN
int "CMOS RST pin number for camera"
default 42
config BSP_DVP_CMOS_VSYNC_PIN
int "CMOS VSYNC pin number for camera"
default 43
config BSP_DVP_CMOS_PWDN_PIN
int "CMOS PWDN pin number for camera"
default 44
config BSP_DVP_CMOS_XCLK_PIN
int "CMOS XCLK pin number for camera"
default 46
config BSP_DVP_CMOS_PCLK_PIN
int "CMOS PCLK pin number for camera"
default 47
config BSP_DVP_CMOS_HREF_PIN
int "CMOS HREF pin number for camera"
default 45
endif
if PKG_USING_RW007
config RW007_SPIDEV_NAME
string "the SPIDEV rw007 driver on"
default "spi11"
config RW007_INT_BUSY_PIN
int "rw007 int pin for rw007"
default 7
config RW007_RST_PIN
int "rw007 rst pin for rw007"
default 6
endif
endmenu
menuconfig BSP_USING_CH438
bool "Enable CH438"
default y
if BSP_USING_CH438
config BSP_CH438_ALE_PIN
int "ale pin number for ch438"
default 23
config BSP_CH438_NWR_PIN
int "nwr pin number for ch438"
default 24
config BSP_CH438_NRD_PIN
int "nrd pin number for ch438"
default 25
config BSP_CH438_D0_PIN
int "d0 pin number for ch438"
default 27
config BSP_CH438_D1_PIN
int "d1 pin number for ch438"
default 28
config BSP_CH438_D2_PIN
int "d2 pin number for ch438"
default 29
config BSP_CH438_D3_PIN
int "d3 pin number for ch438"
default 30
config BSP_CH438_D4_PIN
int "d4 pin number for ch438"
default 31
config BSP_CH438_D5_PIN
int "d5 pin number for ch438"
default 32
config BSP_CH438_D6_PIN
int "d6 pin number for ch438"
default 33
config BSP_CH438_D7_PIN
int "d7 pin number for ch438"
default 34
config BSP_CH438_INT_PIN
int "int pin number for ch438"
default 35
endif
@@ -0,0 +1,51 @@
import os
import rtconfig
from building import *
cwd = GetCurrentDir()
drv_path = cwd+"/../../../rt-thread/bsp/k210/driver/"
src = [
'board.c',
'heap.c',
drv_path + 'drv_uart.c',
'drv_interrupt.c',
'drv_io_config.c',
'dmalock.c'
]
CPPPATH = [cwd,drv_path]
if GetDepend('RT_USING_PIN'):
src += ['drv_gpio.c']
if GetDepend('RT_USING_HWTIMER'):
src += [drv_path + 'drv_hw_timer.c']
if GetDepend('RT_USING_I2C'):
src += [drv_path + 'drv_i2c.c']
if GetDepend('RT_USING_SPI'):
src += ['drv_spi.c']
if GetDepend('RT_USING_PWM'):
src += [drv_path + 'drv_pwm.c']
if GetDepend('RT_USING_WDT'):
src += [drv_path + 'drv_wdt.c']
# if GetDepend('BSP_USING_SDCARD'):
# src += ['sdcard_port.c']
# if GetDepend('BSP_USING_DVP'):
# src += ['drv_dvp.c']
# if GetDepend('BSP_USING_LCD'):
# src += ['drv_lcd.c']
# src += ['drv_mpylcd.c']
if GetDepend('BSP_USING_CH438'):
src += ['ch438.c']
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
@@ -0,0 +1,144 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rthw.h>
#include <rtthread.h>
#include "board.h"
#include "tick.h"
#include "drv_uart.h"
#include "encoding.h"
#include "fpioa.h"
#include "dmac.h"
#include "dmalock.h"
void init_bss(void)
{
unsigned int *dst;
dst = &__bss_start;
while (dst < &__bss_end)
{
*dst++ = 0;
}
}
void primary_cpu_entry(void)
{
extern void entry(void);
/* disable global interrupt */
init_bss();
rt_hw_interrupt_disable();
entry();
}
#include <clint.h>
#include <sysctl.h>
int freq(void)
{
rt_uint64_t value = 0;
value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL0);
rt_kprintf("PLL0: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL1);
rt_kprintf("PLL1: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL2);
rt_kprintf("PLL2: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_CPU);
rt_kprintf("CPU : %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB0);
rt_kprintf("APB0: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB1);
rt_kprintf("APB1: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_APB2);
rt_kprintf("APB2: %d\n", value);
value = sysctl_clock_get_freq(SYSCTL_CLOCK_HCLK);
rt_kprintf("HCLK: %d\n", value);
value = clint_get_time();
rt_kprintf("mtime: %d\n", value);
return 0;
}
MSH_CMD_EXPORT(freq, show freq info);
#ifdef RT_USING_SMP
extern int rt_hw_clint_ipi_enable(void);
#endif
extern int io_config_init(void);
void rt_hw_board_init(void)
{
sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL);
sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL);
sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL);
sysctl_clock_set_threshold(SYSCTL_THRESHOLD_APB1, 2);
/* Init FPIOA */
fpioa_init();
io_config_init();
/* Dmac init */
dmac_init();
dmalock_init();
/* initalize interrupt */
rt_hw_interrupt_init();
/* initialize hardware interrupt */
rt_hw_uart_init();
rt_hw_tick_init();
#ifdef RT_USING_SMP
rt_hw_clint_ipi_enable();
#endif
#ifdef RT_USING_CONSOLE
/* set console device */
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif /* RT_USING_CONSOLE */
#ifdef RT_USING_HEAP
rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t) RT_HW_HEAP_BEGIN, (rt_ubase_t) RT_HW_HEAP_END);
/* initialize memory system */
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
#endif
#ifdef RT_USING_COMPONENTS_INIT
rt_components_board_init();
#endif
}
void rt_hw_cpu_reset(void)
{
sysctl->soft_reset.soft_reset = 1;
while(1);
}
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
/**
* This function will delay for some us.
*
* @param us the delay time of us
*/
void rt_hw_us_delay(rt_uint32_t usec)
{
rt_uint32_t cycle = read_cycle();
rt_uint32_t nop_all = usec * sysctl_clock_get_freq(SYSCTL_CLOCK_CPU) / 1000000UL;
while (1)
{
if(read_cycle() - cycle >= nop_all)
break;
}
}
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2017-5-30 Bernard the first version
*/
#ifndef BOARD_H__
#define BOARD_H__
#include "fpioa.h"
#include "platform.h"
#include <rtconfig.h>
extern unsigned int __bss_start;
extern unsigned int __bss_end;
#define RT_HW_HEAP_BEGIN (void*)&__bss_end
#define RT_HW_HEAP_END (void*)(0x80000000 + 6 * 1024 * 1024)
void rt_hw_board_init(void);
#endif
@@ -0,0 +1,484 @@
#include <rtthread.h>
#include <rtdevice.h>
#include <drv_io_config.h>
#include <gpiohs.h>
#include "board.h"
#include "ch438.h"
#include "sleep.h"
#include <math.h>
static rt_uint8_t offsetadd[] = {0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38,}; /* Offset address of serial port number */
struct rt_serial_device *extuart_serial_parm[8];
void CH438_INIT(void)
{
CH438_set_output();
gpiohs_set_drive_mode(FPIOA_CH438_NWR, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_NRD, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_ALE, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_INT, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_drive_mode(FPIOA_485_DIR, GPIO_DM_OUTPUT);
gpiohs_set_pin(FPIOA_CH438_NWR, GPIO_PV_HIGH);
gpiohs_set_pin(FPIOA_CH438_NRD, GPIO_PV_HIGH);
gpiohs_set_pin(FPIOA_CH438_ALE, GPIO_PV_HIGH);
}
void CH438_PORT_INIT( rt_uint8_t ext_uart_no,rt_uint32_t BaudRate )
{
rt_uint32_t div;
rt_uint8_t DLL,DLM,dlab;
rt_uint8_t REG_LCR_ADDR;
rt_uint8_t REG_DLL_ADDR;
rt_uint8_t REG_DLM_ADDR;
rt_uint8_t REG_IER_ADDR;
rt_uint8_t REG_MCR_ADDR;
rt_uint8_t REG_FCR_ADDR;
rt_uint8_t REG_RBR_ADDR;
rt_uint8_t REG_THR_ADDR;
rt_uint8_t REG_IIR_ADDR;
REG_LCR_ADDR = offsetadd[ext_uart_no] | REG_LCR0_ADDR;
REG_DLL_ADDR = offsetadd[ext_uart_no] | REG_DLL0_ADDR;
REG_DLM_ADDR = offsetadd[ext_uart_no] | REG_DLM0_ADDR;
REG_IER_ADDR = offsetadd[ext_uart_no] | REG_IER0_ADDR;
REG_MCR_ADDR = offsetadd[ext_uart_no] | REG_MCR0_ADDR;
REG_FCR_ADDR = offsetadd[ext_uart_no] | REG_FCR0_ADDR;
REG_RBR_ADDR = offsetadd[ext_uart_no] | REG_RBR0_ADDR;
REG_THR_ADDR = offsetadd[ext_uart_no] | REG_THR0_ADDR;
REG_IIR_ADDR = offsetadd[ext_uart_no] | REG_IIR0_ADDR;
WriteCH438Data( REG_IER_ADDR, BIT_IER_RESET ); /* Reset the serial port */
rt_thread_delay(50);
dlab = ReadCH438Data(REG_IER_ADDR);
dlab &= 0xDF;
WriteCH438Data(REG_IER_ADDR, dlab);
dlab = ReadCH438Data(REG_LCR_ADDR);
dlab |= 0x80;
WriteCH438Data(REG_LCR_ADDR, dlab);
div = ( Fpclk >> 4 ) / BaudRate;
DLM = div >> 8;
DLL = div & 0xff;
WriteCH438Data( REG_DLL_ADDR, DLL ); /* Set baud rate */
WriteCH438Data( REG_DLM_ADDR, DLM );
WriteCH438Data( REG_FCR_ADDR, BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN ); /* Set FIFO mode */
WriteCH438Data( REG_LCR_ADDR, BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0 );
WriteCH438Data( REG_IER_ADDR, /*BIT_IER_IEMODEM | BIT_IER_IETHRE | BIT_IER_IELINES | */BIT_IER_IERECV );
WriteCH438Data( REG_MCR_ADDR, BIT_MCR_OUT2 );
WriteCH438Data(REG_FCR_ADDR,ReadCH438Data(REG_FCR_ADDR)| BIT_FCR_RFIFORST | BIT_FCR_TFIFORST);
}
static void CH438_set_output(void)
{
gpiohs_set_drive_mode(FPIOA_CH438_D0, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_D1, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_D2, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_D3, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_D4, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_D5, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_D6, GPIO_DM_OUTPUT);
gpiohs_set_drive_mode(FPIOA_CH438_D7, GPIO_DM_OUTPUT);
}
static void CH438_set_input(void)
{
gpiohs_set_drive_mode(FPIOA_CH438_D0, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_drive_mode(FPIOA_CH438_D1, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_drive_mode(FPIOA_CH438_D2, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_drive_mode(FPIOA_CH438_D3, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_drive_mode(FPIOA_CH438_D4, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_drive_mode(FPIOA_CH438_D5, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_drive_mode(FPIOA_CH438_D6, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_drive_mode(FPIOA_CH438_D7, GPIO_DM_INPUT_PULL_UP);
}
void set_485_input(rt_uint8_t ch_no)
{
if(ch_no == 1)
gpiohs_set_pin(FPIOA_485_DIR, GPIO_PV_LOW);
}
void set_485_output(rt_uint8_t ch_no)
{
if(ch_no == 1)
gpiohs_set_pin(FPIOA_485_DIR, GPIO_PV_HIGH);
}
rt_uint8_t ReadCH438Data( rt_uint8_t addr )
{
rt_uint8_t dat = 0;
gpiohs_set_pin(FPIOA_CH438_NWR,GPIO_PV_HIGH);
gpiohs_set_pin(FPIOA_CH438_NRD,GPIO_PV_HIGH);
gpiohs_set_pin(FPIOA_CH438_ALE,GPIO_PV_HIGH);
CH438_set_output();
usleep(1);
if(addr &0x80) gpiohs_set_pin(FPIOA_CH438_D7,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D7,GPIO_PV_LOW);
if(addr &0x40) gpiohs_set_pin(FPIOA_CH438_D6,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D6,GPIO_PV_LOW);
if(addr &0x20) gpiohs_set_pin(FPIOA_CH438_D5,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D5,GPIO_PV_LOW);
if(addr &0x10) gpiohs_set_pin(FPIOA_CH438_D4,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D4,GPIO_PV_LOW);
if(addr &0x08) gpiohs_set_pin(FPIOA_CH438_D3,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D3,GPIO_PV_LOW);
if(addr &0x04) gpiohs_set_pin(FPIOA_CH438_D2,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D2,GPIO_PV_LOW);
if(addr &0x02) gpiohs_set_pin(FPIOA_CH438_D1,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D1,GPIO_PV_LOW);
if(addr &0x01) gpiohs_set_pin(FPIOA_CH438_D0,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D0,GPIO_PV_LOW);
usleep(1);
gpiohs_set_pin(FPIOA_CH438_ALE,GPIO_PV_LOW);
usleep(1);
CH438_set_input();
usleep(1);
gpiohs_set_pin(FPIOA_CH438_NRD,GPIO_PV_LOW);
usleep(1);
dat = 0;
if (gpiohs_get_pin(FPIOA_CH438_D7)) dat |= 0x80;
if (gpiohs_get_pin(FPIOA_CH438_D6)) dat |= 0x40;
if (gpiohs_get_pin(FPIOA_CH438_D5)) dat |= 0x20;
if (gpiohs_get_pin(FPIOA_CH438_D4)) dat |= 0x10;
if (gpiohs_get_pin(FPIOA_CH438_D3)) dat |= 0x08;
if (gpiohs_get_pin(FPIOA_CH438_D2)) dat |= 0x04;
if (gpiohs_get_pin(FPIOA_CH438_D1)) dat |= 0x02;
if (gpiohs_get_pin(FPIOA_CH438_D0)) dat |= 0x01;
gpiohs_set_pin(FPIOA_CH438_NRD,GPIO_PV_HIGH);
gpiohs_set_pin(FPIOA_CH438_ALE,GPIO_PV_HIGH);
usleep(1);
return dat;
}
static void WriteCH438Data( rt_uint8_t addr, rt_uint8_t dat)
{
gpiohs_set_pin(FPIOA_CH438_ALE,GPIO_PV_HIGH);
gpiohs_set_pin(FPIOA_CH438_NRD,GPIO_PV_HIGH);
gpiohs_set_pin(FPIOA_CH438_NWR,GPIO_PV_HIGH);
CH438_set_output();
usleep(1);
if(addr &0x80) gpiohs_set_pin(FPIOA_CH438_D7,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D7,GPIO_PV_LOW);
if(addr &0x40) gpiohs_set_pin(FPIOA_CH438_D6,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D6,GPIO_PV_LOW);
if(addr &0x20) gpiohs_set_pin(FPIOA_CH438_D5,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D5,GPIO_PV_LOW);
if(addr &0x10) gpiohs_set_pin(FPIOA_CH438_D4,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D4,GPIO_PV_LOW);
if(addr &0x08) gpiohs_set_pin(FPIOA_CH438_D3,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D3,GPIO_PV_LOW);
if(addr &0x04) gpiohs_set_pin(FPIOA_CH438_D2,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D2,GPIO_PV_LOW);
if(addr &0x02) gpiohs_set_pin(FPIOA_CH438_D1,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D1,GPIO_PV_LOW);
if(addr &0x01) gpiohs_set_pin(FPIOA_CH438_D0,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D0,GPIO_PV_LOW);
usleep(1);
gpiohs_set_pin(FPIOA_CH438_ALE,GPIO_PV_LOW);
usleep(1);
if(dat &0x80) gpiohs_set_pin(FPIOA_CH438_D7,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D7,GPIO_PV_LOW);
if(dat &0x40) gpiohs_set_pin(FPIOA_CH438_D6,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D6,GPIO_PV_LOW);
if(dat &0x20) gpiohs_set_pin(FPIOA_CH438_D5,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D5,GPIO_PV_LOW);
if(dat &0x10) gpiohs_set_pin(FPIOA_CH438_D4,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D4,GPIO_PV_LOW);
if(dat &0x08) gpiohs_set_pin(FPIOA_CH438_D3,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D3,GPIO_PV_LOW);
if(dat &0x04) gpiohs_set_pin(FPIOA_CH438_D2,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D2,GPIO_PV_LOW);
if(dat &0x02) gpiohs_set_pin(FPIOA_CH438_D1,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D1,GPIO_PV_LOW);
if(dat &0x01) gpiohs_set_pin(FPIOA_CH438_D0,GPIO_PV_HIGH); else gpiohs_set_pin(FPIOA_CH438_D0,GPIO_PV_LOW);
usleep(1);
gpiohs_set_pin(FPIOA_CH438_NWR,GPIO_PV_LOW);
usleep(1);
gpiohs_set_pin(FPIOA_CH438_NWR,GPIO_PV_HIGH);
gpiohs_set_pin(FPIOA_CH438_ALE,GPIO_PV_HIGH);
usleep(1);
CH438_set_input();
return;
}
static void WriteCH438Block( rt_uint8_t mAddr, rt_uint8_t mLen, rt_uint8_t *mBuf )
{
while ( mLen -- )
WriteCH438Data( mAddr, *mBuf++ );
}
static int Ch438Irq(void *parameter)
{
rt_uint8_t gInterruptStatus;
rt_uint8_t port = 0;
struct rt_serial_device *serial = (struct rt_serial_device *)parameter;
/* multi irq may happen*/
gInterruptStatus = ReadCH438Data(REG_SSR_ADDR);
port = log(gInterruptStatus & 0xFF)/log(2);
rt_hw_serial_isr(extuart_serial_parm[port], RT_SERIAL_EVENT_RX_IND);
}
static rt_err_t rt_extuart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
{
rt_uint32_t baud_rate = cfg->baud_rate;
rt_uint16_t port = cfg->reserved;
CH438_PORT_INIT(port, baud_rate);
return RT_EOK;
}
static rt_err_t extuart_control(struct rt_serial_device *serial, int cmd, void *arg)
{
rt_uint16_t ext_uart_no = serial->config.reserved;
static rt_uint16_t register_flag = 0;
switch (cmd)
{
case RT_DEVICE_CTRL_CLR_INT:
if(1 == register_flag)
{
gpiohs_irq_unregister(FPIOA_CH438_INT);
register_flag = 0;
}
break;
case RT_DEVICE_CTRL_SET_INT:
if(0 == register_flag)
{
gpiohs_set_drive_mode(FPIOA_CH438_INT, GPIO_DM_INPUT_PULL_UP);
gpiohs_set_pin_edge(FPIOA_CH438_INT,GPIO_PE_FALLING);
gpiohs_irq_register(FPIOA_CH438_INT, 1, Ch438Irq, (void*)serial);
register_flag = 1;
}
break;
}
return (RT_EOK);
}
static int drv_extuart_putc(struct rt_serial_device *serial, char c)
{
uint16_t ext_uart_no = serial->config.reserved;
rt_uint8_t REG_LSR_ADDR,REG_THR_ADDR;
REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR;
REG_THR_ADDR = offsetadd[ext_uart_no] | REG_THR0_ADDR;
if((ReadCH438Data( REG_LSR_ADDR ) & BIT_LSR_TEMT) != 0)
{
WriteCH438Block( REG_THR_ADDR, 1, &c );
return 1;
} else {
return 0;
}
}
static int drv_extuart_getc(struct rt_serial_device *serial)
{
rt_uint8_t dat = 0;
rt_uint8_t REG_LSR_ADDR,REG_RBR_ADDR;
uint16_t ext_uart_no = serial->config.reserved;///< get extern uart port
REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR;
REG_RBR_ADDR = offsetadd[ext_uart_no] | REG_RBR0_ADDR;
if((ReadCH438Data(REG_LSR_ADDR) & BIT_LSR_DATARDY) == 0x01)
{
dat = ReadCH438Data( REG_RBR_ADDR );
if(dat >= 0)
return dat;
} else {
return -1;
}
}
const struct rt_uart_ops extuart_ops =
{
rt_extuart_configure,
extuart_control,
drv_extuart_putc,
drv_extuart_getc,
RT_NULL
};
int rt_hw_ch438_init(void)
{
struct rt_serial_device *extserial;
struct device_uart *extuart;
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
rt_err_t ret;
{
static struct rt_serial_device extserial0;
extserial = &extserial0;
extserial->ops = &extuart_ops;
extserial->config = config;
extserial->config.baud_rate = 115200;
extserial->config.reserved = 0; ///< extern uart port
extuart_serial_parm[0] = &extserial0;
ret = rt_hw_serial_register(extserial,
"extuart_dev0",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
extuart);
if(ret < 0){
rt_kprintf("extuart_dev0 register failed.\n");
}
}
{
static struct rt_serial_device extserial1;
extserial = &extserial1;
extserial->ops = &extuart_ops;
extserial->config = config;
extserial->config.baud_rate = 9600;
extserial->config.reserved = 1; ///< extern uart port
extuart_serial_parm[1] = &extserial1;
ret = rt_hw_serial_register(extserial,
"extuart_dev1",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
extuart);
if(ret < 0){
rt_kprintf("extuart_dev1 register failed.\n");
}
}
{
static struct rt_serial_device extserial2;
extserial = &extserial2;
extserial->ops = &extuart_ops;
extserial->config = config;
extserial->config.baud_rate = 9600;
extserial->config.reserved = 2; ///< extern uart port
extuart_serial_parm[2] = &extserial2;
ret = rt_hw_serial_register(extserial,
"extuart_dev2",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
extuart);
if(ret < 0){
rt_kprintf("extuart_dev2 register failed.\n");
}
}
{
static struct rt_serial_device extserial3;
extserial = &extserial3;
extserial->ops = &extuart_ops;
extserial->config = config;
extserial->config.baud_rate = 9600;
extserial->config.reserved = 3; ///< extern uart port
ret = rt_hw_serial_register(extserial,
"extuart_dev3",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
extuart);
if(ret < 0){
rt_kprintf("extuart_dev3 register failed.\n");
}
extuart_serial_parm[3] = &extserial3;
}
{
static struct rt_serial_device extserial4;
extserial = &extserial4;
extserial->ops = &extuart_ops;
extserial->config = config;
extserial->config.baud_rate = 9600;
extserial->config.reserved = 4; ///< extern uart port
ret = rt_hw_serial_register(extserial,
"extuart_dev4",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
extuart);
if(ret < 0){
rt_kprintf("extuart_dev4 register failed.\n");
}
extuart_serial_parm[4] = &extserial4;
}
{
static struct rt_serial_device extserial5;
extserial = &extserial5;
extserial->ops = &extuart_ops;
extserial->config = config;
extserial->config.baud_rate = 115200;
extserial->config.reserved = 5; ///< extern uart port
ret = rt_hw_serial_register(extserial,
"extuart_dev5",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
extuart);
if(ret < 0){
rt_kprintf("extuart_dev5 register failed.\n");
}
extuart_serial_parm[5] = &extserial5;
}
{
static struct rt_serial_device extserial6;
extserial = &extserial6;
extserial->ops = &extuart_ops;
extserial->config = config;
extserial->config.baud_rate = 57600;
extserial->config.reserved = 6; ///< extern uart port
ret = rt_hw_serial_register(extserial,
"extuart_dev6",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
extuart);
if(ret < 0){
rt_kprintf("extuart_dev6 register failed.\n");
}
extuart_serial_parm[6] = &extserial6;
}
{
static struct rt_serial_device extserial7;
extserial = &extserial7;
extserial->ops = &extuart_ops;
extserial->config = config;
extserial->config.baud_rate = 9600;
extserial->config.reserved = 7; ///< extern uart port
ret = rt_hw_serial_register(extserial,
"extuart_dev7",
RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX,
extuart);
if(ret < 0){
rt_kprintf("extuart_dev7 register failed.\n");
}
extuart_serial_parm[7] = &extserial7;
}
CH438_INIT();
return 0;
}
INIT_DEVICE_EXPORT(rt_hw_ch438_init);
@@ -0,0 +1,251 @@
#ifndef __CH438_H_
#define __CH438_H_
#include "board.h"
#define BUFFSIZE 255
/******************************************************************************************/
/* CH438serial port0 register address */
#define REG_RBR0_ADDR 0x00 /* serial port0receive buffer register address */
#define REG_THR0_ADDR 0x00 /* serial port0send hold register address */
#define REG_IER0_ADDR 0x01 /* serial port0interrupt enable register address */
#define REG_IIR0_ADDR 0x02 /* serial port0interrupt identifies register address */
#define REG_FCR0_ADDR 0x02 /* serial port0FIFO controls register address */
#define REG_LCR0_ADDR 0x03 /* serial port0circuit control register address */
#define REG_MCR0_ADDR 0x04 /* serial port0MODEM controls register address */
#define REG_LSR0_ADDR 0x05 /* serial port0line status register address */
#define REG_MSR0_ADDR 0x06 /* serial port0address of MODEM status register */
#define REG_SCR0_ADDR 0x07 /* serial port0the user can define the register address */
#define REG_DLL0_ADDR 0x00 /* Baud rate divisor latch low 8-bit byte address */
#define REG_DLM0_ADDR 0x01 /* Baud rate divisor latch high 8-bit byte address */
/* CH438serial port1 register address */
#define REG_RBR1_ADDR 0x10 /* serial port1receive buffer register address */
#define REG_THR1_ADDR 0x10 /* serial port1send hold register address */
#define REG_IER1_ADDR 0x11 /* serial port1interrupt enable register address */
#define REG_IIR1_ADDR 0x12 /* serial port1interrupt identifies register address */
#define REG_FCR1_ADDR 0x12 /* serial port1FIFO controls register address */
#define REG_LCR1_ADDR 0x13 /* serial port1circuit control register address */
#define REG_MCR1_ADDR 0x14 /* serial port1MODEM controls register address */
#define REG_LSR1_ADDR 0x15 /* serial port1line status register address */
#define REG_MSR1_ADDR 0x16 /* serial port1address of MODEM status register */
#define REG_SCR1_ADDR 0x17 /* serial port1the user can define the register address */
#define REG_DLL1_ADDR 0x10 /* Baud rate divisor latch low 8-bit byte address */
#define REG_DLM1_ADDR 0x11 /* Baud rate divisor latch high 8-bit byte address */
/* CH438serial port2 register address */
#define REG_RBR2_ADDR 0x20 /* serial port2receive buffer register address */
#define REG_THR2_ADDR 0x20 /* serial port2send hold register address */
#define REG_IER2_ADDR 0x21 /* serial port2interrupt enable register address */
#define REG_IIR2_ADDR 0x22 /* serial port2interrupt identifies register address */
#define REG_FCR2_ADDR 0x22 /* serial port2FIFO controls register address */
#define REG_LCR2_ADDR 0x23 /* serial port2circuit control register address */
#define REG_MCR2_ADDR 0x24 /* serial port2MODEM controls register address */
#define REG_LSR2_ADDR 0x25 /* serial port2line status register address */
#define REG_MSR2_ADDR 0x26 /* serial port2address of MODEM status register */
#define REG_SCR2_ADDR 0x27 /* serial port2the user can define the register address */
#define REG_DLL2_ADDR 0x20 /* Baud rate divisor latch low 8-bit byte address */
#define REG_DLM2_ADDR 0x21 /* Baud rate divisor latch high 8-bit byte address */
/* CH438serial port3 register address */
#define REG_RBR3_ADDR 0x30 /* serial port3receive buffer register address */
#define REG_THR3_ADDR 0x30 /* serial port3send hold register address */
#define REG_IER3_ADDR 0x31 /* serial port3interrupt enable register address */
#define REG_IIR3_ADDR 0x32 /* serial port3interrupt identifies register address */
#define REG_FCR3_ADDR 0x32 /* serial port3FIFO controls register address */
#define REG_LCR3_ADDR 0x33 /* serial port3circuit control register address */
#define REG_MCR3_ADDR 0x34 /* serial port3MODEM controls register address */
#define REG_LSR3_ADDR 0x35 /* serial port3line status register address */
#define REG_MSR3_ADDR 0x36 /* serial port3address of MODEM status register */
#define REG_SCR3_ADDR 0x37 /* serial port3the user can define the register address */
#define REG_DLL3_ADDR 0x30 /* Baud rate divisor latch low 8-bit byte address */
#define REG_DLM3_ADDR 0x31 /* Baud rate divisor latch high 8-bit byte address */
/* CH438serial port4 register address */
#define REG_RBR4_ADDR 0x08 /* serial port4receive buffer register address */
#define REG_THR4_ADDR 0x08 /* serial port4send hold register address */
#define REG_IER4_ADDR 0x09 /* serial port4interrupt enable register address */
#define REG_IIR4_ADDR 0x0A /* serial port4interrupt identifies register address */
#define REG_FCR4_ADDR 0x0A /* serial port4FIFO controls register address */
#define REG_LCR4_ADDR 0x0B /* serial port4circuit control register address */
#define REG_MCR4_ADDR 0x0C /* serial port4MODEM controls register address */
#define REG_LSR4_ADDR 0x0D /* serial port4line status register address */
#define REG_MSR4_ADDR 0x0E /* serial port4address of MODEM status register */
#define REG_SCR4_ADDR 0x0F /* serial port4the user can define the register address */
#define REG_DLL4_ADDR 0x08 /* Baud rate divisor latch low 8-bit byte address */
#define REG_DLM4_ADDR 0x09 /* Baud rate divisor latch high 8-bit byte address */
/* CH438serial port5 register address */
#define REG_RBR5_ADDR 0x18 /* serial port5receive buffer register address */
#define REG_THR5_ADDR 0x18 /* serial port5send hold register address */
#define REG_IER5_ADDR 0x19 /* serial port5interrupt enable register address */
#define REG_IIR5_ADDR 0x1A /* serial port5interrupt identifies register address */
#define REG_FCR5_ADDR 0x1A /* serial port5FIFO controls register address */
#define REG_LCR5_ADDR 0x1B /* serial port5circuit control register address */
#define REG_MCR5_ADDR 0x1C /* serial port5MODEM controls register address */
#define REG_LSR5_ADDR 0x1D /* serial port5line status register address */
#define REG_MSR5_ADDR 0x1E /* serial port5address of MODEM status register */
#define REG_SCR5_ADDR 0x1F /* serial port5the user can define the register address */
#define REG_DLL5_ADDR 0x18 /* Baud rate divisor latch low 8-bit byte address */
#define REG_DLM5_ADDR 0x19 /* Baud rate divisor latch high 8-bit byte address */
/* CH438serial port6 register address */
#define REG_RBR6_ADDR 0x28 /* serial port6receive buffer register address */
#define REG_THR6_ADDR 0x28 /* serial port6send hold register address */
#define REG_IER6_ADDR 0x29 /* serial port6interrupt enable register address */
#define REG_IIR6_ADDR 0x2A /* serial port6interrupt identifies register address */
#define REG_FCR6_ADDR 0x2A /* serial port6FIFO controls register address */
#define REG_LCR6_ADDR 0x2B /* serial port6circuit control register address */
#define REG_MCR6_ADDR 0x2C /* serial port6MODEM controls register address */
#define REG_LSR6_ADDR 0x2D /* serial port6line status register address */
#define REG_MSR6_ADDR 0x2E /* serial port6address of MODEM status register */
#define REG_SCR6_ADDR 0x2F /* serial port6the user can define the register address */
#define REG_DLL6_ADDR 0x28 /* Baud rate divisor latch low 8-bit byte address */
#define REG_DLM6_ADDR 0x29 /* Baud rate divisor latch high 8-bit byte address */
/* CH438serial port7 register address */
#define REG_RBR7_ADDR 0x38 /* serial port7receive buffer register address */
#define REG_THR7_ADDR 0x38 /* serial port7send hold register address */
#define REG_IER7_ADDR 0x39 /* serial port7interrupt enable register address */
#define REG_IIR7_ADDR 0x3A /* serial port7interrupt identifies register address */
#define REG_FCR7_ADDR 0x3A /* serial port7FIFO controls register address */
#define REG_LCR7_ADDR 0x3B /* serial port7circuit control register address */
#define REG_MCR7_ADDR 0x3C /* serial port7MODEM controls register address */
#define REG_LSR7_ADDR 0x3D /* serial port7line status register address */
#define REG_MSR7_ADDR 0x3E /* serial port7address of MODEM status register */
#define REG_SCR7_ADDR 0x3F /* serial port7the user can define the register address */
#define REG_DLL7_ADDR 0x38 /* Baud rate divisor latch low 8-bit byte address */
#define REG_DLM7_ADDR 0x39 /* Baud rate divisor latch high 8-bit byte address */
#define REG_SSR_ADDR 0x4F /* pecial status register address */
/* IER register bit */
#define BIT_IER_RESET 0x80 /* The bit is 1 soft reset serial port */
#define BIT_IER_LOWPOWER 0x40 /* The bit is 1 close serial port internal reference clock */
#define BIT_IER_SLP 0x20 /* serial port0 is SLP, 1 close clock vibrator */
#define BIT_IER1_CK2X 0x20 /* serial port1 is CK2X, 1 force the external clock signal after 2 times as internal reference clock */
#define BIT_IER_IEMODEM 0x08 /* The bit is 1 allows MODEM input status to interrupt */
#define BIT_IER_IELINES 0x04 /* The bit is 1 allow receiving line status to be interrupted */
#define BIT_IER_IETHRE 0x02 /* The bit is 1 allows the send hold register to break in mid-air */
#define BIT_IER_IERECV 0x01 /* The bit is 1 allows receiving data interrupts */
/* IIR register bit */
#define BIT_IIR_FIFOENS1 0x80
#define BIT_IIR_FIFOENS0 0x40 /* The two is 1 said use FIFO */
/* Interrupt type: 0001 has no interrupt, 0110 receiving line status is interrupted, 0100 receiving data can be interrupted,
1100 received data timeout interrupt, 0010THR register air interrupt, 0000MODEM input change interrupt */
#define BIT_IIR_IID3 0x08
#define BIT_IIR_IID2 0x04
#define BIT_IIR_IID1 0x02
#define BIT_IIR_NOINT 0x01
/* FCR register bit */
/* Trigger point: 00 corresponds to 1 byte, 01 corresponds to 16 bytes, 10 corresponds to 64 bytes, 11 corresponds to 112 bytes */
#define BIT_FCR_RECVTG1 0x80 /* Set the trigger point for FIFO interruption and automatic hardware flow control */
#define BIT_FCR_RECVTG0 0x40 /* Set the trigger point for FIFO interruption and automatic hardware flow control */
#define BIT_FCR_TFIFORST 0x04 /* The bit is 1 empty the data sent in FIFO */
#define BIT_FCR_RFIFORST 0x02 /* The bit is 1 empty the data sent in FIFO */
#define BIT_FCR_FIFOEN 0x01 /* The bit is 1 use FIFO, 0 disable FIFO */
/* LCR register bit */
#define BIT_LCR_DLAB 0x80 /* To access DLL, DLM, 0 to access RBR/THR/IER */
#define BIT_LCR_BREAKEN 0x40 /* 1 forces a BREAK line interval*/
/* Set the check format: when PAREN is 1, 00 odd check, 01 even check, 10 MARK (set 1), 11 blank (SPACE, clear 0) */
#define BIT_LCR_PARMODE1 0x20 /* Sets the parity bit format */
#define BIT_LCR_PARMODE0 0x10 /* Sets the parity bit format */
#define BIT_LCR_PAREN 0x08 /* A value of 1 allows you to generate and receive parity bits when sending */
#define BIT_LCR_STOPBIT 0x04 /* If is 1, then two stop bits, is 0, a stop bit */
/* Set word length: 00 for 5 data bits, 01 for 6 data bits, 10 for 7 data bits and 11 for 8 data bits */
#define BIT_LCR_WORDSZ1 0x02 /* Set the word length length */
#define BIT_LCR_WORDSZ0 0x01
/* MCR register bit */
#define BIT_MCR_AFE 0x20 /* For 1 allows automatic flow control of CTS and RTS hardware */
#define BIT_MCR_LOOP 0x10 /* Is the test mode of 1 enabling internal loop */
#define BIT_MCR_OUT2 0x08 /* 1 Allows an interrupt request for the serial port output */
#define BIT_MCR_OUT1 0x04 /* The MODEM control bit defined for the user */
#define BIT_MCR_RTS 0x02 /* The bit is 1 RTS pin output effective */
#define BIT_MCR_DTR 0x01 /* The bit is 1 DTR pin output effective */
/* LSR register bit */
#define BIT_LSR_RFIFOERR 0x80 /* 1 said There is at least one error in receiving FIFO */
#define BIT_LSR_TEMT 0x40 /* 1 said THR and TSR are empty */
#define BIT_LSR_THRE 0x20 /* 1 said THR is empty*/
#define BIT_LSR_BREAKINT 0x10 /* The bit is 1 said the BREAK line interval was detected*/
#define BIT_LSR_FRAMEERR 0x08 /* The bit is 1 said error reading data frame */
#define BIT_LSR_PARERR 0x04 /* The bit is 1 said parity error */
#define BIT_LSR_OVERR 0x02 /* 1 said receive FIFO buffer overflow */
#define BIT_LSR_DATARDY 0x01 /* The bit is 1 said receive data received in FIFO */
/* MSR register bit */
#define BIT_MSR_DCD 0x80 /* The bit is 1 said DCD pin effective */
#define BIT_MSR_RI 0x40 /* The bit is 1 said RI pin effective */
#define BIT_MSR_DSR 0x20 /* The bit is 1 said DSR pin effective */
#define BIT_MSR_CTS 0x10 /* The bit is 1 said CTS pin effective */
#define BIT_MSR_DDCD 0x08 /* The bit is 1 said DCD pin The input state has changed */
#define BIT_MSR_TERI 0x04 /* The bit is 1 said RI pin The input state has changed */
#define BIT_MSR_DDSR 0x02 /* The bit is 1 said DSR pin The input state has changed */
#define BIT_MSR_DCTS 0x01 /* The bit is 1 said CTS pin The input state has changed */
/* Interrupt status code */
#define INT_NOINT 0x01 /* There is no interruption */
#define INT_THR_EMPTY 0x02 /* THR empty interruption */
#define INT_RCV_OVERTIME 0x0C /* Receive timeout interrupt */
#define INT_RCV_SUCCESS 0x04 /* Interrupts are available to receive data */
#define INT_RCV_LINES 0x06 /* Receiving line status interrupted */
#define INT_MODEM_CHANGE 0x00 /* MODEM input changes interrupt */
#define CH438_IIR_FIFOS_ENABLED 0xC0 /* use FIFO */
#define Fpclk 1843200 /* Define the internal clock frequency */
void CH438_INIT(void);
void CH438_PORT_INIT( rt_uint8_t ext_uart_no,rt_uint32_t BaudRate );
rt_uint8_t ReadCH438Data( rt_uint8_t addr );
void CH438UARTSend( rt_uint8_t ext_uart_no,rt_uint8_t *Data, rt_uint8_t Num );
rt_uint8_t CH438UARTRcv( rt_uint8_t ext_uart_no, rt_uint8_t* buf );
void set_485_input(rt_uint8_t ch_no);
void set_485_output(rt_uint8_t ch_no);
static void CH438_set_output(void);
static void CH438_set_input(void);
static void WriteCH438Data( rt_uint8_t addr, rt_uint8_t dat);
static void WriteCH438Block( rt_uint8_t mAddr, rt_uint8_t mLen, rt_uint8_t *mBuf );
#endif
@@ -0,0 +1,90 @@
/* Copyright 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.
*/
#include <rtthread.h>
#include "dmalock.h"
struct dmac_host
{
struct rt_semaphore sem;
struct rt_mutex mutex;
uint8_t channel_used[DMAC_CHANNEL_COUNT];
char *channel_name[DMAC_CHANNEL_COUNT];
};
static struct dmac_host _dmac_host;
void dmalock_init(void)
{
rt_sem_init(&_dmac_host.sem, "dma_sem", DMAC_CHANNEL_COUNT, RT_IPC_FLAG_FIFO);
rt_mutex_init(&_dmac_host.mutex, "dma_mutex", RT_IPC_FLAG_FIFO);
for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
{
_dmac_host.channel_used[i] = 0;
_dmac_host.channel_name[i] = NULL;
}
}
int _dmalock_sync_take(dmac_channel_number_t *chn, int timeout_ms, const char *name)
{
rt_err_t result;
*chn = DMAC_CHANNEL_MAX;
result = rt_sem_take(&_dmac_host.sem, timeout_ms);
if (result == RT_EOK)
{
rt_mutex_take(&_dmac_host.mutex, RT_WAITING_FOREVER);
for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
{
if (_dmac_host.channel_used[i] == 0)
{
_dmac_host.channel_used[i] = 1;
_dmac_host.channel_name[i] = name;
*chn = i;
break;
}
}
rt_mutex_release(&_dmac_host.mutex);
}
return result;
}
void dmalock_release(dmac_channel_number_t chn)
{
if (chn >= DMAC_CHANNEL_MAX)
return;
_dmac_host.channel_name[chn] = NULL;
_dmac_host.channel_used[chn] = 0;
rt_sem_release(&_dmac_host.sem);
}
static void dma_ch_info(int argc, char **argv)
{
uint32_t cnt = 0;
for (int i = 0; i < DMAC_CHANNEL_COUNT; i++)
{
if (_dmac_host.channel_used[i] != 0)
{
rt_kprintf("dma_ch%d is using by func [%s]\n", i, _dmac_host.channel_name[i]);
cnt++;
}
}
if(cnt == 0)
rt_kprintf(" no dma_ch is using.\n");
}
MSH_CMD_EXPORT(dma_ch_info, list dma channel informationn.);
@@ -0,0 +1,14 @@
#ifndef __DMALOCK_H
#define __DMALOCK_H
#include <stdint.h>
#include <rtdef.h>
#include <dmac.h>
#define dmalock_sync_take(x,y) _dmalock_sync_take(x, y, __func__)
void dmalock_init(void);
int _dmalock_sync_take(dmac_channel_number_t *chn, int timeout_ms, const char *name);
void dmalock_release(dmac_channel_number_t chn);
#endif
@@ -0,0 +1,167 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-27 tianchunyu the first version
*/
#include <rtthread.h>
#include <stdio.h>
#ifdef BSP_USING_DVP
#include <drv_dvp.h>
#define DRV_DEBUG
#define LOG_TAG "drv.dvp"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
static struct kendryte_dvp rt_dvp = {0};
static void (*dvp_irq_callback)(void) = NULL;
/*
the camera starts transfering photos
*/
static int on_irq_dvp(void* ctx)
{
if (dvp_get_interrupt(DVP_STS_FRAME_FINISH))
{
rt_dvp_stop();
dvp_clear_interrupt(DVP_STS_FRAME_FINISH);
(*dvp_irq_callback)();
}
return 0;
}
void rt_dvp_start(uint32_t pData, uint32_t Length)
{
dvp_set_display_addr(pData);
dvp_config_interrupt(DVP_CFG_FINISH_INT_ENABLE, 1);
dvp_start_convert();
}
/*
the camera stops transfering photos
*/
void rt_dvp_stop(void)
{
dvp_config_interrupt(DVP_CFG_FINISH_INT_ENABLE, 0);
}
static rt_err_t rt_dvp_init(rt_device_t dev)
{
//sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL);
RT_ASSERT(dev != RT_NULL);
rt_err_t result = RT_EOK;
/* Init DVP IO map and function settings io pin serial number depends on schematic diagram
initialize io in io_config_init function*/
/*ov2640 dvp interface initialize*/
dvp_init(8);
dvp_set_xclk_rate(24000000);
dvp_enable_burst();
dvp_set_output_enable(0, 1);
dvp_set_output_enable(1, 1);
dvp_set_image_format(DVP_CFG_RGB_FORMAT);////////////////
dvp_set_image_size(320, 240); // default
dvp_config_interrupt(DVP_CFG_FINISH_INT_ENABLE, 0);
dvp_disable_auto();
plic_set_priority(IRQN_DVP_INTERRUPT, 1);
plic_irq_register(IRQN_DVP_INTERRUPT, on_irq_dvp, NULL);
plic_irq_enable(IRQN_DVP_INTERRUPT);
dvp_clear_interrupt(DVP_STS_FRAME_FINISH);
LOG_I("dvp initialize success");
return result;
}
static rt_err_t rt_dvp_open(rt_device_t dev, rt_uint16_t oflag)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_err_t rt_dvp_close(rt_device_t dev)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_err_t rt_dvp_control(rt_device_t dev, int cmd, void *args)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_size_t rt_dvp_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
static rt_size_t rt_dvp_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
RT_ASSERT(dev != RT_NULL);
return RT_EOK;
}
rt_err_t rt_set_irq_dvp_callback_hander(void (*p)(void))
{
if(NULL == p)
{
LOG_E("set irq dcmi callback hander is NULL");
return RT_ERROR;
}
dvp_irq_callback = p;
return RT_EOK;
}
int kendryte_dvp_init(void)
{
int ret = 0;
rt_device_t dvp_dev = RT_NULL;
rt_dvp.dev.parent.type = RT_Device_Class_Miscellaneous;
rt_dvp.dev.parent.init = rt_dvp_init;
rt_dvp.dev.parent.open = rt_dvp_open;
rt_dvp.dev.parent.close = rt_dvp_close;
rt_dvp.dev.parent.read = rt_dvp_read;
rt_dvp.dev.parent.write = rt_dvp_write;
rt_dvp.dev.parent.control = rt_dvp_control;
rt_dvp.dev.parent.user_data = RT_NULL;
ret = rt_device_register(&rt_dvp.dev.parent, "dvp", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
if(ret != RT_EOK)
{
LOG_E("dvp register fail!!\n\r");
return -RT_ERROR;
}
LOG_I("dvp register successfully");
dvp_dev = rt_device_find("dvp");
if (dvp_dev == RT_NULL)
{
LOG_E("can't find dvp device!");
return RT_ERROR;
}
ret = rt_device_open(dvp_dev, RT_DEVICE_FLAG_RDWR);
if(ret != RT_EOK)
{
LOG_E("can't open dvp device!");
return RT_ERROR;
}
LOG_I("dvp open successfully");
return RT_EOK;
}
INIT_BOARD_EXPORT(kendryte_dvp_init);
#endif
@@ -0,0 +1,46 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2021-01-27 tianchunyu the first version
*/
#ifndef __DRV_DVP_H__
#define __DRV_DVP_H__
#include <dvp.h>
#include <fpioa.h>
#include <sysctl.h>
#include <plic.h>
#include <sysctl.h>
#ifdef __cplusplus
extern "C" {
#endif
struct rt_dvp_device
{
struct rt_device parent;
};
struct kendryte_dvp
{
struct rt_dvp_device dev;
};
extern void rt_dvp_start(uint32_t pData, uint32_t Length);
extern void rt_dvp_stop(void);
extern rt_err_t rt_set_irq_dvp_callback_hander(void (*p)(void));
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,267 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-19 ZYH first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include <fpioa.h>
#include <gpiohs.h>
#include "drv_gpio.h"
#include "drv_io_config.h"
#include <plic.h>
#include <rthw.h>
#include <utils.h>
#include <string.h>
#define DBG_ENABLE
#define DBG_TAG "PIN"
#define DBG_LVL DBG_WARNING
#define DBG_COLOR
#include <rtdbg.h>
#define FUNC_GPIOHS(n) (FUNC_GPIOHS0 + n)
static short pin_alloc_table[FPIOA_NUM_IO];
static uint32_t free_pin = 0;
static int alloc_pin_channel(rt_base_t pin_index)
{
if(free_pin == 32)
{
LOG_E("no free gpiohs channel to alloc");
return -1;
}
if(pin_alloc_table[pin_index] != -1)
{
LOG_W("already alloc gpiohs channel for pin %d", pin_index);
return pin_alloc_table[pin_index];
}
pin_alloc_table[pin_index] = free_pin;
free_pin++;
fpioa_set_function(pin_index, FUNC_GPIOHS(pin_alloc_table[pin_index]));
return pin_alloc_table[pin_index];
}
int get_pin_channel(rt_base_t pin_index)
{
return pin_alloc_table[pin_index];
}
static void free_pin_channel(rt_base_t pin_index)
{
if(pin_alloc_table[pin_index] == -1)
{
LOG_W("free error:not alloc gpiohs channel for pin %d", pin_index);
return;
}
pin_alloc_table[pin_index] = -1;
free_pin--;
}
static void drv_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode)
{
int pin_channel = get_pin_channel(pin);
if(pin_channel == -1)
{
pin_channel = alloc_pin_channel(pin);
if(pin_channel == -1)
{
return;
}
}
switch (mode)
{
case PIN_MODE_OUTPUT:
gpiohs_set_drive_mode(pin_channel, GPIO_DM_OUTPUT);
break;
case PIN_MODE_INPUT:
gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT);
break;
case PIN_MODE_INPUT_PULLUP:
gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT_PULL_UP);
break;
case PIN_MODE_INPUT_PULLDOWN:
gpiohs_set_drive_mode(pin_channel, GPIO_DM_INPUT_PULL_DOWN);
break;
default:
LOG_E("Not support mode %d", mode);
break;
}
}
static void drv_pin_write(struct rt_device *device, rt_base_t pin, rt_base_t value)
{
int pin_channel = get_pin_channel(pin);
if(pin_channel == -1)
{
LOG_E("pin %d not set mode", pin);
return;
}
gpiohs_set_pin(pin_channel, value == PIN_HIGH ? GPIO_PV_HIGH : GPIO_PV_LOW);
}
static int drv_pin_read(struct rt_device *device, rt_base_t pin)
{
int pin_channel = get_pin_channel(pin);
if(pin_channel == -1)
{
LOG_E("pin %d not set mode", pin);
return -1;
}
return gpiohs_get_pin(pin_channel) == GPIO_PV_HIGH ? PIN_HIGH : PIN_LOW;
}
static struct
{
void (*hdr)(void *args);
void* args;
gpio_pin_edge_t edge;
} irq_table[32];
static void pin_irq(int vector, void *param)
{
int pin_channel = vector - IRQN_GPIOHS0_INTERRUPT;
if(irq_table[pin_channel].edge & GPIO_PE_FALLING)
{
set_gpio_bit(gpiohs->fall_ie.u32, pin_channel, 0);
set_gpio_bit(gpiohs->fall_ip.u32, pin_channel, 1);
set_gpio_bit(gpiohs->fall_ie.u32, pin_channel, 1);
}
if(irq_table[pin_channel].edge & GPIO_PE_RISING)
{
set_gpio_bit(gpiohs->rise_ie.u32, pin_channel, 0);
set_gpio_bit(gpiohs->rise_ip.u32, pin_channel, 1);
set_gpio_bit(gpiohs->rise_ie.u32, pin_channel, 1);
}
if(irq_table[pin_channel].edge & GPIO_PE_LOW)
{
set_gpio_bit(gpiohs->low_ie.u32, pin_channel, 0);
set_gpio_bit(gpiohs->low_ip.u32, pin_channel, 1);
set_gpio_bit(gpiohs->low_ie.u32, pin_channel, 1);
}
if(irq_table[pin_channel].edge & GPIO_PE_HIGH)
{
set_gpio_bit(gpiohs->high_ie.u32, pin_channel, 0);
set_gpio_bit(gpiohs->high_ip.u32, pin_channel, 1);
set_gpio_bit(gpiohs->high_ie.u32, pin_channel, 1);
}
if(irq_table[pin_channel].hdr)
{
irq_table[pin_channel].hdr(irq_table[pin_channel].args);
}
}
static rt_err_t drv_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
int pin_channel = get_pin_channel(pin);
char irq_name[10];
if(pin_channel == -1)
{
LOG_E("pin %d not set mode", pin);
return -RT_ERROR;
}
irq_table[pin_channel].hdr = hdr;
irq_table[pin_channel].args = args;
switch (mode)
{
case PIN_IRQ_MODE_RISING:
irq_table[pin_channel].edge = GPIO_PE_RISING;
break;
case PIN_IRQ_MODE_FALLING:
irq_table[pin_channel].edge = GPIO_PE_FALLING;
break;
case PIN_IRQ_MODE_RISING_FALLING:
irq_table[pin_channel].edge = GPIO_PE_BOTH;
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
irq_table[pin_channel].edge = GPIO_PE_LOW;
break;
case PIN_IRQ_MODE_LOW_LEVEL:
irq_table[pin_channel].edge = GPIO_PE_HIGH;
break;
default:
break;
}
gpiohs_set_pin_edge(pin_channel, irq_table[pin_channel].edge);
rt_snprintf(irq_name, sizeof irq_name, "pin%d", pin);
rt_hw_interrupt_install(IRQN_GPIOHS0_INTERRUPT + pin_channel, pin_irq, RT_NULL, irq_name);
return RT_EOK;
}
static rt_err_t drv_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_err_t ret = RT_EOK;
int pin_channel = get_pin_channel(pin);
if(pin_channel == -1)
{
LOG_E("pin %d not set mode", pin);
return -RT_ERROR;
}
irq_table[pin_channel].hdr = RT_NULL;
irq_table[pin_channel].args = RT_NULL;
return ret;
}
static rt_err_t drv_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
int pin_channel = get_pin_channel(pin);
if(pin_channel == -1)
{
LOG_E("pin %d not set mode", pin);
return -RT_ERROR;
}
if(enabled)
{
rt_hw_interrupt_umask(IRQN_GPIOHS0_INTERRUPT + pin_channel);
}
else
{
rt_hw_interrupt_mask(IRQN_GPIOHS0_INTERRUPT + pin_channel);
}
return RT_EOK;
}
const static struct rt_pin_ops drv_pin_ops =
{
drv_pin_mode,
drv_pin_write,
drv_pin_read,
drv_pin_attach_irq,
drv_pin_detach_irq,
drv_pin_irq_enable
};
int rt_hw_pin_init(void)
{
rt_err_t ret = RT_EOK;
memset(pin_alloc_table, 0xff, sizeof pin_alloc_table);
free_pin = GPIO_ALLOC_START;
ret = rt_device_pin_register("pin", &drv_pin_ops, RT_NULL);
return ret;
}
INIT_BOARD_EXPORT(rt_hw_pin_init);
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-19 ZYH first version
*/
#ifndef DRV_GPIO_H__
#define DRV_GPIO_H__
int rt_hw_pin_init(void);
#endif
@@ -0,0 +1,27 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-19 ZYH first version
*/
#include <plic.h>
void plic_irq_handle(plic_irq_t irq)
{
plic_instance_t (*plic_instance)[IRQN_MAX] = plic_get_instance();
if (plic_instance[0][irq].callback)
{
plic_instance[0][irq].callback(
plic_instance[0][irq].ctx);
}
else if (plic_instance[1][irq].callback)
{
plic_instance[1][irq].callback(
plic_instance[1][irq].ctx);
}
}
@@ -0,0 +1,233 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-19 ZYH first version
*/
#include <rtthread.h>
#include <fpioa.h>
#include <drv_io_config.h>
#include <sysctl.h>
#define HS_GPIO(n) (FUNC_GPIOHS0 + n)
#define IOCONFIG(pin,func) {pin, func, #func}
static struct io_config
{
int io_num;
fpioa_function_t func;
const char * func_name;
} io_config[] =
{
#ifdef BSP_USING_LCD
IOCONFIG(BSP_LCD_CS_PIN, FUNC_SPI0_SS0), /* LCD CS PIN */
IOCONFIG(BSP_LCD_WR_PIN, FUNC_SPI0_SCLK), /* LCD WR PIN */
IOCONFIG(BSP_LCD_DC_PIN, HS_GPIO(LCD_DC_PIN)), /* LCD DC PIN */
#if BSP_LCD_RST_PIN >= 0
IOCONFIG(BSP_LCD_RST_PIN, HS_GPIO(LCD_RST_PIN)), /* LCD RESET PIN */
#endif
#if BSP_LCD_BACKLIGHT_PIN >= 0
IOCONFIG(BSP_LCD_BACKLIGHT_PIN, HS_GPIO(LCD_BACKLIGHT_PIN)), /* LCD BACKLIGHT PIN */
#endif
#endif
#ifdef BSP_USING_DVP
IOCONFIG(BSP_DVP_SCCB_SDA_PIN, FUNC_SCCB_SDA),
IOCONFIG(BSP_DVP_SCCB_SCLK_PIN, FUNC_SCCB_SCLK),
IOCONFIG(BSP_DVP_CMOS_RST_PIN, FUNC_CMOS_RST),
IOCONFIG(BSP_DVP_CMOS_VSYNC_PIN, FUNC_CMOS_VSYNC),
IOCONFIG(BSP_DVP_CMOS_PWDN_PIN, FUNC_CMOS_PWDN),
IOCONFIG(BSP_DVP_CMOS_XCLK_PIN, FUNC_CMOS_XCLK),
IOCONFIG(BSP_DVP_CMOS_PCLK_PIN, FUNC_CMOS_PCLK),
IOCONFIG(BSP_DVP_CMOS_HREF_PIN, FUNC_CMOS_HREF),
#endif
#ifdef BSP_USING_SPI1
IOCONFIG(BSP_SPI1_CLK_PIN, FUNC_SPI1_SCLK),
IOCONFIG(BSP_SPI1_D0_PIN, FUNC_SPI1_D0),
IOCONFIG(BSP_SPI1_D1_PIN, FUNC_SPI1_D1),
#ifdef BSP_USING_SPI1_AS_QSPI
IOCONFIG(BSP_SPI1_D2_PIN, FUNC_SPI1_D2),
IOCONFIG(BSP_SPI1_D3_PIN, FUNC_SPI1_D3),
#endif
#ifdef BSP_SPI1_USING_SS0
IOCONFIG(BSP_SPI1_SS0_PIN, HS_GPIO(SPI1_CS0_PIN)),
#endif
#ifdef BSP_SPI1_USING_SS1
IOCONFIG(BSP_SPI1_SS1_PIN, HS_GPIO(SPI1_CS1_PIN)),
#endif
#ifdef BSP_SPI1_USING_SS2
IOCONFIG(BSP_SPI1_SS2_PIN, HS_GPIO(SPI1_CS2_PIN)),
#endif
#ifdef BSP_SPI1_USING_SS3
IOCONFIG(BSP_SPI1_SS3_PIN, HS_GPIO(SPI1_CS3_PIN)),
#endif
#endif
#ifdef BSP_USING_UART1
IOCONFIG(BSP_UART1_TXD_PIN, FUNC_UART1_TX),
IOCONFIG(BSP_UART1_RXD_PIN, FUNC_UART1_RX),
#if BSP_UART1_RTS_PIN >= 0
IOCONFIG(BSP_UART1_RTS_PIN, FUNC_UART1_RTS),
#endif
#if BSP_UART1_CTS_PIN >= 0
IOCONFIG(BSP_UART1_CTS_PIN, FUNC_UART1_CTS),
#endif
#endif
#ifdef BSP_USING_UART2
IOCONFIG(BSP_UART2_TXD_PIN, FUNC_UART2_TX),
IOCONFIG(BSP_UART2_RXD_PIN, FUNC_UART2_RX),
#if BSP_UART2_RTS_PIN >= 0
IOCONFIG(BSP_UART2_RTS_PIN, FUNC_UART2_RTS),
#endif
#if BSP_UART2_CTS_PIN >= 0
IOCONFIG(BSP_UART2_CTS_PIN, FUNC_UART2_CTS),
#endif
#endif
#ifdef BSP_USING_UART3
IOCONFIG(BSP_UART3_TXD_PIN, FUNC_UART3_TX),
IOCONFIG(BSP_UART3_RXD_PIN, FUNC_UART3_RX),
#if BSP_UART3_RTS_PIN >= 0
IOCONFIG(BSP_UART3_RTS_PIN, FUNC_UART3_RTS),
#endif
#if BSP_UART3_CTS_PIN >= 0
IOCONFIG(BSP_UART3_CTS_PIN, FUNC_UART3_CTS),
#endif
#endif
#ifdef BSP_USING_I2C0
IOCONFIG(BSP_I2C0_SCL_PIN, FUNC_I2C0_SCLK),
IOCONFIG(BSP_I2C0_SDA_PIN, FUNC_I2C0_SDA),
#endif
#ifdef BSP_USING_I2C1
IOCONFIG(BSP_I2C1_SCL_PIN, FUNC_I2C1_SCLK),
IOCONFIG(BSP_I2C1_SDA_PIN, FUNC_I2C1_SDA),
#endif
#ifdef BSP_USING_I2C2
IOCONFIG(BSP_I2C2_SCL_PIN, FUNC_I2C2_SCLK),
IOCONFIG(BSP_I2C2_SDA_PIN, FUNC_I2C2_SDA),
#endif
#ifdef BSP_USING_I2S0
IOCONFIG(BSP_I2S0_OUT_D1_PIN, FUNC_I2S0_OUT_D1),
IOCONFIG(BSP_I2S0_WS_PIN, FUNC_I2S0_WS),
IOCONFIG(BSP_I2S0_SCLK_PIN, FUNC_I2S0_SCLK),
#endif
#ifdef BSP_USING_I2S1
IOCONFIG(BSP_I2S1_IN_D0_PIN, FUNC_I2S1_IN_D0),
IOCONFIG(BSP_I2S1_WS_PIN, FUNC_I2S1_WS),
IOCONFIG(BSP_I2S1_SCLK_PIN, FUNC_I2S1_SCLK),
#endif
#ifdef BSP_USING_I2S2
IOCONFIG(BSP_I2S2_OUT_D1_PIN, FUNC_I2S2_OUT_D1),
IOCONFIG(BSP_I2S2_WS_PIN, FUNC_I2S2_WS),
IOCONFIG(BSP_I2S2_SCLK_PIN, FUNC_I2S2_SCLK),
#endif
#ifdef BSP_PWM_CHN0_ENABLE
IOCONFIG(BSP_PWM_CHN0_PIN, FUNC_TIMER2_TOGGLE1),
#endif
#ifdef BSP_PWM_CHN1_ENABLE
IOCONFIG(BSP_PWM_CHN1_PIN, FUNC_TIMER2_TOGGLE2),
#endif
#ifdef BSP_PWM_CHN2_ENABLE
IOCONFIG(BSP_PWM_CHN2_PIN, FUNC_TIMER2_TOGGLE3),
#endif
#ifdef BSP_PWM_CHN3_ENABLE
IOCONFIG(BSP_PWM_CHN3_PIN, FUNC_TIMER2_TOGGLE4),
#endif
IOCONFIG(BSP_CH438_ALE_PIN, HS_GPIO(FPIOA_CH438_ALE)),
IOCONFIG(BSP_CH438_NWR_PIN, HS_GPIO(FPIOA_CH438_NWR)),
IOCONFIG(BSP_CH438_NRD_PIN, HS_GPIO(FPIOA_CH438_NRD)),
IOCONFIG(BSP_CH438_INT_PIN, HS_GPIO(FPIOA_CH438_INT)),
IOCONFIG(BSP_CH438_D0_PIN, HS_GPIO(FPIOA_CH438_D0)),
IOCONFIG(BSP_CH438_D1_PIN, HS_GPIO(FPIOA_CH438_D1)),
IOCONFIG(BSP_CH438_D2_PIN, HS_GPIO(FPIOA_CH438_D2)),
IOCONFIG(BSP_CH438_D3_PIN, HS_GPIO(FPIOA_CH438_D3)),
IOCONFIG(BSP_CH438_D4_PIN, HS_GPIO(FPIOA_CH438_D4)),
IOCONFIG(BSP_CH438_D5_PIN, HS_GPIO(FPIOA_CH438_D5)),
IOCONFIG(BSP_CH438_D6_PIN, HS_GPIO(FPIOA_CH438_D6)),
IOCONFIG(BSP_CH438_D7_PIN, HS_GPIO(FPIOA_CH438_D7)),
};
static int print_io_config()
{
int i;
rt_kprintf("IO Configuration Table\n");
rt_kprintf("┌───────┬────────────────────────┐\n");
rt_kprintf("│Pin │Function │\n");
rt_kprintf("├───────┼────────────────────────┤\n");
for(i = 0; i < sizeof io_config / sizeof io_config[0]; i++)
{
rt_kprintf("│%-2d │%-24.24s│\n", io_config[i].io_num, io_config[i].func_name);
}
rt_kprintf("└───────┴────────────────────────┘\n");
return 0;
}
MSH_CMD_EXPORT_ALIAS(print_io_config, io, print io config);
int io_config_init(void)
{
int count = sizeof(io_config) / sizeof(io_config[0]);
int i;
/* IO GroupA Power Supply Setting */
#if defined(BSP_GROUPA_POWER_SUPPLY_3V3)
sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V33);
sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V33);
sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V33);
#else
sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18);
sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18);
sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18);
#endif
/* IO GroupB Power Supply Setting */
#if defined(BSP_GROUPB_POWER_SUPPLY_3V3)
sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33);
sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33);
sysctl_set_power_mode(SYSCTL_POWER_BANK5, SYSCTL_POWER_V33);
#else
sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V18);
sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V18);
sysctl_set_power_mode(SYSCTL_POWER_BANK5, SYSCTL_POWER_V18);
#endif
/* IO GroupC Power Supply Setting */
#if defined(BSP_GROUPC_POWER_SUPPLY_3V3)
sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V33);
sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V33);
#else
sysctl_set_power_mode(SYSCTL_POWER_BANK6, SYSCTL_POWER_V18);
sysctl_set_power_mode(SYSCTL_POWER_BANK7, SYSCTL_POWER_V18);
#endif
for(i = 0; i < count; i++)
{
fpioa_set_function(io_config[i].io_num, io_config[i].func);
}
#if defined(BSP_USING_DVP) || defined(BSP_USING_LCD)
sysctl_set_spi0_dvp_data(1);
sysctl_clock_enable(SYSCTL_CLOCK_AI);
#endif
}
int io_config_used(int io_num)
{
int count = sizeof(io_config) / sizeof(io_config[0]);
int i;
for(i = 0; i < count; i++)
{
if (io_config[i].io_num == io_num)
break;
}
return (i < count);
}
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-19 ZYH first version
*/
#ifndef __DRV_IO_CONFIG_H__
#define __DRV_IO_CONFIG_H__
#include <rtconfig.h>
enum HS_GPIO_CONFIG
{
#ifdef BSP_USING_LCD
LCD_DC_PIN = 0, /* LCD DC PIN */
#if BSP_LCD_RST_PIN >= 0
LCD_RST_PIN,
#endif
#if BSP_LCD_BACKLIGHT_PIN >= 0
LCD_BACKLIGHT_PIN,
#endif
#endif
#ifdef BSP_SPI1_USING_SS0
SPI1_CS0_PIN,
#endif
#ifdef BSP_SPI1_USING_SS1
SPI1_CS1_PIN,
#endif
#ifdef BSP_SPI1_USING_SS2
SPI1_CS2_PIN,
#endif
#ifdef BSP_SPI1_USING_SS3
SPI1_CS3_PIN,
#endif
#ifdef BSP_USING_BRIDGE
SPI2_INT_PIN,
SPI2_READY_PIN,
#endif
GPIO_ALLOC_START /* index of gpio driver start */
};
#define FPIOA_CH438_ALE 11
#define FPIOA_CH438_NWR 12
#define FPIOA_CH438_NRD 13
#define FPIOA_CH438_D0 14
#define FPIOA_CH438_D1 15
#define FPIOA_CH438_D2 16
#define FPIOA_CH438_D3 17
#define FPIOA_CH438_D4 18
#define FPIOA_CH438_D5 19
#define FPIOA_CH438_D6 20
#define FPIOA_CH438_D7 21
#define FPIOA_CH438_INT 22
#define FPIOA_485_DIR 23
//PIN.define
#define BSP_CH438_ALE_PIN 23
#define BSP_CH438_NWR_PIN 24
#define BSP_CH438_NRD_PIN 25
#define BSP_CH438_D0_PIN 27
#define BSP_CH438_D1_PIN 28
#define BSP_CH438_D2_PIN 29
#define BSP_CH438_D3_PIN 30
#define BSP_CH438_D4_PIN 31
#define BSP_CH438_D5_PIN 32
#define BSP_CH438_D6_PIN 33
#define BSP_CH438_D7_PIN 34
#define BSP_CH438_INT_PIN 35
extern int io_config_init(void);
#endif
@@ -0,0 +1,550 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-12 ZYH first version
*/
#include <rtthread.h>
#ifdef BSP_USING_LCD
#include <drv_lcd.h>
#define DBG_TAG "LCD"
#define DBG_LVL DBG_WARNING
#include <rtdbg.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
#define LCD_SPI_CHANNEL SPI_DEVICE_0
#define LCD_SPI_CHIP_SELECT SPI_CHIP_SELECT_0
#if defined(BSP_BOARD_K210_OPENMV_TEST)
#define LCD_SCAN_DIR DIR_YX_LRUD
#elif defined(BSP_BOARD_KD233)
#define LCD_SCAN_DIR (DIR_YX_RLUD | 0x08)
#elif defined(BSP_BOARD_USER)
/*user define.*/
#define LCD_SCAN_DIR DIR_YX_RLDU
#endif
static struct lcd_8080_device _lcddev;
static void drv_lcd_cmd(lcd_8080_device_t lcd, rt_uint8_t cmd)
{
gpiohs_set_pin(lcd->dc_pin, GPIO_PV_LOW);
spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
spi_init_non_standard(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(lcd->dma_channel, lcd->spi_channel, lcd->cs, &cmd, 1, SPI_TRANS_CHAR);
}
static void drv_lcd_data_byte(lcd_8080_device_t lcd, rt_uint8_t *data_buf, rt_uint32_t length)
{
gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH);
spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 8, 0);
spi_init_non_standard(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(lcd->dma_channel, lcd->spi_channel, lcd->cs, data_buf, length, SPI_TRANS_CHAR);
}
void drv_lcd_data_half_word(lcd_8080_device_t lcd, rt_uint16_t *data_buf, rt_uint32_t length)
{
gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH);
spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 16, 0);
spi_init_non_standard(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(lcd->dma_channel, lcd->spi_channel, lcd->cs, data_buf, length, SPI_TRANS_SHORT);
}
void drv_lcd_data_word(lcd_8080_device_t lcd, rt_uint32_t *data_buf, rt_uint32_t length)
{
gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH);
spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0);
spi_init_non_standard(lcd->spi_channel, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/,
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
spi_send_data_normal_dma(lcd->dma_channel, lcd->spi_channel, lcd->cs, data_buf, length, SPI_TRANS_INT);
}
static void drv_lcd_hw_init(lcd_8080_device_t lcd)
{
#if BSP_LCD_RST_PIN >= 0
{
gpiohs_set_drive_mode(lcd->rst_pin, GPIO_DM_OUTPUT);
gpiohs_set_pin(lcd->rst_pin, GPIO_PV_LOW);
rt_thread_mdelay(20);
gpiohs_set_pin(lcd->rst_pin, GPIO_PV_HIGH);
rt_thread_mdelay(20);
}
#endif
#if BSP_LCD_BACKLIGHT_PIN >= 0
{
gpiohs_set_drive_mode(lcd->backlight_pin, GPIO_DM_OUTPUT);
#if defined(BSP_LCD_BACKLIGHT_ACTIVE_LOW)
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_LOW);
#elif defined(BSP_LCD_BACKLIGHT_ACTIVE_HIGH)
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_HIGH);
#else
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_LOW);
#endif
}
#endif
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, BSP_LCD_CLK_FREQ);
}
static void drv_lcd_set_direction(lcd_8080_device_t lcd, lcd_dir_t dir)
{
if (dir & DIR_XY_MASK)
{
lcd->lcd_info.width = BSP_LCD_Y_MAX;
lcd->lcd_info.height = BSP_LCD_X_MAX;
}
else
{
lcd->lcd_info.width = BSP_LCD_X_MAX;
lcd->lcd_info.height = BSP_LCD_Y_MAX;
}
rt_kprintf("lcd witdth %d,height %d \n",lcd->lcd_info.width,lcd->lcd_info.height);
drv_lcd_cmd(lcd, MEMORY_ACCESS_CTL);
drv_lcd_data_byte(lcd, (rt_uint8_t *)&dir, 1);
}
void drv_lcd_set_area(lcd_8080_device_t lcd, rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2)
{
rt_uint8_t data[4] = {0};
data[0] = (rt_uint8_t)(x1 >> 8);
data[1] = (rt_uint8_t)(x1);
data[2] = (rt_uint8_t)(x2 >> 8);
data[3] = (rt_uint8_t)(x2);
drv_lcd_cmd(lcd, HORIZONTAL_ADDRESS_SET);
drv_lcd_data_byte(lcd, data, 4);
data[0] = (rt_uint8_t)(y1 >> 8);
data[1] = (rt_uint8_t)(y1);
data[2] = (rt_uint8_t)(y2 >> 8);
data[3] = (rt_uint8_t)(y2);
drv_lcd_cmd(lcd, VERTICAL_ADDRESS_SET);
drv_lcd_data_byte(lcd, data, 4);
drv_lcd_cmd(lcd, MEMORY_WRITE);
}
static void drv_lcd_set_pixel(lcd_8080_device_t lcd, uint16_t x, uint16_t y, uint16_t color)
{
drv_lcd_set_area(lcd, x, y, x, y);
drv_lcd_data_half_word(lcd, &color, 1);
}
static void drv_lcd_clear(lcd_8080_device_t lcd, uint16_t color)
{
uint32_t data = ((uint32_t)color << 16) | (uint32_t)color;
drv_lcd_set_area(lcd, 0, 0, lcd->lcd_info.width - 1, lcd->lcd_info.height - 1);
gpiohs_set_pin(lcd->dc_pin, GPIO_PV_HIGH);
spi_init(lcd->spi_channel, SPI_WORK_MODE_0, SPI_FF_OCTAL, 32, 0);
spi_init_non_standard(lcd->spi_channel, 0 /*instrction length*/, 32 /*address length*/, 0 /*wait cycles*/,
SPI_AITM_AS_FRAME_FORMAT /*spi address trans mode*/);
spi_fill_data_dma(lcd->dma_channel, lcd->spi_channel, lcd->cs, (const uint32_t *)&data, lcd->lcd_info.width * lcd->lcd_info.height / 2);
}
static void rt_bitblt(rt_uint16_t * dest, int dest_segment, int dest_common, int dest_x, int dest_y, int width, int height,
rt_uint16_t *src, int src_segment, int src_common, int src_x, int src_y)
{
int sx0, sx1, sy0, sy1;
int dx0, dx1, dy0, dy1;
rt_uint16_t *buff_src;
rt_uint16_t *buff_dest;
int x, y;
if (width <= 0) {
return;
}
if (height <= 0) {
return;
}
sx0 = src_x;
sy0 = src_y;
sx1 = sx0 + width - 1;
sy1 = sy0 + height - 1;
dx0 = dest_x;
dy0 = dest_y;
dx1 = dx0 + width - 1;
dy1 = dy0 + height - 1;
if (sx0 < 0) {
dx0 -= sx0;
sx0 = 0;
}
if (sy0 < 0) {
dy0 -= sy0;
sy0 = 0;
}
if (sx1 >= src_segment) {
dx1 -= (sx1 - src_segment + 1);
sx1 = src_segment - 1;
}
if (sy1 >= src_common) {
dy1 -= (sy1 - src_common + 1);
sy1 = src_common - 1;
}
if (dx0 < 0) {
sx0 -= dx0;
dx0 = 0;
}
if (dy0 < 0) {
sy0 -= dy0;
dy0 = 0;
}
if (dx1 >= dest_segment) {
sx1 -= (dx1 - dest_segment + 1);
dx1 = dest_segment - 1;
}
if (dy1 >= dest_common) {
sy1 -= (dy1 - dest_common + 1);
dy1 = dest_common - 1;
}
if (sx1 < 0 || sx0 >= src_segment) {
return;
}
if (sy1 < 0 || sy0 >= src_common) {
return;
}
if (dx1 < 0 || dx0 >= dest_segment) {
return;
}
if (dy1 < 0 || dy0 >= dest_common) {
return;
}
if ((rt_ubase_t)dest < (rt_ubase_t)src) {
buff_src = src + (sy0 * src_segment) + sx0;
buff_dest = dest + (dy0 * dest_segment) + dx0;
for (y = sy0; y <= sy1; y++) {
src = buff_src;
dest = buff_dest;
for (x = sx0; x <= sx1; x++) {
*dest++ = *src++;
}
buff_src += src_segment;
buff_dest += dest_segment;
}
} else {
buff_src = src + (sy1 * src_segment) + sx1;
buff_dest = dest + (dy1 * dest_segment) + dx1;
for (y = sy1; y >= sy0; y--) {
src = buff_src;
dest = buff_dest;
for (x = sx1; x >= sx0; x--) {
*dest-- = *src--;
}
buff_src -= src_segment;
buff_dest -= dest_segment;
}
}
}
static void drv_lcd_rect_update(lcd_8080_device_t lcd, uint16_t x1, uint16_t y1, uint16_t width, uint16_t height)
{
static rt_uint16_t * rect_buffer = RT_NULL;
if(!rect_buffer)
{
rect_buffer = rt_malloc_align(lcd->lcd_info.height * lcd->lcd_info.width * (lcd->lcd_info.bits_per_pixel / 8), 64);
if(!rect_buffer)
{
return;
}
}
if(x1 == 0 && y1 == 0 && width == lcd->lcd_info.width && height == lcd->lcd_info.height)
{
drv_lcd_set_area(lcd, x1, y1, x1 + width - 1, y1 + height - 1);
drv_lcd_data_half_word(lcd, (rt_uint32_t *)lcd->lcd_info.framebuffer, width * height);
}
else
{
rt_bitblt(rect_buffer, width, height, 0, 0, width, height,(rt_uint16_t *)lcd->lcd_info.framebuffer, lcd->lcd_info.width, lcd->lcd_info.height, x1, y1);
drv_lcd_set_area(lcd, x1, y1, x1 + width - 1, y1 + height - 1);
drv_lcd_data_half_word(lcd, (rt_uint16_t *)rect_buffer, width * height);
}
}
static rt_err_t drv_lcd_init(rt_device_t dev)
{
rt_err_t ret = RT_EOK;
lcd_8080_device_t lcd = (lcd_8080_device_t)dev;
rt_uint8_t data = 0;
if(!lcd)
{
return RT_ERROR;
}
drv_lcd_hw_init(lcd);
/* reset LCD */
drv_lcd_cmd(lcd, SOFTWARE_RESET);
rt_thread_mdelay(100);
/* Enter normal status */
drv_lcd_cmd(lcd, SLEEP_OFF);
rt_thread_mdelay(100);
/* pixel format rgb565 */
drv_lcd_cmd(lcd, PIXEL_FORMAT_SET);
data = 0x55;
drv_lcd_data_byte(lcd, &data, 1);
/* set direction */
drv_lcd_set_direction(lcd, LCD_SCAN_DIR);
lcd->lcd_info.framebuffer = rt_malloc_align(lcd->lcd_info.height * lcd->lcd_info.width * (lcd->lcd_info.bits_per_pixel / 8), 64);
RT_ASSERT(lcd->lcd_info.framebuffer);
uint16_t *framebuffer = (uint16_t *)(lcd->lcd_info.framebuffer);
for(uint32_t i=0; i<(lcd->lcd_info.height * lcd->lcd_info.width * (lcd->lcd_info.bits_per_pixel / 8))/2; i++) {
framebuffer[i] = BLACK;
}
/*display on*/
drv_lcd_cmd(lcd, DISPALY_ON);
/* set to black */
drv_lcd_clear(lcd, BLACK);
return ret;
}
static rt_err_t drv_lcd_open(rt_device_t dev, rt_uint16_t oflag)
{
/* Not need */
return RT_EOK;
}
static rt_err_t drv_lcd_close(rt_device_t dev)
{
/* Not need */
return RT_EOK;
}
static rt_size_t drv_lcd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
/* Not need */
return 0;
}
static rt_size_t drv_lcd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
/* Not need */
return 0;
}
static rt_err_t drv_lcd_control(rt_device_t dev, int cmd, void *args)
{
rt_err_t ret = RT_EOK;
lcd_8080_device_t lcd = (lcd_8080_device_t)dev;
rt_base_t level;
struct rt_device_rect_info* rect_info = (struct rt_device_rect_info*)args;
RT_ASSERT(dev != RT_NULL);
switch (cmd)
{
case RTGRAPHIC_CTRL_RECT_UPDATE:
if(!rect_info)
{
LOG_E("RTGRAPHIC_CTRL_RECT_UPDATE error args");
return -RT_ERROR;
}
drv_lcd_rect_update(lcd, rect_info->x, rect_info->y, rect_info->width, rect_info->height);
break;
#if BSP_LCD_BACKLIGHT_PIN >= 0
case RTGRAPHIC_CTRL_POWERON:
#if defined(BSP_LCD_BACKLIGHT_ACTIVE_LOW)
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_LOW);
#elif defined(BSP_LCD_BACKLIGHT_ACTIVE_HIGH)
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_HIGH);
#else
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_LOW);
#endif
break;
case RTGRAPHIC_CTRL_POWEROFF:
#if defined(BSP_LCD_BACKLIGHT_ACTIVE_LOW)
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_HIGH);
#elif defined(BSP_LCD_BACKLIGHT_ACTIVE_HIGH)
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_LOW);
#else
gpiohs_set_pin(lcd->backlight_pin, GPIO_PV_HIGH);
#endif
break;
#endif /* BSP_LCD_BACKLIGHT_PIN >= 0 */
case RTGRAPHIC_CTRL_GET_INFO:
*(struct rt_device_graphic_info *)args = lcd->lcd_info;
break;
case RTGRAPHIC_CTRL_SET_MODE:
ret = -RT_ENOSYS;
break;
case RTGRAPHIC_CTRL_GET_EXT:
ret = -RT_ENOSYS;
break;
default:
LOG_E("drv_lcd_control cmd: %d", cmd);
break;
}
return ret;
}
#ifdef RT_USING_DEVICE_OPS
const static struct rt_device_ops drv_lcd_ops =
{
drv_lcd_init,
drv_lcd_open,
drv_lcd_close,
drv_lcd_read,
drv_lcd_write,
drv_lcd_control
};
#endif
int rt_hw_lcd_init(void)
{
rt_err_t ret = RT_EOK;
lcd_8080_device_t lcd_dev = &_lcddev;
lcd_dev->cs = SPI_CHIP_SELECT_0;
lcd_dev->dc_pin = LCD_DC_PIN;
#if BSP_LCD_RST_PIN >= 0
lcd_dev->rst_pin = LCD_RST_PIN;
#endif
#if BSP_LCD_BACKLIGHT_PIN >= 0
lcd_dev->backlight_pin = LCD_BACKLIGHT_PIN;
#endif
dmalock_sync_take(&lcd_dev->dma_channel, RT_WAITING_FOREVER);
lcd_dev->spi_channel = SPI_DEVICE_0;
lcd_dev->lcd_info.bits_per_pixel = 16;
lcd_dev->lcd_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565;
lcd_dev->parent.type = RT_Device_Class_Graphic;
lcd_dev->parent.rx_indicate = RT_NULL;
lcd_dev->parent.tx_complete = RT_NULL;
#ifdef RT_USING_DEVICE_OPS
lcd_dev->parent.ops = &drv_lcd_ops;
#else
lcd_dev->parent.init = drv_lcd_init;
lcd_dev->parent.open = drv_lcd_open;
lcd_dev->parent.close = drv_lcd_close;
lcd_dev->parent.read = drv_lcd_read;
lcd_dev->parent.write = drv_lcd_write;
lcd_dev->parent.control = drv_lcd_control;
#endif
lcd_dev->parent.user_data = RT_NULL;
ret = rt_device_register(&lcd_dev->parent, "lcd", RT_DEVICE_FLAG_RDWR);
return ret;
}
INIT_DEVICE_EXPORT(rt_hw_lcd_init);
void lcd_set_direction(lcd_dir_t dir)
{
drv_lcd_set_direction(&_lcddev, dir);
}
#endif
@@ -0,0 +1,90 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-07 ZYH first version
*/
#ifndef DRV_LCD_H__
#define DRV_LCD_H__
#include <rtdevice.h>
#include <board.h>
#include <gpiohs.h>
#include <spi.h>
#include <drv_io_config.h>
#include <rthw.h>
#include "dmalock.h"
//POINT_COLOR
#define WHITE 0xFFFF
#define BLACK 0x0000
#define BLUE 0x001F
#define BRED 0XF81F
#define GRED 0XFFE0
#define GBLUE 0X07FF
#define RED 0xF800
#define MAGENTA 0xF81F
#define GREEN 0x07E0
#define CYAN 0x7FFF
#define YELLOW 0xFFE0
#define BROWN 0XBC40
#define BRRED 0XFC07
#define GRAY 0X8430
#define GRAY175 0XAD75
#define GRAY151 0X94B2
#define GRAY187 0XBDD7
#define GRAY240 0XF79E
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;
typedef struct lcd_8080_device
{
struct rt_device parent;
struct rt_device_graphic_info lcd_info;
int spi_channel;
int cs;
int dc_pin;
#if BSP_LCD_RST_PIN >= 0
int rst_pin;
#endif
#if BSP_LCD_BACKLIGHT_PIN >= 0
int backlight_pin;
#endif
int dma_channel;
} * lcd_8080_device_t;
int rt_hw_lcd_init(void);
void drv_lcd_set_area(lcd_8080_device_t lcd, rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2);
void drv_lcd_data_word(lcd_8080_device_t lcd, rt_uint32_t *data_buf, rt_uint32_t length);
void drv_lcd_data_half_word(lcd_8080_device_t lcd, rt_uint16_t *data_buf, rt_uint32_t length);
/* for mpy machine.lcd */
void lcd_display_on(void);
void lcd_display_off(void);
void lcd_clear(int color);
void lcd_draw_point_color(int x, int y, int color);
void lcd_show_string(int x, int y, int size, const char *data);
void lcd_draw_line(int x1, int y1, int x2, int y2);
void lcd_draw_rectangle(int x1, int y1, int x2, int y2);
void lcd_draw_circle(int x1, int y1, int r);
void lcd_set_color(int back, int fore);
void lcd_show_image(int x, int y, int length, int wide, const unsigned char *buf);
void lcd_set_direction(lcd_dir_t dir);
#endif
@@ -0,0 +1,27 @@
#include <sysctl.h>
int mp_port_get_freq(int clkid, int *freq)
{
int ret = 0;
uint32_t value;
switch (clkid)
{
case 0:
value = sysctl_clock_get_freq(SYSCTL_CLOCK_CPU);
break;
case 1:
value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL1);
break;
case 2:
value = sysctl_clock_get_freq(SYSCTL_CLOCK_PLL2);
break;
default:
ret = -1;
break;
}
*freq = (int)value;
return ret;
}
@@ -0,0 +1,301 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-18 ZYH first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#ifdef RT_USING_SPI
#include "drv_spi.h"
#include <drv_io_config.h>
#include <spi.h>
#include "dmalock.h"
#include <sysctl.h>
#include <gpiohs.h>
#include <string.h>
#include "utils.h"
#define DRV_SPI_DEVICE(spi_bus) (struct drv_spi_bus *)(spi_bus)
#define MAX_CLOCK (40000000UL)
struct drv_spi_bus
{
struct rt_spi_bus parent;
spi_device_num_t spi_instance;
dmac_channel_number_t dma_send_channel;
dmac_channel_number_t dma_recv_channel;
struct rt_completion dma_completion;
};
struct drv_cs
{
int cs_index;
int cs_pin;
};
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
};
static rt_err_t drv_spi_configure(struct rt_spi_device *device,
struct rt_spi_configuration *configuration)
{
rt_err_t ret = RT_EOK;
int freq = 0;
struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus);
struct drv_cs * cs = (struct drv_cs *)device->parent.user_data;
RT_ASSERT(bus != RT_NULL);
gpiohs_set_drive_mode(cs->cs_pin, GPIO_DM_OUTPUT);
gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH);
#ifdef BSP_USING_SPI1_AS_QSPI
/* Todo:QSPI*/
#else
spi_init(bus->spi_instance, configuration->mode & RT_SPI_MODE_3, SPI_FF_STANDARD, configuration->data_width, 0);
#endif
freq = spi_set_clk_rate(bus->spi_instance, configuration->max_hz > MAX_CLOCK ? MAX_CLOCK : configuration->max_hz);
rt_kprintf("set spi freq %d\n", freq);
return ret;
}
void __spi_set_tmod(uint8_t spi_num, uint32_t tmod)
{
RT_ASSERT(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);
}
int dma_irq_callback(void *ctx)
{
struct rt_completion * cmp = ctx;
if(cmp)
{
rt_completion_done(cmp);
}
}
static rt_uint32_t drv_spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
{
struct drv_spi_bus *bus = DRV_SPI_DEVICE(device->bus);
struct drv_cs * cs = (struct drv_cs *)device->parent.user_data;
struct rt_spi_configuration *cfg = &device->config;
uint32_t * tx_buff = RT_NULL;
uint32_t * rx_buff = RT_NULL;
int i;
rt_ubase_t dummy = 0xFFFFFFFFU;
if(cfg->data_width != 8)
{
return 0;
}
RT_ASSERT(bus != RT_NULL);
if(message->cs_take)
{
gpiohs_set_pin(cs->cs_pin, GPIO_PV_LOW);
}
if(message->length)
{
bus->dma_send_channel = DMAC_CHANNEL_MAX;
bus->dma_recv_channel = DMAC_CHANNEL_MAX;
rt_completion_init(&bus->dma_completion);
if(message->recv_buf)
{
dmalock_sync_take(&bus->dma_recv_channel, RT_WAITING_FOREVER);
sysctl_dma_select(bus->dma_recv_channel, SYSCTL_DMA_SELECT_SSI0_RX_REQ + bus->spi_instance * 2);
rx_buff = rt_calloc(message->length * 4, 1);
if(!rx_buff)
{
goto transfer_done;
}
}
if(message->send_buf)
{
dmalock_sync_take(&bus->dma_send_channel, RT_WAITING_FOREVER);
sysctl_dma_select(bus->dma_send_channel, SYSCTL_DMA_SELECT_SSI0_TX_REQ + bus->spi_instance * 2);
tx_buff = rt_malloc(message->length * 4);
if(!tx_buff)
{
goto transfer_done;
}
for(i = 0; i < message->length; i++)
{
tx_buff[i] = ((uint8_t *)message->send_buf)[i];
}
}
if(message->send_buf && message->recv_buf)
{
dmac_irq_register(bus->dma_recv_channel, dma_irq_callback, &bus->dma_completion, 1);
__spi_set_tmod(bus->spi_instance, SPI_TMOD_TRANS_RECV);
spi_instance[bus->spi_instance]->dmacr = 0x3;
spi_instance[bus->spi_instance]->ssienr = 0x01;
dmac_set_single_mode(bus->dma_recv_channel, (void *)(&spi_instance[bus->spi_instance]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, message->length);
dmac_set_single_mode(bus->dma_send_channel, tx_buff, (void *)(&spi_instance[bus->spi_instance]->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, message->length);
}
else if(message->send_buf)
{
dmac_irq_register(bus->dma_send_channel, dma_irq_callback, &bus->dma_completion, 1);
__spi_set_tmod(bus->spi_instance, SPI_TMOD_TRANS);
spi_instance[bus->spi_instance]->dmacr = 0x2;
spi_instance[bus->spi_instance]->ssienr = 0x01;
dmac_set_single_mode(bus->dma_send_channel, tx_buff, (void *)(&spi_instance[bus->spi_instance]->dr[0]), DMAC_ADDR_INCREMENT, DMAC_ADDR_NOCHANGE,
DMAC_MSIZE_4, DMAC_TRANS_WIDTH_32, message->length);
}
else if(message->recv_buf)
{
dmac_irq_register(bus->dma_recv_channel, dma_irq_callback, &bus->dma_completion, 1);
__spi_set_tmod(bus->spi_instance, SPI_TMOD_RECV);
spi_instance[bus->spi_instance]->ctrlr1 = message->length - 1;
spi_instance[bus->spi_instance]->dmacr = 0x1;
spi_instance[bus->spi_instance]->ssienr = 0x01;
spi_instance[bus->spi_instance]->dr[0] = 0xFF;
dmac_set_single_mode(bus->dma_recv_channel, (void *)(&spi_instance[bus->spi_instance]->dr[0]), rx_buff, DMAC_ADDR_NOCHANGE, DMAC_ADDR_INCREMENT,
DMAC_MSIZE_1, DMAC_TRANS_WIDTH_32, message->length);
}
else
{
goto transfer_done;
}
spi_instance[bus->spi_instance]->ser = 1U << cs->cs_index;
rt_completion_wait(&bus->dma_completion, RT_WAITING_FOREVER);
if(message->recv_buf)
dmac_irq_unregister(bus->dma_recv_channel);
else
dmac_irq_unregister(bus->dma_send_channel);
// wait until all data has been transmitted
while ((spi_instance[bus->spi_instance]->sr & 0x05) != 0x04)
;
spi_instance[bus->spi_instance]->ser = 0x00;
spi_instance[bus->spi_instance]->ssienr = 0x00;
if(message->recv_buf)
{
for(i = 0; i < message->length; i++)
{
((uint8_t *)message->recv_buf)[i] = (uint8_t)rx_buff[i];
}
}
transfer_done:
dmalock_release(bus->dma_send_channel);
dmalock_release(bus->dma_recv_channel);
if(tx_buff)
{
rt_free(tx_buff);
}
if(rx_buff)
{
rt_free(rx_buff);
}
}
if(message->cs_release)
{
gpiohs_set_pin(cs->cs_pin, GPIO_PV_HIGH);
}
return message->length;
}
const static struct rt_spi_ops drv_spi_ops =
{
drv_spi_configure,
drv_spi_xfer
};
int rt_hw_spi_init(void)
{
rt_err_t ret = RT_EOK;
#ifdef BSP_USING_SPI1
{
static struct drv_spi_bus spi_bus1;
spi_bus1.spi_instance = SPI_DEVICE_1;
ret = rt_spi_bus_register(&spi_bus1.parent, "spi1", &drv_spi_ops);
#ifdef BSP_SPI1_USING_SS0
{
static struct rt_spi_device spi_device10;
static struct drv_cs cs10 =
{
.cs_index = SPI_CHIP_SELECT_0,
.cs_pin = SPI1_CS0_PIN
};
rt_spi_bus_attach_device(&spi_device10, "spi10", "spi1", (void *)&cs10);
}
#endif
#ifdef BSP_SPI1_USING_SS1
{
static struct rt_spi_device spi_device11;
static struct drv_cs cs11 =
{
.cs_index = SPI_CHIP_SELECT_1,
.cs_pin = SPI1_CS1_PIN
};
rt_spi_bus_attach_device(&spi_device11, "spi11", "spi1", (void *)&cs11);
}
#endif
#ifdef BSP_SPI1_USING_SS2
{
static struct rt_spi_device spi_device12;
static struct drv_cs cs12 =
{
.cs_index = SPI_CHIP_SELECT_2,
.cs_pin = SPI1_CS2_PIN
};
rt_spi_bus_attach_device(&spi_device12, "spi12", "spi1", (void *)&cs12);
}
#endif
#ifdef BSP_SPI1_USING_SS3
{
static struct rt_spi_device spi_device13;
static struct drv_cs cs13 =
{
.cs_index = SPI_CHIP_SELECT_2,
.cs_pin = SPI1_CS2_PIN
};
rt_spi_bus_attach_device(&spi_device13, "spi13", "spi1", (void *)&cs13);
}
#endif
}
#endif
return ret;
}
INIT_DEVICE_EXPORT(rt_hw_spi_init);
#endif
@@ -0,0 +1,16 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-03-18 ZYH first version
*/
#ifndef DRV_SPI_H__
#define DRV_SPI_H__
int rt_hw_spi_init(void);
#endif
@@ -0,0 +1,11 @@
#include <rtthread.h>
#include <stdlib.h>
size_t get_free_heap_size(void)
{
rt_uint32_t total, used, max;
rt_memory_info(&total, &used, &max);
return total - used;
}
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2006-2018, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
*/
#include <rtthread.h>
#ifdef BSP_USING_SDCARD
#if defined(RT_USING_SPI_MSD) && defined(RT_USING_DFS_ELMFAT)
#include <spi_msd.h>
#include <dfs_fs.h>
#define DBG_TAG "sdcard"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
int sd_mount(void)
{
int ret = 0;
ret = msd_init("sd0", "spi10");
if(RT_EOK == ret)
{
if(dfs_mount("sd0", "/", "elm", 0, 0) == 0)
{
LOG_I("Mount /sd0 successfully");
return RT_EOK;
}
else
{
LOG_E("Mount fail !!1");
return -1;
}
}
LOG_E("msd_init fail !!!");
return -2;
}
INIT_ENV_EXPORT(sd_mount);
#endif
#endif