add ch438 driver and a demo

This commit is contained in:
Liu_Kai 2022-04-26 17:36:34 +08:00
parent a337904560
commit 9ac84e7cb4
7 changed files with 942 additions and 1 deletions

View File

@ -20,7 +20,7 @@
include $(TOPDIR)/Make.defs
CSRCS = imxrt_boot.c imxrt_flexspi_nor_boot.c imxrt_flexspi_nor_flash.c
CSRCS = imxrt_boot.c imxrt_flexspi_nor_boot.c imxrt_flexspi_nor_flash.c imxrt_ch438.c ch438_demo.c
ifeq ($(CONFIG_IMXRT_SDRAMC),y)
CSRCS += imxrt_sdram.c

View File

@ -0,0 +1,71 @@
/****************************************************************************
* apps/examples/sx127x_demo/sx127x_demo.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you 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 ch438_demo.c
* @brief nuttx source code
* https://github.com/apache/incubator-nuttx-apps
* @version 10.2.0
* @author AIIT XUOS Lab
* @date 2022-03-17
*/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <debug.h>
#include <poll.h>
#include <fcntl.h>
#include "imxrt_ch438.h"
#define TMP (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT3 | GPIO_PIN3)
void CH438Demo(void)
{
int i=0;
printf("ch438_main\n");
Ch438InitDefault();
ch438_irq_enable();
up_mdelay(1000);
while(1)
{
CH438UARTSend(2,"AT+BAUD=?",9);
printf("send success\n");
ImxrtCh438ReadData(NULL);
up_mdelay(2000);
}
}

View File

@ -0,0 +1,558 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <errno.h>
#include <nuttx/arch.h>
#include <nuttx/irq.h>
#include <arch/board/board.h>
#include "arm_arch.h"
#include "imxrt_config.h"
#include "imxrt_irq.h"
#include "imxrt_gpio.h"
#include "imxrt_ch438.h"
#include "xidatong.h"
#include <nuttx/pthread.h>
#include <nuttx/semaphore.h>
#include <nuttx/time.h>
#include <stddef.h>
#include <stdint.h>
static pthread_t thr_438;
struct sched_param param;
pthread_attr_t attr = PTHREAD_ATTR_INITIALIZER;
static char thr_438_stack[1024];
static sem_t sem_438; /* 用于接收的信号量 */
/* ch438中断回调函数 */
static int Ch438Irq(int irq, FAR void *context, FAR void *arg)
{
sem_post(&sem_438);
up_mdelay(500);
return OK;
}
void CH438SetOutput(void)
{
imxrt_config_gpio(CH438_D0_PIN_OUT);
imxrt_config_gpio(CH438_D1_PIN_OUT);
imxrt_config_gpio(CH438_D2_PIN_OUT);
imxrt_config_gpio(CH438_D3_PIN_OUT);
imxrt_config_gpio(CH438_D4_PIN_OUT);
imxrt_config_gpio(CH438_D5_PIN_OUT);
imxrt_config_gpio(CH438_D6_PIN_OUT);
imxrt_config_gpio(CH438_D7_PIN_OUT);
}
void CH438SetInput(void)
{
imxrt_config_gpio(CH438_D0_PIN_INPUT);
imxrt_config_gpio(CH438_D1_PIN_INPUT);
imxrt_config_gpio(CH438_D2_PIN_INPUT);
imxrt_config_gpio(CH438_D3_PIN_INPUT);
imxrt_config_gpio(CH438_D4_PIN_INPUT);
imxrt_config_gpio(CH438_D5_PIN_INPUT);
imxrt_config_gpio(CH438_D6_PIN_INPUT);
imxrt_config_gpio(CH438_D7_PIN_INPUT);
}
static uint8_t RevLen ,buff[8][128],buff_ptr[8];
static uint8_t Interruptnum[8] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,}; /* SSR寄存器中断号对应值 */
static uint8_t offsetadd[] = {0x00,0x10,0x20,0x30,0x08,0x18,0x28,0x38,}; /* 串口号的偏移地址 */
void* ImxrtCh438ReadData(void *parameter)
{
int result, i;
uint8_t gInterruptStatus;
uint8_t InterruptStatus;
uint8_t ext_uart_no;
static uint8_t dat;
uint8_t REG_LCR_ADDR;
uint8_t REG_DLL_ADDR;
uint8_t REG_DLM_ADDR;
uint8_t REG_IER_ADDR;
uint8_t REG_MCR_ADDR;
uint8_t REG_FCR_ADDR;
uint8_t REG_RBR_ADDR;
uint8_t REG_THR_ADDR;
uint8_t REG_IIR_ADDR;
uint8_t REG_LSR_ADDR;
uint8_t REG_MSR_ADDR;
// struct timespec abstime;
// abstime.tv_sec = 2;
// while (1)
// {
printf("sem_438 is %d\n",sem_438.semcount);
result = sem_wait(&sem_438);
if (result == OK)
{
gInterruptStatus = ReadCH438Data( REG_SSR_ADDR );
printf("gInterruptStatus is %d\n", gInterruptStatus);
if(!gInterruptStatus)
{
}
else
{
// for(ext_uart_no=0; ext_uart_no<8; ext_uart_no++)
// {
ext_uart_no = 2;
if( gInterruptStatus & Interruptnum[ext_uart_no] ) /* 检测哪个串口发生中断 */
{
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;
REG_LSR_ADDR = offsetadd[ext_uart_no] | REG_LSR0_ADDR;
REG_MSR_ADDR = offsetadd[ext_uart_no] | REG_MSR0_ADDR;
InterruptStatus = ReadCH438Data( REG_IIR_ADDR ) & 0x0f; /* 读串口的中断状态 */
printf("InterruptStatus is %d\n", InterruptStatus);
switch( InterruptStatus )
{
case INT_NOINT: /* 没有中断 */
break;
case INT_THR_EMPTY: /* THR空中断 */
// ReadCH438Data( REG_IIR_ADDR );
break;
case INT_RCV_OVERTIME: /* 接收超时中断,收到数据后一般是触发这个 。在收到一帧数据后4个数据时间没有后续的数据时触发*/
case INT_RCV_SUCCESS: /* 接收数据可用中断。这是一个数据帧超过缓存了才发生,否则一般是前面的超时中断。处理过程同上面的超时中断 */
RevLen = CH438UARTRcv(ext_uart_no, buff[ext_uart_no]);
for(i=0;i<RevLen;++i)
{
printf("%c(0x%x) ", buff[ext_uart_no][i], buff[ext_uart_no][i]);
}
for(i=0;i<128;i++)
buff[ext_uart_no][i] = 0;
buff_ptr[ext_uart_no] = 0;
break;
case INT_RCV_LINES: /* 接收线路状态中断 */
ReadCH438Data( REG_LSR_ADDR );
break;
case INT_MODEM_CHANGE: /* MODEM输入变化中断 */
ReadCH438Data( REG_MSR_ADDR );
break;
default:
// ReadCH438Data( REG_IIR_ADDR );
break;
}
}
// }
}
}
// }
}
void Ch438InitDefault(void)
{
int ret = 0;
sem_init(&sem_438, 0, 0);
printf("sem_438 init is %d\n",sem_438.semcount);
// attr.priority = 120;
// attr.stacksize = 8192;
// ret = pthread_create(&thr_438, &attr, &ImxrtCh438ReadData, NULL);
if (ret != 0){
printf("ImxrtCh438ReadData: task create failed, status=%d\n", ret);
}
ImxrtCH438Init();
CH438PortInit(0,115200);
CH438PortInit(1,115200);
CH438PortInit(2,9600);
CH438PortInit(3,9600);
CH438PortInit(4,115200);
CH438PortInit(5,115200);
CH438PortInit(6,115200);
CH438PortInit(7,115200);
up_mdelay(10);
imxrt_config_gpio(CH438_INT_PIN);
irq_attach(IMXRT_IRQ_GPIO3_3, Ch438Irq, NULL);
}
void ch438_irq_enable(void)
{
//重新对每个串口初始化
CH438PortInit(0,115200);
CH438PortInit(1,115200);
CH438PortInit(2,9600);
CH438PortInit(3,9600);
CH438PortInit(4,115200);
CH438PortInit(5,115200);
CH438PortInit(6,115200);
CH438PortInit(7,115200);
/* 使能中断 */
up_enable_irq(IMXRT_IRQ_GPIO3_3);
//以下代码测试用。用于enable时向所有串口发一串数据
up_mdelay(20);
CH438UARTSend(0,"#1234ABCD!",10);
CH438UARTSend(1,"#1234ABCD!",10);
CH438UARTSend(2,"#1234ABCD!",10);
CH438UARTSend(3,"#1234ABCD!",10);
CH438UARTSend(4,"#1234ABCD!",10);
CH438UARTSend(5,"#1234ABCD!",10);
CH438UARTSend(6,"#1234ABCD!",10);
CH438UARTSend(7,"#1234ABCD!",10);
up_mdelay(20);
}
static void ImxrtCH438Init(void)
{
uint8_t dat;
CH438SetOutput();
imxrt_config_gpio(CH438_NWR_PIN);
imxrt_config_gpio(CH438_NRD_PIN);
imxrt_config_gpio(CH438_ALE_PIN);
imxrt_gpio_write(CH438_NWR_PIN,true);
imxrt_gpio_write(CH438_NRD_PIN,true);
imxrt_gpio_write(CH438_ALE_PIN,true);
}
static void CH438PortInit( uint8_t ext_uart_no,uint32_t baud_rate )
{
uint32_t div;
uint8_t DLL,DLM,dlab;
uint8_t REG_LCR_ADDR;
uint8_t REG_DLL_ADDR;
uint8_t REG_DLM_ADDR;
uint8_t REG_IER_ADDR;
uint8_t REG_MCR_ADDR;
uint8_t REG_FCR_ADDR;
uint8_t REG_RBR_ADDR;
uint8_t REG_THR_ADDR;
uint8_t REG_IIR_ADDR;
uint8_t dat;
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 ); /* 复位该串口 */
up_mdelay(50);
// dat = ReadCH438Data(REG_FCR_ADDR);
// dat = ReadCH438Data(REG_LCR_ADDR);
dlab = ReadCH438Data(REG_IER_ADDR);
dlab &= 0xDF;
WriteCH438Data(REG_IER_ADDR, dlab);
// WriteCH438Data( REG_LCR_ADDR, BIT_LCR_DLAB ); /* 设置DLAB为1 */
dlab = ReadCH438Data(REG_LCR_ADDR);
dlab |= 0x80; //置LCR寄存器DLAB位为1
WriteCH438Data(REG_LCR_ADDR, dlab);
div = ( Fpclk >> 4 ) / baud_rate;
DLM = div >> 8;
DLL = div & 0xff;
WriteCH438Data( REG_DLL_ADDR, DLL ); /* 设置波特率 */
WriteCH438Data( REG_DLM_ADDR, DLM );
WriteCH438Data( REG_FCR_ADDR, BIT_FCR_RECVTG1 | BIT_FCR_RECVTG0 | BIT_FCR_FIFOEN ); /* 设置FIFO模式触发点为112字节 */
WriteCH438Data( REG_LCR_ADDR, BIT_LCR_WORDSZ1 | BIT_LCR_WORDSZ0 ); /* 字长8位1位停止位、无校验 */
// if(ext_uart_no==1)
// WriteCH438Data( REG_IER_ADDR, 0x00 ); /* 使能中断 */
// else
WriteCH438Data( REG_IER_ADDR, /*BIT_IER_IEMODEM | BIT_IER_IETHRE | BIT_IER_IELINES | */BIT_IER_IERECV ); /* 使能中断 */
WriteCH438Data( REG_MCR_ADDR, BIT_MCR_OUT2 );// | BIT_MCR_RTS | BIT_MCR_DTR ); /* 允许中断输出,DTR,RTS为1 */
WriteCH438Data(REG_FCR_ADDR,ReadCH438Data(REG_FCR_ADDR)| BIT_FCR_TFIFORST); /* 清空FIFO中的数据 */
}
/*********************************************************************************************************
** : ReadCH438Data
** : CH438地址读取数据
**  :
**
**  :
**
**  : 2011826
**-------------------------------------------------------------------------------------------------------
** :
**  :
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static uint8_t ReadCH438Data( uint8_t addr )
{
//读函数
//ALE WR RD线空闲都为高电平读取数据时候先将地址放在并口然后拉低ALE锁存地址延时保持
//切换引脚输入拉低RD读信号线延时等待读取并口上数据
//撤销RD撤销ALE
uint8_t dat;
// imxrt_gpio_write(CH438_NCS_PIN,true);
imxrt_gpio_write(CH438_NWR_PIN, true);
imxrt_gpio_write(CH438_NRD_PIN, true);
imxrt_gpio_write(CH438_ALE_PIN, true);
CH438SetOutput();
up_udelay(1);
if(addr &0x80) imxrt_gpio_write(CH438_D7_PIN_OUT, true); else imxrt_gpio_write(CH438_D7_PIN_OUT, false);
if(addr &0x40) imxrt_gpio_write(CH438_D6_PIN_OUT, true); else imxrt_gpio_write(CH438_D6_PIN_OUT, false);
if(addr &0x20) imxrt_gpio_write(CH438_D5_PIN_OUT, true); else imxrt_gpio_write(CH438_D5_PIN_OUT, false);
if(addr &0x10) imxrt_gpio_write(CH438_D4_PIN_OUT, true); else imxrt_gpio_write(CH438_D4_PIN_OUT, false);
if(addr &0x08) imxrt_gpio_write(CH438_D3_PIN_OUT, true); else imxrt_gpio_write(CH438_D3_PIN_OUT, false);
if(addr &0x04) imxrt_gpio_write(CH438_D2_PIN_OUT, true); else imxrt_gpio_write(CH438_D2_PIN_OUT, false);
if(addr &0x02) imxrt_gpio_write(CH438_D1_PIN_OUT, true); else imxrt_gpio_write(CH438_D1_PIN_OUT, false);
if(addr &0x01) imxrt_gpio_write(CH438_D0_PIN_OUT, true); else imxrt_gpio_write(CH438_D0_PIN_OUT, false);
up_udelay(1);
imxrt_gpio_write(CH438_ALE_PIN, false);
up_udelay(1);
CH438SetInput();
up_udelay(1);
imxrt_gpio_write(CH438_NRD_PIN, false);
up_udelay(1);
dat = 0;
if (imxrt_gpio_read(CH438_D7_PIN_INPUT)) dat |= 0x80;
if (imxrt_gpio_read(CH438_D6_PIN_INPUT)) dat |= 0x40;
if (imxrt_gpio_read(CH438_D5_PIN_INPUT)) dat |= 0x20;
if (imxrt_gpio_read(CH438_D4_PIN_INPUT)) dat |= 0x10;
if (imxrt_gpio_read(CH438_D3_PIN_INPUT)) dat |= 0x08;
if (imxrt_gpio_read(CH438_D2_PIN_INPUT)) dat |= 0x04;
if (imxrt_gpio_read(CH438_D1_PIN_INPUT)) dat |= 0x02;
if (imxrt_gpio_read(CH438_D0_PIN_INPUT)) dat |= 0x01;
imxrt_gpio_write(CH438_NRD_PIN, true);
imxrt_gpio_write(CH438_ALE_PIN, true);
up_udelay(1);
return dat;
}
static void WriteCH438Data( uint8_t addr, uint8_t dat)
{
imxrt_gpio_write(CH438_ALE_PIN, true);
imxrt_gpio_write(CH438_NRD_PIN, true);
imxrt_gpio_write(CH438_NWR_PIN, true);
CH438SetOutput();
up_udelay(1);
if(addr &0x80) imxrt_gpio_write(CH438_D7_PIN_OUT, true); else imxrt_gpio_write(CH438_D7_PIN_OUT, false);
if(addr &0x40) imxrt_gpio_write(CH438_D6_PIN_OUT, true); else imxrt_gpio_write(CH438_D6_PIN_OUT, false);
if(addr &0x20) imxrt_gpio_write(CH438_D5_PIN_OUT, true); else imxrt_gpio_write(CH438_D5_PIN_OUT, false);
if(addr &0x10) imxrt_gpio_write(CH438_D4_PIN_OUT, true); else imxrt_gpio_write(CH438_D4_PIN_OUT, false);
if(addr &0x08) imxrt_gpio_write(CH438_D3_PIN_OUT, true); else imxrt_gpio_write(CH438_D3_PIN_OUT, false);
if(addr &0x04) imxrt_gpio_write(CH438_D2_PIN_OUT, true); else imxrt_gpio_write(CH438_D2_PIN_OUT, false);
if(addr &0x02) imxrt_gpio_write(CH438_D1_PIN_OUT, true); else imxrt_gpio_write(CH438_D1_PIN_OUT, false);
if(addr &0x01) imxrt_gpio_write(CH438_D0_PIN_OUT, true); else imxrt_gpio_write(CH438_D0_PIN_OUT, false);
up_udelay(1);
imxrt_gpio_write(CH438_ALE_PIN, false);
up_udelay(1);
if(dat &0x80) imxrt_gpio_write(CH438_D7_PIN_OUT, true); else imxrt_gpio_write(CH438_D7_PIN_OUT, false);
if(dat &0x40) imxrt_gpio_write(CH438_D6_PIN_OUT, true); else imxrt_gpio_write(CH438_D6_PIN_OUT, false);
if(dat &0x20) imxrt_gpio_write(CH438_D5_PIN_OUT, true); else imxrt_gpio_write(CH438_D5_PIN_OUT, false);
if(dat &0x10) imxrt_gpio_write(CH438_D4_PIN_OUT, true); else imxrt_gpio_write(CH438_D4_PIN_OUT, false);
if(dat &0x08) imxrt_gpio_write(CH438_D3_PIN_OUT, true); else imxrt_gpio_write(CH438_D3_PIN_OUT, false);
if(dat &0x04) imxrt_gpio_write(CH438_D2_PIN_OUT, true); else imxrt_gpio_write(CH438_D2_PIN_OUT, false);
if(dat &0x02) imxrt_gpio_write(CH438_D1_PIN_OUT, true); else imxrt_gpio_write(CH438_D1_PIN_OUT, false);
if(dat &0x01) imxrt_gpio_write(CH438_D0_PIN_OUT, true); else imxrt_gpio_write(CH438_D0_PIN_OUT, false);
up_udelay(1);
imxrt_gpio_write(CH438_NWR_PIN, false);
up_udelay(1);
imxrt_gpio_write(CH438_NWR_PIN, true);
imxrt_gpio_write(CH438_ALE_PIN, true);
up_udelay(1);
CH438SetInput();
return;
}
/*********************************************************************************************************
** : WriteCH438Block
** : CH438地址写入数据块
**  : CH438寄存器地址,,
**
**  :
**
**  : 2011826
**-------------------------------------------------------------------------------------------------------
** :
**  :
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
static void WriteCH438Block( uint8_t mAddr, uint8_t mLen, uint8_t *mBuf )
{
while ( mLen -- )
WriteCH438Data( mAddr, *mBuf++ );
}
///*********************************************************************************************************
//** 函数名称: CH438UARTSend
//** 功能描述: 功能函数启用FIFO模式, 用于CH438串口0 发送多字节数据 单次最多发送128字节数据
//** 输 入: 发送数据缓冲区地址, 发送数据块长度
//**
//** 输 出: 无
//**
//** 日 期: 2011年8月26日
//**-------------------------------------------------------------------------------------------------------
//** 修改人:
//** 日 期:
//**-------------------------------------------------------------------------------------------------------
//********************************************************************************************************/
void CH438UARTSend( uint8_t ext_uart_no, uint8_t *Data, uint8_t Num )
{
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;
while( 1 )
{
while( ( ReadCH438Data( REG_LSR_ADDR ) & BIT_LSR_TEMT ) == 0 ); /* 等待数据发送完毕THR,TSR全空 */
if( Num <= 128 )
{
WriteCH438Block( REG_THR_ADDR, Num, Data );
break;
}
else
{
WriteCH438Block( REG_THR_ADDR, 128, Data );
Num -= 128;
Data += 128;
}
}
}
/*********************************************************************************************************
** : CH438UARTRcv
** : FIFO模式, CH438串口0
**  :
**
**  :
**
**  : 2011826
**-------------------------------------------------------------------------------------------------------
** :
**  :
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
uint8_t CH438UARTRcv( uint8_t ext_uart_no, uint8_t* buf )
{
uint8_t RcvNum = 0;
uint8_t dat = 0;
uint8_t REG_LSR_ADDR,REG_RBR_ADDR;
uint8_t *p_rev;
p_rev = buf;
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_BREAKINT | BIT_LSR_FRAMEERR | BIT_LSR_PARERR | BIT_LSR_OVERR ) ) ) /* b1-b4无错误 */
// if( !( dat & ( BIT_LSR_BREAKINT | BIT_LSR_FRAMEERR | BIT_LSR_PARERR | BIT_LSR_OVERR ) ) ) /* b1-b4无错误 */ 不用管这有没有错误,只管 DATAREADY
{
while( ( ReadCH438Data( REG_LSR_ADDR ) & BIT_LSR_DATARDY ) == 0 ); /* 等待数据准备好 */
while( ( ReadCH438Data( REG_LSR_ADDR ) & BIT_LSR_DATARDY ) == 0x01 )
{
// *buf++ = ReadCH438Data( REG_RBR_ADDR ); /* 从接收缓冲寄存器读出数据 */
dat = ReadCH438Data( REG_RBR_ADDR );
buff[ext_uart_no][buff_ptr[ext_uart_no]] = dat;
buff_ptr[ext_uart_no] = buff_ptr[ext_uart_no] + 1;
if (buff_ptr[ext_uart_no] == 128)
buff_ptr[ext_uart_no] = 0;
RcvNum = RcvNum + 1;
}
}
// else ReadCH438Data( REG_RBR_ADDR );
return( RcvNum );
}

View File

@ -0,0 +1,297 @@
#ifndef __QC_TEST_CH438__
#define __QC_TEST_CH438__
#include "xidatong.h"
/******************************************************************************************/
/* 芯片定义 */
/* CH438串口0寄存器地址 */
#define REG_RBR0_ADDR 0x00 /* 串口0接收缓冲寄存器地址 */
#define REG_THR0_ADDR 0x00 /* 串口0发送保持寄存器地址 */
#define REG_IER0_ADDR 0x01 /* 串口0中断使能寄存器地址 */
#define REG_IIR0_ADDR 0x02 /* 串口0中断识别寄存器地址 */
#define REG_FCR0_ADDR 0x02 /* 串口0FIFO控制寄存器地址 */
#define REG_LCR0_ADDR 0x03 /* 串口0线路控制寄存器地址 */
#define REG_MCR0_ADDR 0x04 /* 串口0MODEM控制寄存器地址 */
#define REG_LSR0_ADDR 0x05 /* 串口0线路状态寄存器地址 */
#define REG_MSR0_ADDR 0x06 /* 串口0MODEM状态寄存器地址 */
#define REG_SCR0_ADDR 0x07 /* 串口0用户可定义寄存器地址 */
#define REG_DLL0_ADDR 0x00 /* 波特率除数锁存器低8位字节地址 */
#define REG_DLM0_ADDR 0x01 /* 波特率除数锁存器高8位字节地址 */
/* CH438串口1寄存器地址 */
#define REG_RBR1_ADDR 0x10 /* 串口1接收缓冲寄存器地址 */
#define REG_THR1_ADDR 0x10 /* 串口1发送保持寄存器地址 */
#define REG_IER1_ADDR 0x11 /* 串口1中断使能寄存器地址 */
#define REG_IIR1_ADDR 0x12 /* 串口1中断识别寄存器地址 */
#define REG_FCR1_ADDR 0x12 /* 串口1FIFO控制寄存器地址 */
#define REG_LCR1_ADDR 0x13 /* 串口1线路控制寄存器地址 */
#define REG_MCR1_ADDR 0x14 /* 串口1MODEM控制寄存器地址 */
#define REG_LSR1_ADDR 0x15 /* 串口1线路状态寄存器地址 */
#define REG_MSR1_ADDR 0x16 /* 串口1MODEM状态寄存器地址 */
#define REG_SCR1_ADDR 0x17 /* 串口1用户可定义寄存器地址 */
#define REG_DLL1_ADDR 0x10 /* 波特率除数锁存器低8位字节地址 */
#define REG_DLM1_ADDR 0x11 /* 波特率除数锁存器高8位字节地址 */
/* CH438串口2寄存器地址 */
#define REG_RBR2_ADDR 0x20 /* 串口2接收缓冲寄存器地址 */
#define REG_THR2_ADDR 0x20 /* 串口2发送保持寄存器地址 */
#define REG_IER2_ADDR 0x21 /* 串口2中断使能寄存器地址 */
#define REG_IIR2_ADDR 0x22 /* 串口2中断识别寄存器地址 */
#define REG_FCR2_ADDR 0x22 /* 串口2FIFO控制寄存器地址 */
#define REG_LCR2_ADDR 0x23 /* 串口2线路控制寄存器地址 */
#define REG_MCR2_ADDR 0x24 /* 串口2MODEM控制寄存器地址 */
#define REG_LSR2_ADDR 0x25 /* 串口2线路状态寄存器地址 */
#define REG_MSR2_ADDR 0x26 /* 串口2MODEM状态寄存器地址 */
#define REG_SCR2_ADDR 0x27 /* 串口2用户可定义寄存器地址 */
#define REG_DLL2_ADDR 0x20 /* 波特率除数锁存器低8位字节地址 */
#define REG_DLM2_ADDR 0x21 /* 波特率除数锁存器高8位字节地址 */
/* CH438串口3寄存器地址 */
#define REG_RBR3_ADDR 0x30 /* 串口3接收缓冲寄存器地址 */
#define REG_THR3_ADDR 0x30 /* 串口3发送保持寄存器地址 */
#define REG_IER3_ADDR 0x31 /* 串口3中断使能寄存器地址 */
#define REG_IIR3_ADDR 0x32 /* 串口3中断识别寄存器地址 */
#define REG_FCR3_ADDR 0x32 /* 串口3FIFO控制寄存器地址 */
#define REG_LCR3_ADDR 0x33 /* 串口3线路控制寄存器地址 */
#define REG_MCR3_ADDR 0x34 /* 串口3MODEM控制寄存器地址 */
#define REG_LSR3_ADDR 0x35 /* 串口3线路状态寄存器地址 */
#define REG_MSR3_ADDR 0x36 /* 串口3MODEM状态寄存器地址 */
#define REG_SCR3_ADDR 0x37 /* 串口3用户可定义寄存器地址 */
#define REG_DLL3_ADDR 0x30 /* 波特率除数锁存器低8位字节地址 */
#define REG_DLM3_ADDR 0x31 /* 波特率除数锁存器高8位字节地址 */
/* CH438串口4寄存器地址 */
#define REG_RBR4_ADDR 0x08 /* 串口4接收缓冲寄存器地址 */
#define REG_THR4_ADDR 0x08 /* 串口4发送保持寄存器地址 */
#define REG_IER4_ADDR 0x09 /* 串口4中断使能寄存器地址 */
#define REG_IIR4_ADDR 0x0A /* 串口4中断识别寄存器地址 */
#define REG_FCR4_ADDR 0x0A /* 串口4FIFO控制寄存器地址 */
#define REG_LCR4_ADDR 0x0B /* 串口4线路控制寄存器地址 */
#define REG_MCR4_ADDR 0x0C /* 串口4MODEM控制寄存器地址 */
#define REG_LSR4_ADDR 0x0D /* 串口4线路状态寄存器地址 */
#define REG_MSR4_ADDR 0x0E /* 串口4MODEM状态寄存器地址 */
#define REG_SCR4_ADDR 0x0F /* 串口4用户可定义寄存器地址 */
#define REG_DLL4_ADDR 0x08 /* 波特率除数锁存器低8位字节地址 */
#define REG_DLM4_ADDR 0x09 /* 波特率除数锁存器高8位字节地址 */
/* CH438串口5寄存器地址 */
#define REG_RBR5_ADDR 0x18 /* 串口5接收缓冲寄存器地址 */
#define REG_THR5_ADDR 0x18 /* 串口5发送保持寄存器地址 */
#define REG_IER5_ADDR 0x19 /* 串口5中断使能寄存器地址 */
#define REG_IIR5_ADDR 0x1A /* 串口5中断识别寄存器地址 */
#define REG_FCR5_ADDR 0x1A /* 串口5FIFO控制寄存器地址 */
#define REG_LCR5_ADDR 0x1B /* 串口5线路控制寄存器地址 */
#define REG_MCR5_ADDR 0x1C /* 串口5MODEM控制寄存器地址 */
#define REG_LSR5_ADDR 0x1D /* 串口5线路状态寄存器地址 */
#define REG_MSR5_ADDR 0x1E /* 串口5MODEM状态寄存器地址 */
#define REG_SCR5_ADDR 0x1F /* 串口5用户可定义寄存器地址 */
#define REG_DLL5_ADDR 0x18 /* 波特率除数锁存器低8位字节地址 */
#define REG_DLM5_ADDR 0x19 /* 波特率除数锁存器高8位字节地址 */
/* CH438串口6寄存器地址 */
#define REG_RBR6_ADDR 0x28 /* 串口6接收缓冲寄存器地址 */
#define REG_THR6_ADDR 0x28 /* 串口6发送保持寄存器地址 */
#define REG_IER6_ADDR 0x29 /* 串口6中断使能寄存器地址 */
#define REG_IIR6_ADDR 0x2A /* 串口6中断识别寄存器地址 */
#define REG_FCR6_ADDR 0x2A /* 串口6FIFO控制寄存器地址 */
#define REG_LCR6_ADDR 0x2B /* 串口6线路控制寄存器地址 */
#define REG_MCR6_ADDR 0x2C /* 串口6MODEM控制寄存器地址 */
#define REG_LSR6_ADDR 0x2D /* 串口6线路状态寄存器地址 */
#define REG_MSR6_ADDR 0x2E /* 串口6MODEM状态寄存器地址 */
#define REG_SCR6_ADDR 0x2F /* 串口6用户可定义寄存器地址 */
#define REG_DLL6_ADDR 0x28 /* 波特率除数锁存器低8位字节地址 */
#define REG_DLM6_ADDR 0x29 /* 波特率除数锁存器高8位字节地址 */
/* CH438串口7寄存器地址 */
#define REG_RBR7_ADDR 0x38 /* 串口7接收缓冲寄存器地址 */
#define REG_THR7_ADDR 0x38 /* 串口7发送保持寄存器地址 */
#define REG_IER7_ADDR 0x39 /* 串口7中断使能寄存器地址 */
#define REG_IIR7_ADDR 0x3A /* 串口7中断识别寄存器地址 */
#define REG_FCR7_ADDR 0x3A /* 串口7FIFO控制寄存器地址 */
#define REG_LCR7_ADDR 0x3B /* 串口7线路控制寄存器地址 */
#define REG_MCR7_ADDR 0x3C /* 串口7MODEM控制寄存器地址 */
#define REG_LSR7_ADDR 0x3D /* 串口7线路状态寄存器地址 */
#define REG_MSR7_ADDR 0x3E /* 串口7MODEM状态寄存器地址 */
#define REG_SCR7_ADDR 0x3F /* 串口7用户可定义寄存器地址 */
#define REG_DLL7_ADDR 0x38 /* 波特率除数锁存器低8位字节地址 */
#define REG_DLM7_ADDR 0x39 /* 波特率除数锁存器高8位字节地址 */
/* CH438内部串口0~7 专用状态寄存器 */
#define REG_SSR_ADDR 0x4F /* 专用状态寄存器地址 */
/* IER寄存器的位 */
#define BIT_IER_RESET 0x80 /* 该位置1则软复位该串口 */
#define BIT_IER_LOWPOWER 0x40 /* 该位为1则关闭该串口的内部基准时钟 */
#define BIT_IER_SLP 0x20 /* 串口0是SLP,为1则关闭时钟震荡器 */
#define BIT_IER1_CK2X 0x20 /* 串口1是CK2X,为1则强制将外部时钟信号2倍频后作为内部基准时钟 */
#define BIT_IER_IEMODEM 0x08 /* 该位为1允许MODEM输入状态变化中断 */
#define BIT_IER_IELINES 0x04 /* 该位为1允许接收线路状态中断 */
#define BIT_IER_IETHRE 0x02 /* 该位为1允许发送保持寄存器空中断 */
#define BIT_IER_IERECV 0x01 /* 该位为1允许接收到数据中断 */
/* IIR寄存器的位 */
#define BIT_IIR_FIFOENS1 0x80
#define BIT_IIR_FIFOENS0 0x40 /* 该2位为1表示起用FIFO */
/* 中断类型0001没有中断0110接收线路状态中断0100接收数据可用中断
11000010THR寄存器空中断0000MODEM输入变化中断 */
#define BIT_IIR_IID3 0x08
#define BIT_IIR_IID2 0x04
#define BIT_IIR_IID1 0x02
#define BIT_IIR_NOINT 0x01
/* FCR寄存器的位 */
/* 触发点: 00对应1个字节01对应16个字节10对应64个字节11对应112个字节 */
#define BIT_FCR_RECVTG1 0x80 /* 设置FIFO的中断和自动硬件流控制的触发点 */
#define BIT_FCR_RECVTG0 0x40 /* 设置FIFO的中断和自动硬件流控制的触发点 */
#define BIT_FCR_TFIFORST 0x04 /* 该位置1则清空发送FIFO中的数据 */
#define BIT_FCR_RFIFORST 0x02 /* 该位置1则清空接收FIFO中的数据 */
#define BIT_FCR_FIFOEN 0x01 /* 该位置1则起用FIFO,为0则禁用FIFO */
/* LCR寄存器的位 */
#define BIT_LCR_DLAB 0x80 /* 为1才能存取DLLDLM为0才能存取RBR/THR/IER */
#define BIT_LCR_BREAKEN 0x40 /* 为1则强制产生BREAK线路间隔*/
/* 设置校验格式当PAREN为1时00奇校验01偶校验10标志位MARK置1)11空白位SPACE清0) */
#define BIT_LCR_PARMODE1 0x20 /* 设置奇偶校验位格式 */
#define BIT_LCR_PARMODE0 0x10 /* 设置奇偶校验位格式 */
#define BIT_LCR_PAREN 0x08 /* 为1则允许发送时产生和接收校验奇偶校验位 */
#define BIT_LCR_STOPBIT 0x04 /* 为1则两个停止位,为0一个停止位 */
/* 设置字长度00则5个数据位01则6个数据位10则7个数据位11则8个数据位 */
#define BIT_LCR_WORDSZ1 0x02 /* 设置字长长度 */
#define BIT_LCR_WORDSZ0 0x01
/* MCR寄存器的位 */
#define BIT_MCR_AFE 0x20 /* 为1允许CTS和RTS硬件自动流控制 */
#define BIT_MCR_LOOP 0x10 /* 为1使能内部回路的测试模式 */
#define BIT_MCR_OUT2 0x08 /* 为1允许该串口的中断请求输出 */
#define BIT_MCR_OUT1 0x04 /* 为用户定义的MODEM控制位 */
#define BIT_MCR_RTS 0x02 /* 该位为1则RTS引脚输出有效 */
#define BIT_MCR_DTR 0x01 /* 该位为1则DTR引脚输出有效 */
/* LSR寄存器的位 */
#define BIT_LSR_RFIFOERR 0x80 /* 为1表示在接收FIFO中存在至少一个错误 */
#define BIT_LSR_TEMT 0x40 /* 为1表示THR和TSR全空 */
#define BIT_LSR_THRE 0x20 /* 为1表示THR空*/
#define BIT_LSR_BREAKINT 0x10 /* 该位为1表示检测到BREAK线路间隔 */
#define BIT_LSR_FRAMEERR 0x08 /* 该位为1表示读取数据帧错误 */
#define BIT_LSR_PARERR 0x04 /* 该位为1表示奇偶校验错误 */
#define BIT_LSR_OVERR 0x02 /* 为1表示接收FIFO缓冲区溢出 */
#define BIT_LSR_DATARDY 0x01 /* 该位为1表示接收FIFO中有接收到的数据 */
/* MSR寄存器的位 */
#define BIT_MSR_DCD 0x80 /* 该位为1表示DCD引脚有效 */
#define BIT_MSR_RI 0x40 /* 该位为1表示RI引脚有效 */
#define BIT_MSR_DSR 0x20 /* 该位为1表示DSR引脚有效 */
#define BIT_MSR_CTS 0x10 /* 该位为1表示CTS引脚有效 */
#define BIT_MSR_DDCD 0x08 /* 该位为1表示DCD引脚输入状态发生变化过 */
#define BIT_MSR_TERI 0x04 /* 该位为1表示RI引脚输入状态发生变化过 */
#define BIT_MSR_DDSR 0x02 /* 该位为1表示DSR引脚输入状态发生变化过 */
#define BIT_MSR_DCTS 0x01 /* 该位为1表示CTS引脚输入状态发生变化过 */
/* 中断状态码 */
#define INT_NOINT 0x01 /* 没有中断 */
#define INT_THR_EMPTY 0x02 /* THR空中断 */
#define INT_RCV_OVERTIME 0x0C /* 接收超时中断 */
#define INT_RCV_SUCCESS 0x04 /* 接收数据可用中断 */
#define INT_RCV_LINES 0x06 /* 接收线路状态中断 */
#define INT_MODEM_CHANGE 0x00 /* MODEM输入变化中断 */
#define CH438_IIR_FIFOS_ENABLED 0xC0 /* 起用FIFO */
#define Fpclk 1843200 /* 定义内部时钟频率 */
// #define IOMUX_CH438OUT_DEFAULT
#define CH438_D0_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT1 | GPIO_PIN25)
#define CH438_D1_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT1 | GPIO_PIN24)
#define CH438_D2_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT1 | GPIO_PIN20)
#define CH438_D3_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT1 | GPIO_PIN21)
#define CH438_D4_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT1 | GPIO_PIN31)
#define CH438_D5_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT1 | GPIO_PIN28)
#define CH438_D6_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT1 | GPIO_PIN30)
#define CH438_D7_PIN_OUT (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT1 | GPIO_PIN29)
#define CH438_NWR_PIN (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT3 | GPIO_PIN4)
#define CH438_NRD_PIN (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT3 | GPIO_PIN5)
#define CH438_ALE_PIN (GPIO_OUTPUT | IOMUX_GOUT_DEFAULT | \
GPIO_PORT3 | GPIO_PIN2)
#define CH438_INT_PIN (GPIO_INTERRUPT | GPIO_INT_FALLINGEDGE | IOMUX_SW_DEFAULT | \
GPIO_PORT3 | GPIO_PIN3)
#define CH438_D0_PIN_INPUT (GPIO_INPUT | \
GPIO_PORT1 | GPIO_PIN25)
#define CH438_D1_PIN_INPUT (GPIO_INPUT | \
GPIO_PORT1 | GPIO_PIN24)
#define CH438_D2_PIN_INPUT (GPIO_INPUT | \
GPIO_PORT1 | GPIO_PIN20)
#define CH438_D3_PIN_INPUT (GPIO_INPUT | \
GPIO_PORT1 | GPIO_PIN21)
#define CH438_D4_PIN_INPUT (GPIO_INPUT | \
GPIO_PORT1 | GPIO_PIN31)
#define CH438_D5_PIN_INPUT (GPIO_INPUT | \
GPIO_PORT1 | GPIO_PIN28)
#define CH438_D6_PIN_INPUT (GPIO_INPUT | \
GPIO_PORT1 | GPIO_PIN30)
#define CH438_D7_PIN_INPUT (GPIO_INPUT | \
GPIO_PORT1 | GPIO_PIN29)
static void ImxrtCH438Init(void);
static void CH438PortInit( uint8_t ext_uart_no,uint32_t baud_rate );
static void CH438SetOutput(void);
static void CH438SetInput(void);
static uint8_t ReadCH438Data( uint8_t addr );
static void WriteCH438Data( uint8_t addr, uint8_t dat);
static void WriteCH438Block( uint8_t mAddr, uint8_t mLen, uint8_t *mBuf ) ;
void CH438UARTSend( uint8_t ext_uart_no,uint8_t *Data, uint8_t Num );
static uint8_t CH438UARTRcv( uint8_t ext_uart_no, uint8_t* buf );
void Ch438InitDefault(void);
void ch438_irq_enable(void);
void *ImxrtCh438ReadData(void *parameter);
#endif

View File

@ -1417,6 +1417,8 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb,
FAR void *arg);
#endif
int cmd_Ch438(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#if defined(CONFIG_APPLICATION_SENSOR_HCHO_TB600B_WQ_HCHO1OS) && !defined(CONFIG_NSH_DISABLE_HCHO_TB600B_WQ_HCHO1OS)
int cmd_Hcho1os(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
#endif

View File

@ -38,6 +38,17 @@
extern int FrameworkInit(void);
extern void CH438Demo(void);
int cmd_Ch438(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
nsh_output(vtbl, "Hello, world!\n");
FrameworkInit();
CH438Demo();
return OK;
}
/****************************************************************************
* Name: cmd_Hcho1os
****************************************************************************/

View File

@ -590,6 +590,8 @@ static const struct cmdmap_s g_cmdmap[] =
{ "xd", cmd_xd, 3, 3, "<hex-address> <byte-count>" },
#endif
{ "ch438", cmd_Ch438, 1, 1, "[get the concentration of formaldehyde with sensor tb600b_wq_hcho1os.]" },
#if defined(CONFIG_APPLICATION_SENSOR_HCHO_TB600B_WQ_HCHO1OS) && !defined(CONFIG_NSH_DISABLE_HCHO_TB600B_WQ_HCHO1OS)
{ "hcho1os", cmd_Hcho1os, 1, 1, "[get the concentration of formaldehyde with sensor tb600b_wq_hcho1os.]" },
#endif