fixed merge fault

This commit is contained in:
wlyu 2022-01-30 23:39:16 +08:00
commit 521dc56e15
90 changed files with 15039 additions and 482 deletions

View File

@ -28,6 +28,8 @@
* Definitions
******************************************************************************/
#define TCP_DEMO_BUF_SIZE 65535
/*******************************************************************************
* Prototypes
******************************************************************************/
@ -38,8 +40,6 @@
char tcp_socket_ip[] = {192, 168, 250, 252};
#define TCP_DEMO_BUF_SIZE 65535
/*******************************************************************************
* Code
******************************************************************************/
@ -80,7 +80,7 @@ static void tcp_recv_demo(void *arg)
}
lw_print("tcp bind success, start to receive.\n");
lw_print("\n\nLocal Port:%d\n\n", LWIP_LOCAL_PORT);
lw_pr_info("\n\nLocal Port:%d\n\n", LWIP_LOCAL_PORT);
// setup socket fd as listening mode
if (listen(fd, 5) != 0 )
@ -91,7 +91,7 @@ static void tcp_recv_demo(void *arg)
// accept client connection
clientfd = accept(fd, (struct sockaddr *)&tcp_addr, (socklen_t*)&addr_len);
lw_print("client %s connected\n", inet_ntoa(tcp_addr.sin_addr));
lw_pr_info("client %s connected\n", inet_ntoa(tcp_addr.sin_addr));
while(1)
{
@ -163,7 +163,7 @@ static void tcp_send_demo(void *arg)
}
lw_print("tcp connect success, start to send.\n");
lw_pr_info("\n\nTarget Port:%d\n\n", tcp_sock.sin_port);
lw_pr_info("\n\nTarget Port:%d\n\n", LWIP_TARGET_PORT);
while (cnt --)
{

View File

@ -23,11 +23,15 @@
#include "sys_arch.h"
#include "lwip/udp.h"
#include "lwip/opt.h"
#include <lwip/sockets.h>
#include "lwip/sys.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define UDP_BUF_SIZE 65536
/*******************************************************************************
* Prototypes
******************************************************************************/
@ -35,6 +39,7 @@
/*******************************************************************************
* Variables
******************************************************************************/
extern char udp_target[];
static struct udp_pcb *udpecho_raw_pcb;
char udp_socket_ip[] = {192, 168, 250, 252};
@ -42,14 +47,6 @@ char udp_socket_ip[] = {192, 168, 250, 252};
/*******************************************************************************
* Code
******************************************************************************/
#include <lwip/sockets.h>
#include "lwip/sys.h"
#define LWIP_UDP_TASK_STACK 4096
#define LWIP_UDP_TASK_PRIO 25
#define UDP_BUF_SIZE 1024
static void udp_recv_demo(void *arg)
{
lw_print("udp_recv_demo start.\n");
@ -63,14 +60,14 @@ static void udp_recv_demo(void *arg)
while(1)
{
recv_buf = (char *)malloc(UDP_BUF_SIZE);
if (recv_buf == NULL)
if(recv_buf == NULL)
{
lw_print("No memory\n");
goto __exit;
}
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0)
if(socket_fd < 0)
{
lw_print("Socket error\n");
goto __exit;
@ -81,7 +78,7 @@ static void udp_recv_demo(void *arg)
udp_addr.sin_port = htons(LWIP_LOCAL_PORT);
memset(&(udp_addr.sin_zero), 0, sizeof(udp_addr.sin_zero));
if (bind(socket_fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1)
if(bind(socket_fd, (struct sockaddr *)&udp_addr, sizeof(struct sockaddr)) == -1)
{
lw_print("Unable to bind\n");
goto __exit;
@ -94,27 +91,24 @@ static void udp_recv_demo(void *arg)
{
memset(recv_buf, 0, UDP_BUF_SIZE);
recv_len = recvfrom(socket_fd, recv_buf, UDP_BUF_SIZE, 0, (struct sockaddr *)&server_addr, &addr_len);
lw_print("Receive from : %s\n", inet_ntoa(server_addr.sin_addr));
lw_print("Receive data : %s\n\n", recv_buf);
lw_pr_info("Receive from : %s\n", inet_ntoa(server_addr.sin_addr));
lw_pr_info("Receive data : %s\n\n", recv_buf);
sendto(socket_fd, recv_buf, recv_len, 0, (struct sockaddr*)&server_addr, addr_len);
}
__exit:
if (socket_fd >= 0)
if(socket_fd >= 0)
{
closesocket(socket_fd);
}
if (recv_buf)
if(recv_buf)
{
free(recv_buf);
}
}
}
static void udp_recv_demo_thread(void* param)
{
ETH_BSP_Config();
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
sys_thread_new("udp_recv_demo", udp_recv_demo, NULL, LWIP_UDP_TASK_STACK, LWIP_UDP_TASK_PRIO);
}
void udp_socket_recv_run(int argc, char *argv[])
{
int result = 0;
@ -127,7 +121,9 @@ void udp_socket_recv_run(int argc, char *argv[])
sscanf(argv[1], "%d.%d.%d.%d", &udp_socket_ip[0], &udp_socket_ip[1], &udp_socket_ip[2], &udp_socket_ip[3]);
}
sys_thread_new("udp socket send", udp_recv_demo_thread, NULL, 4096, 15);
ETH_BSP_Config();
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
sys_thread_new("udp_recv_demo", udp_recv_demo, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
@ -144,7 +140,7 @@ static void udp_send_demo(void *arg)
memset(send_str, 0, sizeof(send_str));
socket_fd = socket(AF_INET, SOCK_DGRAM, 0);
if (socket_fd < 0)
if(socket_fd < 0)
{
lw_print("Socket error\n");
goto __exit;
@ -153,10 +149,10 @@ static void udp_send_demo(void *arg)
struct sockaddr_in udp_sock;
udp_sock.sin_family = AF_INET;
udp_sock.sin_port = htons(LWIP_TARGET_PORT);
udp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(udp_target[0],udp_target[1],udp_target[2],udp_target[3]));
udp_sock.sin_addr.s_addr = PP_HTONL(LWIP_MAKEU32(udp_target[0], udp_target[1], udp_target[2], udp_target[3]));
memset(&(udp_sock.sin_zero), 0, sizeof(udp_sock.sin_zero));
if (connect(socket_fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)))
if(connect(socket_fd, (struct sockaddr *)&udp_sock, sizeof(struct sockaddr)))
{
lw_print("Unable to connect\n");
goto __exit;
@ -174,7 +170,7 @@ static void udp_send_demo(void *arg)
}
__exit:
if (socket_fd >= 0)
if(socket_fd >= 0)
{
closesocket(socket_fd);
}
@ -182,13 +178,6 @@ __exit:
return;
}
static void udp_send_demo_thread(void* param)
{
ETH_BSP_Config();
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
sys_thread_new("udp_send_demo", udp_send_demo, NULL, LWIP_UDP_TASK_STACK, LWIP_UDP_TASK_PRIO);
}
void udp_socket_send_run(int argc, char *argv[])
{
int result = 0;
@ -201,7 +190,9 @@ void udp_socket_send_run(int argc, char *argv[])
sscanf(argv[1], "%d.%d.%d.%d", &udp_socket_ip[0], &udp_socket_ip[1], &udp_socket_ip[2], &udp_socket_ip[3]);
}
sys_thread_new("udp socket send", udp_send_demo_thread, NULL, 4096, 15);
ETH_BSP_Config();
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
sys_thread_new("udp_send_demo", udp_send_demo, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),

View File

@ -31,6 +31,8 @@
#define TCP_LOCAL_PORT 4840
#define UA_URL_SIZE 100
#define UA_STACK_SIZE 4096
#define UA_TASK_PRIO 25
/*******************************************************************************
* Prototypes
@ -91,7 +93,7 @@ void test_sh_ua_connect(void)
int result = 0;
pthread_t th_id;
pthread_attr_t attr;
sys_thread_new("ua test", test_ua_connect_thr, NULL, 4096, 15);
sys_thread_new("ua test", test_ua_connect_thr, NULL, UA_STACK_SIZE, UA_TASK_PRIO);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
@ -148,7 +150,7 @@ void *test_sh_ua_brower_objects(int argc, char *argv[])
ETH_BSP_Config();
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
sys_thread_new("ua object", test_ua_browser_objects, NULL, 4096, 15);
sys_thread_new("ua object", test_ua_browser_objects, NULL, UA_STACK_SIZE, UA_TASK_PRIO);
return NULL;
}
@ -202,7 +204,7 @@ void *test_sh_ua_get_info(int argc, char *argv[])
ETH_BSP_Config();
lwip_config_tcp(lwip_ipaddr, lwip_netmask, test_ua_ip);
sys_thread_new("ua object", test_ua_get_info, NULL, 4096, 15);
sys_thread_new("ua object", test_ua_browser_objects, NULL, UA_STACK_SIZE, UA_TASK_PRIO);
return NULL;
}

View File

@ -18,14 +18,20 @@
* @date 2021.12.15
*/
#include "open62541.h"
#include "ua_api.h"
#include "plc.h"
#include "plc_bus.h"
#include "plc_dev.h"
#define PLC_BUS_NAME "plc bus"
#define PLC_DRV_NAME "plc driver"
struct PlcDevice plc_device;
struct PlcBus plc_bus;
struct PlcDriver plc_drv;
static DoubleLinklistType plcdev_list;
@ -183,3 +189,17 @@ int PlcDeviceAttachToBus(const char *dev_name, const char *bus_name)
return EOK;
}
void PlcTestInit(void)
{
PlcBusInit(&plc_bus, PLC_BUS_NAME);
PlcDriverInit(&plc_drv, PLC_DRV_NAME);
}
void test_plc_bus(int argc, char *argv[])
{
PlcTestInit();
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
plc, test_plc_bus, test PLC);

View File

@ -15,9 +15,12 @@
* @brief plc relative definition and structure
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.12.15
* @date 2022-01-24
*/
#ifndef __PLC_H_
#define __PLC_H_
#include "bus.h"
#include "xs_klist.h"
@ -78,7 +81,7 @@ enum PlcCtlType {
enum PlcIndHybridNet
{
//PLC Field Bus
// PLC Field Bus
PLC_IND_FIELD_MODBUS_485,
PLC_IND_FIELD_PROFIBUS,
PLC_IND_FIELD_CANOPEN,
@ -92,7 +95,7 @@ enum PlcIndHybridNet
PLC_IND_ENET_SERCOS,
PLC_IND_ENET_OPCUA,
//PLC wireless net
// PLC wireless net
PLC_IND_WIRELESS
};
@ -112,7 +115,7 @@ struct PlcInterface
// identify PLC device
struct PlcDevice {
char name[PLC_NAME_SIZE]; /* name of the device */
char name[PLC_NAME_SIZE]; /* name of the device */
enum PlcCtlType type; /* PLC Control Type */
enum DevState state;
enum PlcIndHybridNet net;
@ -125,3 +128,4 @@ struct PlcDevice {
DoubleLinklistType link;/* link list node */
};
#endif

View File

@ -11,11 +11,11 @@
*/
/**
* @file plc_bus.c
* @file bus_plc.c
* @brief register plc bus function using bus driver framework
* @version 1.0
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
* @date 2022-01-24
*/
#include "plc_bus.h"
@ -30,7 +30,6 @@ int PlcBusInit(struct PlcBus *plc_bus, const char *bus_name)
if (BUS_INSTALL != plc_bus->bus.bus_state) {
strncpy(plc_bus->bus.bus_name, bus_name, NAME_NUM_MAX);
plc_bus->bus.bus_type = TYPE_PLC_BUS;
plc_bus->bus.bus_state = BUS_INSTALL;
plc_bus->bus.private_data = plc_bus->private_data;
@ -41,7 +40,7 @@ int PlcBusInit(struct PlcBus *plc_bus, const char *bus_name)
return ret;
}
} else {
KPrintf("PlcBusInit BusRegister bus has been register state%u\n", plc_bus->bus.bus_state);
KPrintf("PlcBusInit BusRegister bus has been register state%u\n", plc_bus->bus.bus_state);
}
return ret;
@ -85,7 +84,7 @@ int PlcDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
@ -104,6 +103,7 @@ int PlcDriverAttachToBus(const char *drv_name, const char *bus_name)
return ERROR;
}
if (TYPE_PLC_DRV == driver->driver_type) {
ret = DriverRegisterToBus(bus, driver);
if (EOK != ret) {

View File

@ -13,9 +13,9 @@
/**
* @file plc_bus.h
* @brief define plc bus and drv function using bus driver framework
* @version 1.0
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
* @date 2022-01-24
*/
#ifndef __PLC_BUS_H_
@ -30,14 +30,12 @@ extern "C" {
struct PlcDriver
{
struct Driver driver;
uint32 (*configure) (void *drv, struct BusConfigureInfo *configure_info);
};
struct PlcBus
{
struct Bus bus;
void *private_data;
};

View File

@ -15,7 +15,7 @@
* @brief register plc dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
* @date 2022-01-24
*/
#include "plc_bus.h"
@ -38,6 +38,7 @@ static uint32 PlcHardwareDevOpen(void *dev)
return EOK;
}
static uint32 PlcHardwareDevClose(void *dev)
{
NULL_PARAM_CHECK(dev);
@ -47,6 +48,7 @@ static uint32 PlcHardwareDevClose(void *dev)
return EOK;
}
static uint32 PlcHardwareDevWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
@ -84,12 +86,13 @@ static uint32 PlcHardwareDevRead(void *dev, struct BusBlockReadParam *read_param
NULL_PARAM_CHECK(read_param);
int ret;
struct PlcHardwareDevice *plc_dev = (struct PlcHardwareDevice *)dev;
struct PlcDataStandard *plc_msg;
plc_msg = (struct PlcDataStandard *)x_malloc(sizeof(struct PlcDataStandard));
if (NONE == plc_msg) {
KPrintf("PlcHardwareDevRead x_malloc msg error\n");
x_free(plc_msg);
return ERROR;
}
@ -214,7 +217,7 @@ int PlcHardwareDevConfigureCs(struct HardwareDev *dev, uint8 plc_chip_select, ui
struct PlcDataStandard *msg;
msg = (struct PlcDataStandard *)x_malloc(sizeof(struct PlcDataStandard));
if (NONE == msg) {
if (NONE == msg){
KPrintf("PlcHardwareDevConfigureCs x_malloc msg error\n");
x_free(msg);
return ERROR;
@ -228,8 +231,10 @@ int PlcHardwareDevConfigureCs(struct HardwareDev *dev, uint8 plc_chip_select, ui
msg->plc_chip_select = plc_chip_select;
msg->plc_cs_release = plc_cs_release;
ret = plc_dev->plc_dev_done->dev_write(plc_dev, msg);
x_free(msg);
return ret;
}

View File

@ -11,44 +11,44 @@
*/
/**
* @file plc_dev.h
* @file dev_plc.h
* @brief define plc dev function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
* @date 2022-01-24
*/
#ifndef __PLC_DEV_H_
#define __PLC_DEV_H_
#ifndef DEV_PLC_H
#define DEV_PLC_H
#include <bus.h>
#ifdef __cplusplus
#ifdef __cpluspluss
extern "C" {
#endif
#define PLC_MAX_CLOCK 40000000
#define PLC_MAX_CLOCK 40000000
#define plc_device_max_num 4
#define PLC_LINE_CPHA (1<<0)
#define PLC_LINE_CPOL (1<<1)
#define PLC_LINE_CPHA (1 << 0)
#define PLC_LINE_CPOL (1 << 1)
#define PLC_LSB (0<<2)
#define PLC_MSB (1<<2)
#define PLC_LSB (0 << 2)
#define PLC_MSB (1 << 2)
#define PLC_MASTER (0<<3)
#define DEV_PLC_SLAVE (1<<3)
#define PLC_MASTER (0 << 3)
#define DEV_PLC_SLAVE (1 << 3)
#define PLC_MODE_0 (0 | 0)
#define PLC_MODE_1 (0 | PLC_LINE_CPHA)
#define PLC_MODE_2 (PLC_LINE_CPOL | 0)
#define PLC_MODE_3 (PLC_LINE_CPOL | PLC_LINE_CPHA)
#define PLC_MODE_MASK (PLC_LINE_CPHA | PLC_LINE_CPOL | PLC_MSB)
#define PLC_MODE_0 (0 | 0)
#define PLC_MODE_1 (0 | PLC_LINE_CPHA)
#define PLC_MODE_2 (PLC_LINE_CPOL | 0)
#define PLC_MODE_3 (PLC_LINE_CPOL | PLC_LINE_CPHA)
#define PLC_MODE_MASK (PLC_LINE_CPHA | PLC_LINE_CPOL | PLC_MSB)
#define PLC_CS_HIGH (1<<4)
#define PLC_NO_CS (1<<5)
#define PLC_3WIRE (1<<6)
#define PLC_READY (1<<7)
#define PLC_CS_HIGH (1 << 4)
#define PLC_NO_CS (1 << 5)
#define PLC_3WIRE (1 << 6)
#define PLC_READY (1 << 7)
struct PlcDataStandard
{
@ -70,7 +70,7 @@ struct PlcMasterParam
uint8 plc_work_mode;//CPOL CPHA
uint8 plc_frame_format;//frame format
uint8 plc_data_bit_width;//bit width
uint8 plc_data_endian;//little endian0big endian1
uint8 plc_data_endian;//little endian 0 : big endian 1
uint32 plc_maxfrequency;//work frequency
};

View File

@ -11,13 +11,14 @@
*/
/**
* @file plc_drv.c
* @file drv_plc.c
* @brief register plc drv function using bus driver framework
* @version 1.0
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
* @date 2022-01-24
*/
#include "transform.h"
#include "plc_bus.h"
#include "plc_dev.h"
@ -32,7 +33,7 @@ static void PlcDrvLinkInit()
DriverType PlcDriverFind(const char *drv_name, enum DriverType_e drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
@ -65,3 +66,4 @@ int PlcDriverRegister(struct Driver *driver)
return ret;
}

View File

@ -107,7 +107,7 @@ struct PinDevIrq
struct PinParam
{
int cmd;//< cmd:GPIO_CONFIG_MODE/GPIO_IRQ_REGISTER/GPIO_IRQ_FREE/GPIO_IRQ_DISABLE/GPIO_IRQ_ENABLE
long pin;//< pin number
long pin;//< pin number
int mode;//< pin mode: input/output
struct PinDevIrq irq_set;//< pin irq set
uint64 arg;
@ -170,9 +170,6 @@ int PrivMutexDelete(pthread_mutex_t *p_mutex);
int PrivMutexObtain(pthread_mutex_t *p_mutex);
int PrivMutexAbandon(pthread_mutex_t *p_mutex);
/*********************semaphore**********************/
int PrivSemaphoreCreate(sem_t *sem, int pshared, unsigned int value);

View File

@ -5,18 +5,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file board.c
* @brief relative configure for ok1052-c

View File

@ -5,19 +5,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file board.h
* @brief define imxrt1052-board init configure and start-up function

View File

@ -8,7 +8,7 @@
/**
* @file pin_mux.h
* @brief define imxrt1052-board pin configure
* @version 1.0
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-29
*/
@ -71,6 +71,8 @@ void BOARD_InitBootPins(void);
*
*/
void BOARD_InitPins(void);
void BOARD_InitI2C1Pins(void);
void BOARD_InitSPIPins(void);
#if defined(__cplusplus)
}

View File

@ -2,6 +2,7 @@ menuconfig BSP_USING_LPUART
bool "Using UART device"
default y
select RESOURCES_SERIAL
if BSP_USING_LPUART
source "$BSP_DIR/third_party_driver/uart/Kconfig"
endif
@ -11,6 +12,34 @@ menuconfig BSP_USING_LWIP
default n
select RESOURCES_LWIP
menuconfig BSP_USING_GPIO
bool "Using GPIO device "
default y
select RESOURCES_PIN
if BSP_USING_GPIO
source "$BSP_DIR/third_party_driver/gpio/Kconfig"
endif
menuconfig BSP_USING_I2C
bool "Using I2C device"
default y
select RESOURCES_I2C
if BSP_USING_I2C
source "$BSP_DIR/third_party_driver/i2c/Kconfig"
endif
menuconfig BSP_USING_ADC
bool "Using ADC device"
default y
select RESOURCES_ADC
menuconfig BSP_USING_SPI
bool "Using SPI device"
default y
select RESOURCES_SPI
menuconfig BSP_USING_SEMC
bool "Using SEMC device"
default y

View File

@ -8,6 +8,18 @@ ifeq ($(CONFIG_BSP_USING_LWIP),y)
SRC_DIR += ethernet
endif
ifeq ($(CONFIG_BSP_USING_I2C),y)
SRC_DIR += i2c
endif
ifeq ($(CONFIG_BSP_USING_ADC),y)
SRC_DIR += adc
endif
ifeq ($(CONFIG_BSP_USING_SPI),y)
SRC_DIR += spi
endif
ifeq ($(CONFIG_BSP_USING_SEMC),y)
SRC_DIR += semc
endif

View File

@ -0,0 +1,3 @@
SRC_FILES := fsl_adc.c adc_interrupt.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,178 @@
/*
* Copyright (c) 2013 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2018 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file adc_interrupt.c
* @brief Demo for ADC function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.1.18
*/
#include "fsl_debug_console.h"
#include "board.h"
#include "fsl_adc.h"
#include "fsl_common.h"
#include "pin_mux.h"
#include "clock_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define DEMO_ADC_BASE ADC1
#define DEMO_ADC_IRQn ADC1_IRQn
//#define DEMO_ADC_USER_CHANNEL 0U
#define DEMO_ADC_USER_CHANNEL 3U
#define DEMO_ADC_CHANNEL_GROUP 0U
#define EXAMPLE_ADC_IRQHandler ADC1_IRQHandler
#define adc_print KPrintf
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool g_AdcConversionDoneFlag;
volatile uint32_t g_AdcConversionValue;
volatile uint32_t g_AdcInterruptCounter;
const uint32_t g_Adc_12bitFullRange = 4096U;
/*******************************************************************************
* Code
******************************************************************************/
//#define ADC_BUS_NAME_1 "adc1"
//#define ADC_DRV_NAME_1 "adc1_drv"
//#define ADC_1_DEVICE_NAME_0 "adc1_dev0"
//
//static struct Bus *adc_bus = NONE; /* I2C bus handle */
//
//void AdcInit(const char *bus_name, const char *dev_name, const char *drv_name)
//{
// /* find I2C device and get I2C handle */
// adc_bus = BusFind(bus_name);
// if (NONE == adc_bus){
// i2c_print("%s can't find %s bus!\n", __func__, bus_name);
// }
// else{
// i2c_print("%s find %s bus!\n", __func__, bus_name);
// }
//
// adc_bus->owner_haldev = BusFindDevice(adc_bus, dev_name);
// adc_bus->owner_driver = BusFindDriver(adc_bus, drv_name);
//
// if(adc_bus->match(adc_bus->owner_driver, adc_bus->owner_haldev)){
// i2c_print("i2c match drv %s %p dev %s %p error\n", drv_name, adc_bus->owner_driver, dev_name, adc_bus->owner_haldev);
// }
// else{
// i2c_print("HS3000Init successfully!write %p read %p\n",
// adc_bus->owner_haldev->dev_done->write,
// adc_bus->owner_haldev->dev_done->read);
// }
//}
//
//void TestAdcInit(void)
//{
// AdcInit(ADC_BUS_NAME_1, ADC_1_DEVICE_NAME_0, ADC_DRV_NAME_1); /* init sensor */
//}
void EXAMPLE_ADC_IRQHandler(int vector, void *param)
{
g_AdcConversionDoneFlag = true;
/* Read conversion result to clear the conversion completed flag. */
g_AdcConversionValue = ADC_GetChannelConversionValue(DEMO_ADC_BASE, DEMO_ADC_CHANNEL_GROUP);
g_AdcInterruptCounter++;
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
DECLARE_HW_IRQ(ADC1_IRQn, EXAMPLE_ADC_IRQHandler, NONE);
/*!
* @brief Main function
*/
int test_adc(void)
{
int cnt = 3;
adc_config_t adcConfigStrcut;
adc_channel_config_t adcChannelConfigStruct;
EnableIRQ(DEMO_ADC_IRQn);
adc_print("\r\nADC interrupt Example.\r\n");
/*
* config->enableAsynchronousClockOutput = true;
* config->enableOverWrite = false;
* config->enableContinuousConversion = false;
* config->enableHighSpeed = false;
* config->enableLowPower = false;
* config->enableLongSample = false;
* config->referenceVoltageSource = kADC_ReferenceVoltageSourceVref;
* config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
* config->clockSource = kADC_ClockSourceAD;
* config->clockDriver = kADC_ClockDriver1;
* config->resolution = kADC_Resolution12Bit;
*/
ADC_GetDefaultConfig(&adcConfigStrcut);
ADC_Init(DEMO_ADC_BASE, &adcConfigStrcut);
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
ADC_EnableHardwareTrigger(DEMO_ADC_BASE, false);
#endif
/* Do auto hardware calibration. */
if (kStatus_Success == ADC_DoAutoCalibration(DEMO_ADC_BASE))
{
adc_print("ADC_DoAntoCalibration() Done.\r\n");
}
else
{
adc_print("ADC_DoAutoCalibration() Failed.\r\n");
}
/* Configure the user channel and interrupt. */
adcChannelConfigStruct.channelNumber = DEMO_ADC_USER_CHANNEL;
adcChannelConfigStruct.enableInterruptOnConversionCompleted = true;
g_AdcInterruptCounter = 0U; /* Clear the interrupt counter. */
adc_print("ADC Full Range: %d\r\n", g_Adc_12bitFullRange);
while (cnt --)
{
adc_print("Press any key to get user channel's ADC value.\r\n");
getchar();
g_AdcConversionDoneFlag = false;
/*
When in software trigger mode, each conversion would be launched once calling the "ADC16_ChannelConfigure()"
function, which works like writing a conversion command and executing it. For another channel's conversion,
just to change the "channelNumber" field in channel configuration structure, and call the function
"ADC_ChannelConfigure()"" again.
Also, the "enableInterruptOnConversionCompleted" inside the channel configuration structure is a parameter
for
the conversion command. It takes affect just for the current conversion. If the interrupt is still required
for the following conversion, it is necessary to assert the "enableInterruptOnConversionCompleted" every
time
for each command.
*/
ADC_SetChannelConfig(DEMO_ADC_BASE, DEMO_ADC_CHANNEL_GROUP, &adcChannelConfigStruct);
while (g_AdcConversionDoneFlag == false);
adc_print("ADC Value: %d\r\n", g_AdcConversionValue);
adc_print("ADC Interrupt Counter: %d\r\n", g_AdcInterruptCounter);
}
}
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
adc, test_adc, ADC test );

View File

@ -0,0 +1,394 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_adc.h"
/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.adc_12b1msps_sar"
#endif
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Get instance number for ADC module.
*
* @param base ADC peripheral base address
*/
static uint32_t ADC_GetInstance(ADC_Type *base);
/*******************************************************************************
* Variables
******************************************************************************/
/*! @brief Pointers to ADC bases for each instance. */
static ADC_Type *const s_adcBases[] = ADC_BASE_PTRS;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to ADC clocks for each instance. */
static const clock_ip_name_t s_adcClocks[] = ADC_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/*******************************************************************************
* Code
******************************************************************************/
static uint32_t ADC_GetInstance(ADC_Type *base)
{
uint32_t instance;
/* Find the instance index from base address mappings. */
for (instance = 0; instance < ARRAY_SIZE(s_adcBases); instance++)
{
if (s_adcBases[instance] == base)
{
break;
}
}
assert(instance < ARRAY_SIZE(s_adcBases));
return instance;
}
/*!
* brief Initialize the ADC module.
*
* param base ADC peripheral base address.
* param config Pointer to "adc_config_t" structure.
*/
void ADC_Init(ADC_Type *base, const adc_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Enable the clock. */
CLOCK_EnableClock(s_adcClocks[ADC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
/* ADCx_CFG */
tmp32 = base->CFG & (ADC_CFG_AVGS_MASK | ADC_CFG_ADTRG_MASK); /* Reserve AVGS and ADTRG bits. */
tmp32 |= ADC_CFG_REFSEL(config->referenceVoltageSource) | ADC_CFG_ADSTS(config->samplePeriodMode) |
ADC_CFG_ADICLK(config->clockSource) | ADC_CFG_ADIV(config->clockDriver) | ADC_CFG_MODE(config->resolution);
if (config->enableOverWrite)
{
tmp32 |= ADC_CFG_OVWREN_MASK;
}
if (config->enableLongSample)
{
tmp32 |= ADC_CFG_ADLSMP_MASK;
}
if (config->enableLowPower)
{
tmp32 |= ADC_CFG_ADLPC_MASK;
}
if (config->enableHighSpeed)
{
tmp32 |= ADC_CFG_ADHSC_MASK;
}
base->CFG = tmp32;
/* ADCx_GC */
tmp32 = base->GC & ~(ADC_GC_ADCO_MASK | ADC_GC_ADACKEN_MASK);
if (config->enableContinuousConversion)
{
tmp32 |= ADC_GC_ADCO_MASK;
}
if (config->enableAsynchronousClockOutput)
{
tmp32 |= ADC_GC_ADACKEN_MASK;
}
base->GC = tmp32;
}
/*!
* brief De-initializes the ADC module.
*
* param base ADC peripheral base address.
*/
void ADC_Deinit(ADC_Type *base)
{
#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/* Disable the clock. */
CLOCK_DisableClock(s_adcClocks[ADC_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}
/*!
* brief Gets an available pre-defined settings for the converter's configuration.
*
* This function initializes the converter configuration structure with available settings. The default values are:
* code
* config->enableAsynchronousClockOutput = true;
* config->enableOverWrite = false;
* config->enableContinuousConversion = false;
* config->enableHighSpeed = false;
* config->enableLowPower = false;
* config->enableLongSample = false;
* config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
* config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
* config->clockSource = kADC_ClockSourceAD;
* config->clockDriver = kADC_ClockDriver1;
* config->resolution = kADC_Resolution12Bit;
* endcode
* param base ADC peripheral base address.
* param config Pointer to the configuration structure.
*/
void ADC_GetDefaultConfig(adc_config_t *config)
{
assert(NULL != config);
/* Initializes the configure structure to zero. */
memset(config, 0, sizeof(*config));
config->enableAsynchronousClockOutput = true;
config->enableOverWrite = false;
config->enableContinuousConversion = false;
config->enableHighSpeed = false;
config->enableLowPower = false;
config->enableLongSample = false;
config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
config->clockSource = kADC_ClockSourceAD;
config->clockDriver = kADC_ClockDriver1;
config->resolution = kADC_Resolution12Bit;
}
/*!
* brief Configures the conversion channel.
*
* This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
* configures the channel while the external trigger source helps to trigger the conversion.
*
* Note that the "Channel Group" has a detailed description.
* To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one
* group of status and control registers, one for each conversion. The channel group parameter indicates which group of
* registers are used, for example channel group 0 is for Group A registers and channel group 1 is for Group B
* registers. The
* channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of
* the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and
* hardware
* trigger modes. Channel groups 1 and greater indicate potentially multiple channel group registers for
* use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual
* about the
* number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used
* for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion.
* Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and
* vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
* conversion aborts the current conversion.
*
* param base ADC peripheral base address.
* param channelGroup Channel group index.
* param config Pointer to the "adc_channel_config_t" structure for the conversion channel.
*/
void ADC_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc_channel_config_t *config)
{
assert(NULL != config);
assert(channelGroup < FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT);
uint32_t tmp32;
tmp32 = ADC_HC_ADCH(config->channelNumber);
if (config->enableInterruptOnConversionCompleted)
{
tmp32 |= ADC_HC_AIEN_MASK;
}
base->HC[channelGroup] = tmp32;
}
/*
*To complete calibration, the user must follow the below procedure:
* 1. Configure ADC_CFG with actual operating values for maximum accuracy.
* 2. Configure the ADC_GC values along with CAL bit.
* 3. Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC.
* 4. When CAL bit becomes '0' then check the CALF status and COCO[0] bit status.
*/
/*!
* brief Automates the hardware calibration.
*
* This auto calibration helps to adjust the plus/minus side gain automatically.
* Execute the calibration before using the converter. Note that the software trigger should be used
* during calibration.
*
* param base ADC peripheral base address.
*
* return Execution status.
* retval kStatus_Success Calibration is done successfully.
* retval kStatus_Fail Calibration has failed.
*/
status_t ADC_DoAutoCalibration(ADC_Type *base)
{
status_t status = kStatus_Success;
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
bool bHWTrigger = false;
/* The calibration would be failed when in hardwar mode.
* Remember the hardware trigger state here and restore it later if the hardware trigger is enabled.*/
if (0U != (ADC_CFG_ADTRG_MASK & base->CFG))
{
bHWTrigger = true;
ADC_EnableHardwareTrigger(base, false);
}
#endif
/* Clear the CALF and launch the calibration. */
base->GS = ADC_GS_CALF_MASK; /* Clear the CALF. */
base->GC |= ADC_GC_CAL_MASK; /* Launch the calibration. */
/* Check the status of CALF bit in ADC_GS and the CAL bit in ADC_GC. */
while (0U != (base->GC & ADC_GC_CAL_MASK))
{
/* Check the CALF when the calibration is active. */
if (0U != (ADC_GetStatusFlags(base) & kADC_CalibrationFailedFlag))
{
status = kStatus_Fail;
break;
}
}
/* When CAL bit becomes '0' then check the CALF status and COCO[0] bit status. */
if (0U == ADC_GetChannelStatusFlags(base, 0U)) /* Check the COCO[0] bit status. */
{
status = kStatus_Fail;
}
if (0U != (ADC_GetStatusFlags(base) & kADC_CalibrationFailedFlag)) /* Check the CALF status. */
{
status = kStatus_Fail;
}
/* Clear conversion done flag. */
ADC_GetChannelConversionValue(base, 0U);
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
/* Restore original trigger mode. */
if (true == bHWTrigger)
{
ADC_EnableHardwareTrigger(base, true);
}
#endif
return status;
}
/*!
* brief Set user defined offset.
*
* param base ADC peripheral base address.
* param config Pointer to "adc_offest_config_t" structure.
*/
void ADC_SetOffsetConfig(ADC_Type *base, const adc_offest_config_t *config)
{
assert(NULL != config);
uint32_t tmp32;
tmp32 = ADC_OFS_OFS(config->offsetValue);
if (config->enableSigned)
{
tmp32 |= ADC_OFS_SIGN_MASK;
}
base->OFS = tmp32;
}
/*!
* brief Configures the hardware compare mode.
*
* The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the
* result
* in the compare range is available. To compare the range, see "adc_hardware_compare_mode_t" or the appopriate
* reference
* manual for more information.
*
* param base ADC peripheral base address.
* param Pointer to "adc_hardware_compare_config_t" structure.
*
*/
void ADC_SetHardwareCompareConfig(ADC_Type *base, const adc_hardware_compare_config_t *config)
{
uint32_t tmp32;
tmp32 = base->GC & ~(ADC_GC_ACFE_MASK | ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK);
if (NULL == config) /* Pass "NULL" to disable the feature. */
{
base->GC = tmp32;
return;
}
/* Enable the feature. */
tmp32 |= ADC_GC_ACFE_MASK;
/* Select the hardware compare working mode. */
switch (config->hardwareCompareMode)
{
case kADC_HardwareCompareMode0:
break;
case kADC_HardwareCompareMode1:
tmp32 |= ADC_GC_ACFGT_MASK;
break;
case kADC_HardwareCompareMode2:
tmp32 |= ADC_GC_ACREN_MASK;
break;
case kADC_HardwareCompareMode3:
tmp32 |= ADC_GC_ACFGT_MASK | ADC_GC_ACREN_MASK;
break;
default:
break;
}
base->GC = tmp32;
/* Load the compare values. */
tmp32 = ADC_CV_CV1(config->value1) | ADC_CV_CV2(config->value2);
base->CV = tmp32;
}
/*!
* brief Configures the hardware average mode.
*
* The hardware average mode provides a way to process the conversion result automatically by using hardware. The
* multiple
* conversion results are accumulated and averaged internally making them easier to read.
*
* param base ADC peripheral base address.
* param mode Setting the hardware average mode. See "adc_hardware_average_mode_t".
*/
void ADC_SetHardwareAverageConfig(ADC_Type *base, adc_hardware_average_mode_t mode)
{
uint32_t tmp32;
if (mode == kADC_HardwareAverageDiasable)
{
base->GC &= ~ADC_GC_AVGE_MASK;
}
else
{
tmp32 = base->CFG & ~ADC_CFG_AVGS_MASK;
tmp32 |= ADC_CFG_AVGS(mode);
base->CFG = tmp32;
base->GC |= ADC_GC_AVGE_MASK; /* Enable the hardware compare. */
}
}
/*!
* brief Clears the converter's status falgs.
*
* param base ADC peripheral base address.
* param mask Mask value for the cleared flags. See "adc_status_flags_t".
*/
void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask)
{
uint32_t tmp32 = 0;
if (0U != (mask & kADC_CalibrationFailedFlag))
{
tmp32 |= ADC_GS_CALF_MASK;
}
if (0U != (mask & kADC_ConversionActiveFlag))
{
tmp32 |= ADC_GS_ADACT_MASK;
}
base->GS = tmp32;
}

View File

@ -0,0 +1,420 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _FSL_ADC_H_
#define _FSL_ADC_H_
#include "fsl_common.h"
/*!
* @addtogroup adc_12b1msps_sar
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief ADC driver version */
#define FSL_ADC_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version 2.0.2. */
/*!
* @brief Converter's status flags.
*/
typedef enum _adc_status_flags
{
kADC_ConversionActiveFlag = ADC_GS_ADACT_MASK, /*!< Conversion is active,not support w1c. */
kADC_CalibrationFailedFlag = ADC_GS_CALF_MASK, /*!< Calibration is failed,support w1c. */
kADC_AsynchronousWakeupInterruptFlag =
ADC_GS_AWKST_MASK, /*!< Asynchronous wakeup interrupt occurred, support w1c. */
} adc_status_flags_t;
/*!
* @brief Reference voltage source.
*/
typedef enum _adc_reference_voltage_source
{
kADC_ReferenceVoltageSourceAlt0 = 0U, /*!< For external pins pair of VrefH and VrefL. */
} adc_reference_voltage_source_t;
/*!
* @brief Sample time duration.
*/
typedef enum _adc_sample_period_mode
{
/* This group of enumeration is for internal use which is related to register setting. */
kADC_SamplePeriod2or12Clocks = 0U, /*!< Long sample 12 clocks or short sample 2 clocks. */
kADC_SamplePeriod4or16Clocks = 1U, /*!< Long sample 16 clocks or short sample 4 clocks. */
kADC_SamplePeriod6or20Clocks = 2U, /*!< Long sample 20 clocks or short sample 6 clocks. */
kADC_SamplePeriod8or24Clocks = 3U, /*!< Long sample 24 clocks or short sample 8 clocks. */
/* This group of enumeration is for a public user. */
/* For long sample mode. */
kADC_SamplePeriodLong12Clcoks = kADC_SamplePeriod2or12Clocks, /*!< Long sample 12 clocks. */
kADC_SamplePeriodLong16Clcoks = kADC_SamplePeriod4or16Clocks, /*!< Long sample 16 clocks. */
kADC_SamplePeriodLong20Clcoks = kADC_SamplePeriod6or20Clocks, /*!< Long sample 20 clocks. */
kADC_SamplePeriodLong24Clcoks = kADC_SamplePeriod8or24Clocks, /*!< Long sample 24 clocks. */
/* For short sample mode. */
kADC_SamplePeriodShort2Clocks = kADC_SamplePeriod2or12Clocks, /*!< Short sample 2 clocks. */
kADC_SamplePeriodShort4Clocks = kADC_SamplePeriod4or16Clocks, /*!< Short sample 4 clocks. */
kADC_SamplePeriodShort6Clocks = kADC_SamplePeriod6or20Clocks, /*!< Short sample 6 clocks. */
kADC_SamplePeriodShort8Clocks = kADC_SamplePeriod8or24Clocks, /*!< Short sample 8 clocks. */
} adc_sample_period_mode_t;
/*!
* @brief Clock source.
*/
typedef enum _adc_clock_source
{
kADC_ClockSourceIPG = 0U, /*!< Select IPG clock to generate ADCK. */
kADC_ClockSourceIPGDiv2 = 1U, /*!< Select IPG clock divided by 2 to generate ADCK. */
#if !(defined(FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE) && FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE)
kADC_ClockSourceALT = 2U, /*!< Select alternate clock to generate ADCK. */
#endif
kADC_ClockSourceAD = 3U, /*!< Select Asynchronous clock to generate ADCK. */
} adc_clock_source_t;
/*!
* @brief Clock divider for the converter.
*/
typedef enum _adc_clock_drvier
{
kADC_ClockDriver1 = 0U, /*!< For divider 1 from the input clock to the module. */
kADC_ClockDriver2 = 1U, /*!< For divider 2 from the input clock to the module. */
kADC_ClockDriver4 = 2U, /*!< For divider 4 from the input clock to the module. */
kADC_ClockDriver8 = 3U, /*!< For divider 8 from the input clock to the module. */
} adc_clock_driver_t;
/*!
* @brief Converter's resolution.
*/
typedef enum _adc_resolution
{
kADC_Resolution8Bit = 0U, /*!< Single End 8-bit resolution. */
kADC_Resolution10Bit = 1U, /*!< Single End 10-bit resolution. */
kADC_Resolution12Bit = 2U, /*!< Single End 12-bit resolution. */
} adc_resolution_t;
/*!
* @brief Converter hardware compare mode.
*/
typedef enum _adc_hardware_compare_mode
{
kADC_HardwareCompareMode0 = 0U, /*!< Compare true if the result is less than the value1. */
kADC_HardwareCompareMode1 = 1U, /*!< Compare true if the result is greater than or equal to value1. */
kADC_HardwareCompareMode2 = 2U, /*!< Value1 <= Value2, compare true if the result is less than value1 Or
the result is Greater than value2.
Value1 > Value2, compare true if the result is less than value1 And the
result is greater than value2*/
kADC_HardwareCompareMode3 = 3U, /*!< Value1 <= Value2, compare true if the result is greater than or equal
to value1 And the result is less than or equal to value2.
Value1 > Value2, compare true if the result is greater than or equal to
value1 Or the result is less than or equal to value2. */
} adc_hardware_compare_mode_t;
/*!
* @brief Converter hardware average mode.
*/
typedef enum _adc_hardware_average_mode
{
kADC_HardwareAverageCount4 = 0U, /*!< For hardware average with 4 samples. */
kADC_HardwareAverageCount8 = 1U, /*!< For hardware average with 8 samples. */
kADC_HardwareAverageCount16 = 2U, /*!< For hardware average with 16 samples. */
kADC_HardwareAverageCount32 = 3U, /*!< For hardware average with 32 samples. */
kADC_HardwareAverageDiasable = 4U, /*!< Disable the hardware average function. */
} adc_hardware_average_mode_t;
/*!
* @brief Converter configuration.
*/
typedef struct _adc_config
{
bool enableOverWrite; /*!< Enable the overwriting. */
bool enableContinuousConversion; /*!< Enable the continuous conversion mode. */
bool enableHighSpeed; /*!< Enable the high-speed mode. */
bool enableLowPower; /*!< Enable the low power mode. */
bool enableLongSample; /*!< Enable the long sample mode. */
bool enableAsynchronousClockOutput; /*!< Enable the asynchronous clock output. */
adc_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */
adc_sample_period_mode_t samplePeriodMode; /*!< Select the sample period in long sample mode or short mode. */
adc_clock_source_t clockSource; /*!< Select the input clock source to generate the internal clock ADCK. */
adc_clock_driver_t clockDriver; /*!< Select the divide ratio used by the ADC to generate the internal clock ADCK. */
adc_resolution_t resolution; /*!< Select the ADC resolution mode. */
} adc_config_t;
/*!
* @brief Converter Offset configuration.
*/
typedef struct _adc_offest_config
{
bool enableSigned; /*!< if false,The offset value is added with the raw result.
if true,The offset value is subtracted from the raw converted value. */
uint32_t offsetValue; /*!< User configurable offset value(0-4095). */
} adc_offest_config_t;
/*!
* @brief ADC hardware compare configuration.
*
* In kADC_HardwareCompareMode0, compare true if the result is less than the value1.
* In kADC_HardwareCompareMode1, compare true if the result is greater than or equal to value1.
* In kADC_HardwareCompareMode2, Value1 <= Value2, compare true if the result is less than value1 Or the result is
* Greater than value2.
* Value1 > Value2, compare true if the result is less than value1 And the result is
* Greater than value2.
* In kADC_HardwareCompareMode3, Value1 <= Value2, compare true if the result is greater than or equal to value1 And the
* result is less than or equal to value2.
* Value1 > Value2, compare true if the result is greater than or equal to value1 Or the
* result is less than or equal to value2.
*/
typedef struct _adc_hardware_compare_config
{
adc_hardware_compare_mode_t hardwareCompareMode; /*!< Select the hardware compare mode.
See "adc_hardware_compare_mode_t". */
uint16_t value1; /*!< Setting value1(0-4095) for hardware compare mode. */
uint16_t value2; /*!< Setting value2(0-4095) for hardware compare mode. */
} adc_hardware_compare_config_t;
/*!
* @brief ADC channel conversion configuration.
*/
typedef struct _adc_channel_config
{
uint32_t channelNumber; /*!< Setting the conversion channel number. The available range is 0-31.
See channel connection information for each chip in Reference
Manual document. */
bool enableInterruptOnConversionCompleted; /*!< Generate an interrupt request once the conversion is completed. */
} adc_channel_config_t;
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @name Initialization
* @{
*/
/*!
* @brief Initialize the ADC module.
*
* @param base ADC peripheral base address.
* @param config Pointer to "adc_config_t" structure.
*/
void ADC_Init(ADC_Type *base, const adc_config_t *config);
/*!
* @brief De-initializes the ADC module.
*
* @param base ADC peripheral base address.
*/
void ADC_Deinit(ADC_Type *base);
/*!
* @brief Gets an available pre-defined settings for the converter's configuration.
*
* This function initializes the converter configuration structure with available settings. The default values are:
* @code
* config->enableAsynchronousClockOutput = true;
* config->enableOverWrite = false;
* config->enableContinuousConversion = false;
* config->enableHighSpeed = false;
* config->enableLowPower = false;
* config->enableLongSample = false;
* config->referenceVoltageSource = kADC_ReferenceVoltageSourceAlt0;
* config->samplePeriodMode = kADC_SamplePeriod2or12Clocks;
* config->clockSource = kADC_ClockSourceAD;
* config->clockDriver = kADC_ClockDriver1;
* config->resolution = kADC_Resolution12Bit;
* @endcode
* @param base ADC peripheral base address.
* @param config Pointer to the configuration structure.
*/
void ADC_GetDefaultConfig(adc_config_t *config);
/*!
* @brief Configures the conversion channel.
*
* This operation triggers the conversion when in software trigger mode. When in hardware trigger mode, this API
* configures the channel while the external trigger source helps to trigger the conversion.
*
* Note that the "Channel Group" has a detailed description.
* To allow sequential conversions of the ADC to be triggered by internal peripherals, the ADC has more than one
* group of status and control registers, one for each conversion. The channel group parameter indicates which group of
* registers are used, for example channel group 0 is for Group A registers and channel group 1 is for Group B
* registers. The
* channel groups are used in a "ping-pong" approach to control the ADC operation. At any point, only one of
* the channel groups is actively controlling ADC conversions. The channel group 0 is used for both software and
* hardware
* trigger modes. Channel groups 1 and greater indicate potentially multiple channel group registers for
* use only in hardware trigger mode. See the chip configuration information in the appropriate MCU reference manual
* about the
* number of SC1n registers (channel groups) specific to this device. None of the channel groups 1 or greater are used
* for software trigger operation. Therefore, writing to these channel groups does not initiate a new conversion.
* Updating the channel group 0 while a different channel group is actively controlling a conversion is allowed and
* vice versa. Writing any of the channel group registers while that specific channel group is actively controlling a
* conversion aborts the current conversion.
*
* @param base ADC peripheral base address.
* @param channelGroup Channel group index.
* @param config Pointer to the "adc_channel_config_t" structure for the conversion channel.
*/
void ADC_SetChannelConfig(ADC_Type *base, uint32_t channelGroup, const adc_channel_config_t *config);
/*!
* @brief Gets the conversion value.
*
* @param base ADC peripheral base address.
* @param channelGroup Channel group index.
*
* @return Conversion value.
*/
static inline uint32_t ADC_GetChannelConversionValue(ADC_Type *base, uint32_t channelGroup)
{
assert(channelGroup < FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT);
return base->R[channelGroup];
}
/*!
* @brief Gets the status flags of channel.
*
* A conversion is completed when the result of the conversion is transferred into the data
* result registers. (provided the compare function & hardware averaging is disabled), this is
* indicated by the setting of COCOn. If hardware averaging is enabled, COCOn sets only,
* if the last of the selected number of conversions is complete. If the compare function is
* enabled, COCOn sets and conversion result data is transferred only if the compare
* condition is true. If both hardware averaging and compare functions are enabled, then
* COCOn sets only if the last of the selected number of conversions is complete and the
* compare condition is true.
*
* @param base ADC peripheral base address.
* @param channelGroup Channel group index.
*
* @return Status flags of channel.return 0 means COCO flag is 0,return 1 means COCOflag is 1.
*/
static inline uint32_t ADC_GetChannelStatusFlags(ADC_Type *base, uint32_t channelGroup)
{
assert(channelGroup < FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT);
/* If flag is set,return 1,otherwise, return 0. */
return (((base->HS) & (1U << channelGroup)) >> channelGroup);
}
/*!
* @brief Automates the hardware calibration.
*
* This auto calibration helps to adjust the plus/minus side gain automatically.
* Execute the calibration before using the converter. Note that the software trigger should be used
* during calibration.
*
* @param base ADC peripheral base address.
*
* @return Execution status.
* @retval kStatus_Success Calibration is done successfully.
* @retval kStatus_Fail Calibration has failed.
*/
status_t ADC_DoAutoCalibration(ADC_Type *base);
/*!
* @brief Set user defined offset.
*
* @param base ADC peripheral base address.
* @param config Pointer to "adc_offest_config_t" structure.
*/
void ADC_SetOffsetConfig(ADC_Type *base, const adc_offest_config_t *config);
/*!
* @brief Enables generating the DMA trigger when the conversion is complete.
*
* @param base ADC peripheral base address.
* @param enable Switcher of the DMA feature. "true" means enabled, "false" means not enabled.
*/
static inline void ADC_EnableDMA(ADC_Type *base, bool enable)
{
if (enable)
{
base->GC |= ADC_GC_DMAEN_MASK;
}
else
{
base->GC &= ~ADC_GC_DMAEN_MASK;
}
}
/*!
* @brief Enables the hardware trigger mode.
*
* @param base ADC peripheral base address.
* @param enable Switcher of the trigger mode. "true" means hardware tirgger mode,"false" means software mode.
*/
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
static inline void ADC_EnableHardwareTrigger(ADC_Type *base, bool enable)
{
if (enable)
{
base->CFG |= ADC_CFG_ADTRG_MASK;
}
else
{
base->CFG &= ~ADC_CFG_ADTRG_MASK;
}
}
#endif
/*!
* @brief Configures the hardware compare mode.
*
* The hardware compare mode provides a way to process the conversion result automatically by using hardware. Only the
* result
* in the compare range is available. To compare the range, see "adc_hardware_compare_mode_t" or the appopriate
* reference
* manual for more information.
*
* @param base ADC peripheral base address.
* @param Pointer to "adc_hardware_compare_config_t" structure.
*
*/
void ADC_SetHardwareCompareConfig(ADC_Type *base, const adc_hardware_compare_config_t *config);
/*!
* @brief Configures the hardware average mode.
*
* The hardware average mode provides a way to process the conversion result automatically by using hardware. The
* multiple
* conversion results are accumulated and averaged internally making them easier to read.
*
* @param base ADC peripheral base address.
* @param mode Setting the hardware average mode. See "adc_hardware_average_mode_t".
*/
void ADC_SetHardwareAverageConfig(ADC_Type *base, adc_hardware_average_mode_t mode);
/*!
* @brief Gets the converter's status flags.
*
* @param base ADC peripheral base address.
*
* @return Flags' mask if indicated flags are asserted. See "adc_status_flags_t".
*/
static inline uint32_t ADC_GetStatusFlags(ADC_Type *base)
{
return base->GS;
}
/*!
* @brief Clears the converter's status falgs.
*
* @param base ADC peripheral base address.
* @param mask Mask value for the cleared flags. See "adc_status_flags_t".
*/
void ADC_ClearStatusFlags(ADC_Type *base, uint32_t mask);
#if defined(__cplusplus)
}
#endif
#endif /* _FSL_ADC_H_ */

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_cache.c
* @brief cache drivers
@ -45,9 +33,9 @@
#define L2CACHE_1KBCOVERTOB 1024U
#define L2CACHE_SAMLLWAYS_SIZE 16U
#define L2CACHE_LOCKDOWN_REGNUM 8 /*!< Lock down register numbers.*/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief Set for all ways and waiting for the operation finished.
* This is provided for all the background operations.

View File

@ -5,18 +5,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_clock.c
* @brief clock drivers

View File

@ -7,18 +7,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_common.c
* @brief common drivers

View File

@ -639,6 +639,128 @@ BOARD_InitPins:
* Description : Configures pin routing and optionally pin electrical features.
*
* END ****************************************************************************************************************/
void BOARD_InitSPIPins(void){
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 is configured as LPUART1_TX */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 is configured as LPUART1_RX */
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(
IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, /* GPIO_SD_B1_05 is configured as FLEXSPIA_DQS */
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_05 */
IOMUXC_SetPinMux(
IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, /* GPIO_SD_B1_06 is configured as FLEXSPIA_SS0_B */
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_06 */
IOMUXC_SetPinMux(
IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, /* GPIO_SD_B1_07 is configured as FLEXSPIA_SCLK */
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_07 */
IOMUXC_SetPinMux(
IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, /* GPIO_SD_B1_08 is configured as FLEXSPIA_DATA00 */
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_08 */
IOMUXC_SetPinMux(
IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, /* GPIO_SD_B1_09 is configured as FLEXSPIA_DATA01 */
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_09 */
IOMUXC_SetPinMux(
IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, /* GPIO_SD_B1_10 is configured as FLEXSPIA_DATA02 */
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_10 */
IOMUXC_SetPinMux(
IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, /* GPIO_SD_B1_11 is configured as FLEXSPIA_DATA03 */
1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_11 */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 PAD functional properties : */
0x10B0u); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: R0/6
Speed Field: medium(100MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 PAD functional properties : */
0x10B0u); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: R0/6
Speed Field: medium(100MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_SD_B1_05_FLEXSPIA_DQS, /* GPIO_SD_B1_05 PAD functional properties : */
0x10F1u); /* Slew Rate Field: Fast Slew Rate
Drive Strength Field: R0/6
Speed Field: max(200MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_SD_B1_06_FLEXSPIA_SS0_B, /* GPIO_SD_B1_06 PAD functional properties : */
0x10F1u); /* Slew Rate Field: Fast Slew Rate
Drive Strength Field: R0/6
Speed Field: max(200MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_SD_B1_07_FLEXSPIA_SCLK, /* GPIO_SD_B1_07 PAD functional properties : */
0x10F1u); /* Slew Rate Field: Fast Slew Rate
Drive Strength Field: R0/6
Speed Field: max(200MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_SD_B1_08_FLEXSPIA_DATA00, /* GPIO_SD_B1_08 PAD functional properties : */
0x10F1u); /* Slew Rate Field: Fast Slew Rate
Drive Strength Field: R0/6
Speed Field: max(200MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_SD_B1_09_FLEXSPIA_DATA01, /* GPIO_SD_B1_09 PAD functional properties : */
0x10F1u); /* Slew Rate Field: Fast Slew Rate
Drive Strength Field: R0/6
Speed Field: max(200MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_SD_B1_10_FLEXSPIA_DATA02, /* GPIO_SD_B1_10 PAD functional properties : */
0x10F1u); /* Slew Rate Field: Fast Slew Rate
Drive Strength Field: R0/6
Speed Field: max(200MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_SD_B1_11_FLEXSPIA_DATA03, /* GPIO_SD_B1_11 PAD functional properties : */
0x10F1u); /* Slew Rate Field: Fast Slew Rate
Drive Strength Field: R0/6
Speed Field: max(200MHz)
Open Drain Enable Field: Open Drain Disabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 100K Ohm Pull Down
Hyst. Enable Field: Hysteresis Disabled */
}
void BOARD_InitPins(void) {
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
@ -848,8 +970,41 @@ void BOARD_InitPins(void) {
Pull / Keep Select Field: Pull
Pull Up / Down Config. Field: 100K Ohm Pull Up
Hyst. Enable Field: Hysteresis Disabled */
}
void BOARD_InitI2C1Pins(void) {
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, /* GPIO_AD_B1_00 is configured as LPI2C1_SCL */
1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_00 */
IOMUXC_SetPinMux(
IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, /* GPIO_AD_B1_01 is configured as LPI2C1_SDA */
1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_01 */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_AD_B1_00_LPI2C1_SCL, /* GPIO_AD_B1_00 PAD functional properties : */
0xD8B0u); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: R0/6
Speed Field: medium(100MHz)
Open Drain Enable Field: Open Drain Enabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 22K Ohm Pull Up
Hyst. Enable Field: Hysteresis Disabled */
IOMUXC_SetPinConfig(
IOMUXC_GPIO_AD_B1_01_LPI2C1_SDA, /* GPIO_AD_B1_01 PAD functional properties : */
0xD8B0u); /* Slew Rate Field: Slow Slew Rate
Drive Strength Field: R0/6
Speed Field: medium(100MHz)
Open Drain Enable Field: Open Drain Enabled
Pull / Keep Enable Field: Pull/Keeper Enabled
Pull / Keep Select Field: Keeper
Pull Up / Down Config. Field: 22K Ohm Pull Up
Hyst. Enable Field: Hysteresis Disabled */
}
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/

View File

@ -38,18 +38,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file enet_ethernetif.c
* @brief ethernet drivers
@ -90,7 +78,6 @@
* Definitions
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/

View File

@ -38,18 +38,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file enet_ethernetif_kinetis.c
* @brief ethernet drivers

View File

@ -38,18 +38,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file enet_ethernetif_lpc.c
* @brief ethernet drivers

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_enet.c
* @brief ethernet drivers

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_phy.c
* @brief phy drivers for ksz8081

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_phy.h
* @brief phy drivers for ksz8081

View File

@ -0,0 +1,12 @@
config PIN_BUS_NAME
string "pin bus name"
default "pin"
config PIN_DRIVER_NAME
string "pin driver name"
default "pin_drv"
config PIN_DEVICE_NAME
string "pin device name"
default "pin_dev"

View File

@ -1,3 +1,3 @@
SRC_FILES := fsl_gpio.c
SRC_FILES := connect_gpio.c fsl_gpio.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,544 @@
/*
* Copyright (c) 2020 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-06 balanceTWK first version
* 2019-04-23 WillianChan Fix GPIO serial number disorder
*/
/**
* @file connect_gpio.c
* @brief support gpio function using bus driver framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: connect_gpio.c
Description: support gpio configure and register to bus framework
Others: take RT-Thread v4.0.2/bsp/stm32/libraries/HAL_Drivers/drv_gpio.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification: add bus driver framework support for gpio
*************************************************/
#include <device.h>
#include <board.h>
#define STM32_PIN_NUMBERS 100 // [48, 64, 100, 144]
#define ITEM_NUM(items) sizeof(items)/sizeof(items[0])
struct PinIndex
{
int index;
GPIO_Type *gpio;
uint32_t pin;
};
struct PinIrq
{
uint8 port_source;
uint8 pin_source;
enum IRQn irq_exti_channel;
uint32 exti_line;
};
static const struct PinIndex pins[] = {
{0, GPIO1, 0},
{1, GPIO1, 1},
{2, GPIO1, 2},
{3, GPIO1, 3},
{4, GPIO1, 4},
{5, GPIO1, 5},
{6, GPIO1, 6},
{7, GPIO1, 7},
{8, GPIO1, 8},
{9, GPIO1, 9},
{10, GPIO1, 10},
{11, GPIO1, 11},
{12, GPIO1, 12},
{13, GPIO1, 13},
{14, GPIO1, 14},
{15, GPIO1, 15},
{16, GPIO2, 0},
{17, GPIO2, 1},
{18, GPIO2, 2},
{19, GPIO2, 3},
{20, GPIO2, 4},
{21, GPIO2, 5},
{22, GPIO2, 6},
{23, GPIO2, 7},
{24, GPIO2, 8},
{25, GPIO2, 9},
{26, GPIO2, 10},
{27, GPIO2, 11},
{28, GPIO2, 12},
{29, GPIO2, 13},
{30, GPIO2, 14},
{31, GPIO2, 15},
{32, GPIO3, 0},
{33, GPIO3, 1},
{34, GPIO3, 2},
{35, GPIO3, 3},
{36, GPIO3, 4},
{37, GPIO3, 5},
{38, GPIO3, 6},
{39, GPIO3, 7},
{40, GPIO3, 8},
{41, GPIO3, 9},
{42, GPIO3, 10},
{43, GPIO3, 11},
{44, GPIO3, 12},
{45, GPIO3, 13},
{46, GPIO3, 14},
{47, GPIO3, 15},
{-1, 0u, -1}
};
struct PinIrqHdr pin_irq_hdr_tab[] = {};
const struct PinIndex *GetPin(uint8_t pin)
{
const struct PinIndex *index;
if (pin < ITEM_NUM(pins)){
index = &pins[pin];
if (index->index == -1)
index = NONE;
}
else{
index = NONE;
}
return index;
}
static int32 GpioConfigMode(int mode, const struct PinIndex* index)
{
gpio_pin_config_t gpio_config;
NULL_PARAM_CHECK(index);
switch (mode)
{
case GPIO_CFG_OUTPUT:
gpio_config.direction = kGPIO_DigitalOutput;
gpio_config.interruptMode = kGPIO_NoIntmode;
break;
case GPIO_CFG_INPUT:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_NoIntmode;
break;
case GPIO_CFG_INPUT_PULLUP:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntRisingEdge;
break;
case GPIO_CFG_INPUT_PULLDOWN:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntFallingEdge;
break;
case GPIO_CFG_OUTPUT_OD:
gpio_config.direction = kGPIO_DigitalOutput;
break;
default:
break;
}
GPIO_PinInit(index->gpio, index->pin, &gpio_config);
return EOK;
}
static __inline int32 Bit2Bitnum(uint32 bit)
{
for (int i = 0; i < 32; i++){
if ((1UL << i) == bit){
return i;
}
}
return -1;
}
static __inline int32 Bitno2Bit(uint32 bitno)
{
if (bitno <= 32) {
return 1UL << bitno;
}
else {
return 0;
}
}
static const struct PinIrq *GetPinIrq(uint16_t pin)
{
static struct PinIrq irq;
const struct PinIndex* index = GetPin(pin);
if (index == NONE) {
return NONE;
}
irq.exti_line = index->pin;
irq.pin_source = Bit2Bitnum(index->pin);
irq.port_source = ((uint32_t)index->gpio - GPIO1_BASE) / (GPIO2_BASE - GPIO1_BASE);
switch (irq.pin_source)
{
case 0 :
irq.irq_exti_channel = GPIO1_INT0_IRQn;
break;
case 1 :
irq.irq_exti_channel = GPIO1_INT1_IRQn;
break;
case 2 :
irq.irq_exti_channel = GPIO1_INT2_IRQn;
break;
case 3 :
irq.irq_exti_channel = GPIO1_INT3_IRQn;
break;
case 4 :
irq.irq_exti_channel = GPIO1_INT4_IRQn;
break;
case 5 :
irq.irq_exti_channel = GPIO1_INT5_IRQn;
break;
case 6 :
irq.irq_exti_channel = GPIO1_INT6_IRQn;
break;
case 7 :
irq.irq_exti_channel = GPIO1_INT7_IRQn;
break;
default :
return NONE;
}
return &irq;
};
static int32 GpioIrqRegister(int32 pin, int32 mode, void (*hdr)(void *args), void *args)
{
const struct PinIndex* index = GetPin(pin);
int32 irqindex = -1;
irqindex = Bit2Bitnum(index->pin);
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)) {
return -ENONESYS;
}
x_base level = CriticalAreaLock();
if (pin_irq_hdr_tab[irqindex].pin == pin &&
pin_irq_hdr_tab[irqindex].hdr == hdr &&
pin_irq_hdr_tab[irqindex].mode == mode &&
pin_irq_hdr_tab[irqindex].args == args
)
{
CriticalAreaUnLock(level);
return EOK;
}
if (pin_irq_hdr_tab[irqindex].pin != -1) {
CriticalAreaUnLock(level);
return -EDEV_BUSY;
}
pin_irq_hdr_tab[irqindex].pin = pin;
pin_irq_hdr_tab[irqindex].hdr = hdr;
pin_irq_hdr_tab[irqindex].mode = mode;
pin_irq_hdr_tab[irqindex].args = args;
CriticalAreaUnLock(level);
return EOK;
}
static uint32 GpioIrqFree(int32 pin)
{
const struct PinIndex* index = GetPin(pin);
int32 irqindex = -1;
irqindex = Bit2Bitnum(index->pin);
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)) {
return -ENONESYS;
}
x_base level = CriticalAreaLock();
if (pin_irq_hdr_tab[irqindex].pin == -1){
CriticalAreaUnLock(level);
return EOK;
}
pin_irq_hdr_tab[irqindex].pin = -1;
pin_irq_hdr_tab[irqindex].hdr = NONE;
pin_irq_hdr_tab[irqindex].mode = 0;
pin_irq_hdr_tab[irqindex].args = NONE;
CriticalAreaUnLock(level);
return EOK;
}
static int32 GpioIrqEnable(x_base pin)
{
const struct PinIndex* index = GetPin(pin);
int32 irqindex = -1;
const struct PinIrq *irq;
gpio_pin_config_t gpio_config;
irqindex = Bit2Bitnum(index->pin);
if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_hdr_tab)){
return -ENONESYS;
}
x_base level = CriticalAreaLock();
if (pin_irq_hdr_tab[irqindex].pin == -1) {
CriticalAreaUnLock(level);
return -ENONESYS;
}
irq = GetPinIrq(pin);
if (irq == NONE){
CriticalAreaUnLock(level);
return -ENONESYS;
}
switch (pin_irq_hdr_tab[irqindex].mode)
{
case GPIO_IRQ_EDGE_RISING:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntRisingEdge;
break;
case GPIO_IRQ_EDGE_FALLING:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntFallingEdge;
break;
case GPIO_IRQ_EDGE_BOTH:
gpio_config.direction = kGPIO_DigitalInput;
gpio_config.interruptMode = kGPIO_IntRisingOrFallingEdge;
break;
}
GPIO_PinInit(index->gpio, index->pin, &gpio_config);
GPIO_PortEnableInterrupts(index->gpio, index->pin);
CriticalAreaUnLock(level);
return EOK;
}
static int32 GpioIrqDisable(x_base pin)
{
const struct PinIndex* index = GetPin(pin);
const struct PinIrq *irq;
irq = GetPinIrq(index->pin);
NULL_PARAM_CHECK(irq);
GPIO_PortDisableInterrupts(index->gpio, index->pin);
return EOK;
}
static uint32 Stm32PinConfigure(struct PinParam *param)
{
NULL_PARAM_CHECK(param);
int ret = EOK;
const struct PinIndex *index = GetPin(param->pin);
switch(param->cmd)
{
case GPIO_CONFIG_MODE:
GpioConfigMode(param->mode, index);
break;
case GPIO_IRQ_REGISTER:
ret = GpioIrqRegister(param->pin,param->irq_set.irq_mode,param->irq_set.hdr,param->irq_set.args);
break;
case GPIO_IRQ_FREE:
ret = GpioIrqFree(param->pin);
break;
case GPIO_IRQ_ENABLE:
ret = GpioIrqEnable(param->pin);
break;
case GPIO_IRQ_DISABLE:
ret = GpioIrqDisable(param->pin);
break;
default:
ret = -EINVALED;
break;
}
return ret;
}
static uint32 Stm32PinInit(void)
{
static x_bool pin_init_flag = RET_FALSE;
if (!pin_init_flag) {
pin_init_flag = RET_TRUE;
}
return EOK;
}
static uint32 Stm32GpioDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
struct PinParam *param;
switch (configure_info->configure_cmd)
{
case OPE_INT:
ret = Stm32PinInit();
break;
case OPE_CFG:
param = (struct PinParam *)configure_info->private_data;
ret = Stm32PinConfigure(param);
break;
default:
break;
}
return ret;
}
uint32 Stm32PinWrite(void *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(write_param);
struct PinStat *pinstat = (struct PinStat *)write_param->buffer;
const struct PinIndex* index = GetPin(pinstat->pin);
NULL_PARAM_CHECK(index);
if (GPIO_LOW == pinstat->val) {
GPIO_PinWrite(index->gpio, index->pin, 0);
} else {
GPIO_PinWrite(index->gpio, index->pin, 1);
}
return EOK;
}
uint32 Stm32PinRead(void *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
NULL_PARAM_CHECK(read_param);
struct PinStat *pinstat = (struct PinStat *)read_param->buffer;
const struct PinIndex* index = GetPin(pinstat->pin);
NULL_PARAM_CHECK(index);
if(GPIO_PinRead(index->gpio, index->pin) == GPIO_LOW) {
pinstat->val = GPIO_LOW;
} else {
pinstat->val = GPIO_HIGH;
}
return pinstat->val;
}
static const struct PinDevDone dev_done =
{
.open = NONE,
.close = NONE,
.write = Stm32PinWrite,
.read = Stm32PinRead,
};
int Stm32HwGpioInit(void)
{
x_err_t ret = EOK;
static struct PinBus pin;
ret = PinBusInit(&pin, PIN_BUS_NAME);
if (ret != EOK) {
KPrintf("gpio bus init error %d\n", ret);
return ERROR;
}
static struct PinDriver drv;
drv.configure = &Stm32GpioDrvConfigure;
ret = PinDriverInit(&drv, PIN_DRIVER_NAME, NONE);
if (ret != EOK) {
KPrintf("pin driver init error %d\n", ret);
return ERROR;
}
ret = PinDriverAttachToBus(PIN_DRIVER_NAME, PIN_BUS_NAME);
if (ret != EOK) {
KPrintf("pin driver attach error %d\n", ret);
return ERROR;
}
static struct PinHardwareDevice dev;
dev.dev_done = &dev_done;
ret = PinDeviceRegister(&dev, NONE, PIN_DEVICE_NAME);
if (ret != EOK) {
KPrintf("pin device register error %d\n", ret);
return ERROR;
}
ret = PinDeviceAttachToBus(PIN_DEVICE_NAME, PIN_BUS_NAME);
if (ret != EOK) {
KPrintf("pin device register error %d\n", ret);
return ERROR;
}
return ret;
}
static __inline void PinIrqHdr(int irqno)
{
const struct PinIndex* index = GetPin(irqno);
const struct PinIrq *irq;
irq = GetPinIrq(index->pin);
NULL_PARAM_CHECK(irq);
GPIO_ClearPinsInterruptFlags(index->gpio, index->pin);
if (pin_irq_hdr_tab[irqno].hdr){
pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
}
}
void EXTI0_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(0);
}
DECLARE_HW_IRQ(GPIO1_INT0_IRQn, EXTI0_IRQHandler, NONE);
void EXTI1_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(1);
}
DECLARE_HW_IRQ(GPIO1_INT1_IRQn, EXTI1_IRQHandler, NONE);
void EXTI2_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(2);
}
DECLARE_HW_IRQ(GPIO1_INT2_IRQn, EXTI2_IRQHandler, NONE);
void EXTI3_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(3);
}
DECLARE_HW_IRQ(GPIO1_INT3_IRQn, EXTI3_IRQHandler, NONE);
void EXTI4_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(4);
}
DECLARE_HW_IRQ(GPIO1_INT4_IRQn, EXTI4_IRQHandler, NONE);
void EXTI5_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(5);
}
DECLARE_HW_IRQ(GPIO1_INT5_IRQn, EXTI5_IRQHandler, NONE);
void EXTI6_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(6);
}
DECLARE_HW_IRQ(GPIO1_INT6_IRQn, EXTI6_IRQHandler, NONE);
void EXTI7_IRQHandler(int irq_num, void *arg)
{
PinIrqHdr(7);
}
DECLARE_HW_IRQ(GPIO1_INT7_IRQn, EXTI7_IRQHandler, NONE);

View File

@ -0,0 +1,12 @@
if BSP_USING_I2C
config I2C_BUS_NAME_1
string "i2c bus 1 name"
default "i2c1"
config I2C_DRV_NAME_1
string "i2c bus 1 driver name"
default "i2c1_drv"
config I2C_1_DEVICE_NAME_0
string "i2c bus 1 device 0 name"
default "i2c1_dev0"
endif

View File

@ -0,0 +1,3 @@
SRC_FILES := connect_i2c.c i2c_eeprom.c i2c_eeprom_test.c fsl_lpi2c.c i2c_rtc_rx8010.c i2c_rtc_rx8010_test.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,200 @@
/*
* Copyright (c) 2020 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2012-04-25 weety first version
*/
/**
* @file connect_i2c.c
* @brief support stm32f407-st-discovery-board i2c function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: connect_i2c.c
Description: support stm32f407-st-discovery-board i2c configure and i2c bus register function
Others: take RT-Thread v4.0.2/components/drivers/i2c/i2c-bit-ops.c for references
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. support stm32f407-st-discovery-board i2c bit configure, write and read
2. support stm32f407-st-discovery-board i2c bus device and driver register
*************************************************/
#include <board.h>
#include "connect_i2c.h"
#include "bus_serial.h"
#include "i2c_rtc_rx8010.h"
#include "i2c_eeprom.h"
#ifndef BSP_USING_I2C1
#define BSP_USING_I2C1
#endif
static uint32 I2cWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
{
int32 ret;
if(i2c_dev->i2c_dev_addr == I2C_RTC_ADDR){
ret = rx8010_set_time(msg->buf);
} else if(i2c_dev->i2c_dev_addr == I2C_EEPROM_ADDR) {
ret = eeprom_write(msg->buf);
}
return ret;
}
static uint32 I2cReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
{
int32 ret;
if(i2c_dev->i2c_dev_addr == I2C_RTC_ADDR){
ret = rx8010_get_time();
} else if(i2c_dev->i2c_dev_addr == I2C_EEPROM_ADDR) {
ret = eeprom_read(msg->buf);
}
return ret;
}
static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(i2c_drv);
struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)i2c_drv->driver.owner_bus->owner_haldev;
if (configure_info->private_data) {
i2c_dev->i2c_dev_addr = *((uint16 *)configure_info->private_data);
return EOK;
}
KPrintf("I2cInit need set i2c dev addr\n");
return ERROR;
}
static uint32 I2cDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
{
NULL_PARAM_CHECK(drv);
NULL_PARAM_CHECK(configure_info);
x_err_t ret = EOK;
struct I2cDriver *i2c_drv = (struct I2cDriver *)drv;
switch (configure_info->configure_cmd)
{
case OPE_INT:
ret = I2cInit(i2c_drv, configure_info);
break;
default:
break;
}
return ret;
}
/*manage the i2c device operations*/
static const struct I2cDevDone i2c_dev_done =
{
.dev_open = NONE,
.dev_close = NONE,
.dev_write = I2cWriteData,
.dev_read = I2cReadData,
};
/*Init i2c bus*/
static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver)
{
x_err_t ret = EOK;
/*Init the i2c bus */
i2c_bus->private_data = (void *)NULL;
ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_i2c_init I2cBusInit error %d\n", ret);
return ERROR;
}
/*Init the i2c driver*/
i2c_driver->private_data = (void *)NULL;
ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1);
if (EOK != ret) {
KPrintf("board_i2c_init I2cDriverInit error %d\n", ret);
return ERROR;
}
/*Attach the i2c driver to the i2c bus*/
ret = I2cDriverAttachToBus(I2C_DRV_NAME_1, I2C_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_i2c_init I2cDriverAttachToBus error %d\n", ret);
return ERROR;
}
return ret;
}
/*Attach the i2c device to the i2c bus*/
static int BoardI2cDevBend(void)
{
x_err_t ret = EOK;
static struct I2cHardwareDevice i2c_device0;
memset(&i2c_device0, 0, sizeof(struct I2cHardwareDevice));
i2c_device0.i2c_dev_done = &i2c_dev_done;
ret = I2cDeviceRegister(&i2c_device0, NONE, I2C_1_DEVICE_NAME_0);
if (EOK != ret) {
KPrintf("board_i2c_init I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
return ERROR;
}
ret = I2cDeviceAttachToBus(I2C_1_DEVICE_NAME_0, I2C_BUS_NAME_1);
if (EOK != ret) {
KPrintf("board_i2c_init I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret);
return ERROR;
}
return ret;
}
/*BOARD I2C INIT*/
int Stm32HwI2cInit(void)
{
static int init_flag = 0;
x_err_t ret = EOK;
if(init_flag)
{
return ret;
}
init_flag = 1;
static struct I2cBus i2c_bus;
memset(&i2c_bus, 0, sizeof(struct I2cBus));
static struct I2cDriver i2c_driver;
memset(&i2c_driver, 0, sizeof(struct I2cDriver));
#ifdef BSP_USING_I2C1
i2c_driver.configure = I2cDrvConfigure;
ret = BoardI2cBusInit(&i2c_bus, &i2c_driver);
if (EOK != ret) {
KPrintf("board_i2c_Init error ret %u\n", ret);
return ERROR;
}
ret = BoardI2cDevBend();
if (EOK != ret) {
KPrintf("board_i2c_Init error ret %u\n", ret);
return ERROR;
}
#endif
return ret;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,110 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "fsl_common.h"
#include "fsl_lpi2c.h"
#include "i2c_eeprom.h"
/////////////////////////////EEPROM INIT/////////////////////////////////////////
void I2C_EEPROM_Init()
{
lpi2c_master_config_t masterConfig = {0};
/*
* masterConfig.debugEnable = false;
* masterConfig.ignoreAck = false;
* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
* masterConfig.baudRate_Hz = 100000U;
* masterConfig.busIdleTimeout_ns = 0;
* masterConfig.pinLowTimeout_ns = 0;
* masterConfig.sdaGlitchFilterWidth_ns = 0;
* masterConfig.sclGlitchFilterWidth_ns = 0;
*/
LPI2C_MasterGetDefaultConfig(&masterConfig);
/* Change the default baudrate configuration */
masterConfig.baudRate_Hz = I2C_EEPROM_BAUDRATE;
/* Initialize the LPI2C master peripheral */
LPI2C_MasterInit(I2C_EEPROM_BASE, &masterConfig, I2C_EEPROM_CLOCK_FREQ);
}
//struct _lpi2c_master_transfer
//{
// uint32_t
// flags; /*!< Bit mask of options for the transfer. See enumeration #_lpi2c_master_transfer_flags for available
// options. Set to 0 or #kLPI2C_TransferDefaultFlag for normal transfers. */
// uint16_t slaveAddress; /*!< The 7-bit slave address. */
// lpi2c_direction_t direction; /*!< Either #kLPI2C_Read or #kLPI2C_Write. */
// uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
// size_t subaddressSize; /*!< Length of sub address to send in bytes. Maximum size is 4 bytes. */
// void *data; /*!< Pointer to data to transfer. */
// size_t dataSize; /*!< Number of bytes to transfer. */
//};
status_t I2C_EEPROM_Write(LPI2C_Type* base, uint32_t subAdd, uint8_t* dataBuff, uint16_t dataLen)
{
// lpi2c_master_transfer_t *xfer = &(handle->xfer);
lpi2c_master_transfer_t xfer;
status_t status;
xfer.slaveAddress =(0xA0 >> 1);
xfer.direction = kLPI2C_Write;
xfer.subaddress = subAdd;
xfer.subaddressSize = 0x01;
xfer.data = dataBuff;
xfer.dataSize = dataLen;
xfer.flags = kLPI2C_TransferDefaultFlag;
status = LPI2C_MasterTransferBlocking(base, &xfer);
return status;
}
uint32_t I2C_EEPROM_Read(LPI2C_Type* base, uint32_t subAdd, uint8_t* dataBuffer, uint16_t dataLen)
{
lpi2c_master_transfer_t masterXfer = {0};
status_t reVal = kStatus_Fail;
masterXfer.slaveAddress =(0XA0>>1);
masterXfer.direction = kLPI2C_Read;
masterXfer.subaddress = subAdd;
masterXfer.subaddressSize = 0x01;
masterXfer.data = dataBuffer;
masterXfer.dataSize = dataLen;
masterXfer.flags = kLPI2C_TransferDefaultFlag;
reVal = LPI2C_MasterTransferBlocking(base, &masterXfer);
if(reVal != kStatus_Success)
{
return 1;
}
return 0;
}

View File

@ -0,0 +1,27 @@
#ifndef __I2C_EEPROM_H_
#define __I2C_EEPROM_H_
#include "fsl_common.h"
/* Macros for the touch touch controller. */
#define I2C_EEPROM_BASE LPI2C1
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
#define I2C_EEPROM_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
#define I2C_EEPROM_BAUDRATE 100000U
void I2C_EEPROM_Init ( void );
status_t I2C_EEPROM_Write ( LPI2C_Type* base,uint32_t subAdd,uint8_t* dataBuff,uint16_t dataLen );
uint32_t I2C_EEPROM_Read ( LPI2C_Type* base,uint32_t subAdd,uint8_t* dataBuff, uint16_t dataLen );
int eeprom_read(uint8_t *dat);
int eeprom_write(uint8_t *dat);
#endif

View File

@ -0,0 +1,135 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_iomuxc.h"
#include "fsl_gpio.h"
#include "connect_i2c.h"
#include "fsl_lpi2c.h"
#include "i2c_eeprom.h"
#include "pin_mux.h"
#include "clock_config.h"
#include <device.h>
#include <bus.h>
/*******************************************************************************
* Definitions
******************************************************************************/
#define i2c_print KPrintf
#define EE_I2C_BUS_NAME I2C_BUS_NAME_1 /* I2C bus name */
#define EE_I2C_DEV_NAME I2C_1_DEVICE_NAME_0 /* I2C device name */
#define EE_I2C_DRV_NAME I2C_DRV_NAME_1 /* I2C driver name */
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief delay a while.
*/
void I2C_EEPROM_TEST(void);
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
int eeprom_read(uint8_t *dat)
{
uint32_t ret;
ret = I2C_EEPROM_Read(I2C_EEPROM_BASE, 0, dat, 8);
return ret;
}
int eeprom_write(uint8_t *dat)
{
uint32_t ret;
ret = I2C_EEPROM_Write(I2C_EEPROM_BASE, 0, dat, 8);
return ret;
}
/*!
* @brief I2C_EEPROM_TEST: Write and Read
*/
void I2C_EEPROM_TEST(void)
{
uint8_t dat[8] = {0};
if(!I2C_EEPROM_Read(I2C_EEPROM_BASE, 0, dat, 8))
{
i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n",
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
}
for(uint8_t i = 0; i < 8; i++)
{
dat[i] = 1;
}
if(!I2C_EEPROM_Write(I2C_EEPROM_BASE, 0, dat, 8))
{
i2c_print("Write to EEPROM %d %d %d %d %d %d %d %d\r\n",
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
}
memset(dat, 0, 8);
if(!I2C_EEPROM_Read(I2C_EEPROM_BASE, 0, dat, 8))
{
i2c_print("Read from EEPROM %d %d %d %d %d %d %d %d\r\n",
dat[0], dat[1], dat[2], dat[3], dat[4], dat[5], dat[6], dat[7]);
}
}
int test_eerpom(void)
{
Stm32HwI2cInit();
BOARD_InitI2C1Pins();
I2C_EEPROM_Init();
I2C_EEPROM_TEST();
return 0;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(0),
eeprom, test_eerpom, i2c eeprom);

View File

@ -0,0 +1,127 @@
/*
* The Clear BSD License
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file i2c_RTC_RX8010.c
* @brief I2C RTC drivers
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.1.18
*/
#include "fsl_common.h"
#include "fsl_debug_console.h"
#include "fsl_lpi2c.h"
#include "i2c_rtc_rx8010.h"
/////////////////////////////EEPROM INIT/////////////////////////////////////////
void I2C_Init()
{
lpi2c_master_config_t masterConfig = {0};
/*
* masterConfig.debugEnable = false;
* masterConfig.ignoreAck = false;
* masterConfig.pinConfig = kLPI2C_2PinOpenDrain;
* masterConfig.baudRate_Hz = 100000U;
* masterConfig.busIdleTimeout_ns = 0;
* masterConfig.pinLowTimeout_ns = 0;
* masterConfig.sdaGlitchFilterWidth_ns = 0;
* masterConfig.sclGlitchFilterWidth_ns = 0;
*/
LPI2C_MasterGetDefaultConfig(&masterConfig);
/* Change the default baudrate configuration */
masterConfig.baudRate_Hz = I2C_BAUDRATE;
/* Initialize the LPI2C master peripheral */
LPI2C_MasterInit(I2C_BASE, &masterConfig, I2C_CLOCK_FREQ);
}
//struct _lpi2c_master_transfer
//{
// uint32_t
// flags; /*!< Bit mask of options for the transfer. See enumeration #_lpi2c_master_transfer_flags for available
// options. Set to 0 or #kLPI2C_TransferDefaultFlag for normal transfers. */
// uint16_t slaveAddress; /*!< The 7-bit slave address. */
// lpi2c_direction_t direction; /*!< Either #kLPI2C_Read or #kLPI2C_Write. */
// uint32_t subaddress; /*!< Sub address. Transferred MSB first. */
// size_t subaddressSize; /*!< Length of sub address to send in bytes. Maximum size is 4 bytes. */
// void *data; /*!< Pointer to data to transfer. */
// size_t dataSize; /*!< Number of bytes to transfer. */
//};
status_t I2C_Write(LPI2C_Type *base,uint32_t subAdd,uint8_t *dataBuff,uint16_t dataLen)
{
// lpi2c_master_transfer_t *xfer = &(handle->xfer);
lpi2c_master_transfer_t xfer;
status_t status;
xfer.slaveAddress = 0x32; ////RX8010 SLEVEADDRESS 7BIT
xfer.direction = kLPI2C_Write;
xfer.subaddress = subAdd;
xfer.subaddressSize = 0x01;
xfer.data = dataBuff;
xfer.dataSize = dataLen;
xfer.flags = kLPI2C_TransferDefaultFlag;
status = LPI2C_MasterTransferBlocking(base, &xfer);
return status;
}
uint32_t I2C_Read(LPI2C_Type *base,uint32_t subAdd,uint8_t* dataBuffer, uint16_t dataLen)
{
lpi2c_master_transfer_t masterXfer = {0};
status_t reVal = kStatus_Fail;
masterXfer.slaveAddress = 0x32;
masterXfer.direction = kLPI2C_Read;
masterXfer.subaddress = subAdd;
masterXfer.subaddressSize = 0x01;
masterXfer.data = dataBuffer;
masterXfer.dataSize = dataLen;
masterXfer.flags = kLPI2C_TransferDefaultFlag;
reVal = LPI2C_MasterTransferBlocking(base, &masterXfer);
if (reVal != kStatus_Success)
{
return 1;
}
return 0;
}

View File

@ -0,0 +1,27 @@
#ifndef __I2C_RTC_RX8010_H_
#define __I2C_RTC_RX8010_H_
#include "fsl_common.h"
/* Macros for the touch touch controller. */
#define I2C_BASE LPI2C1
/* Select USB1 PLL (480 MHz) as master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_SELECT (0U)
/* Clock divider for master lpi2c clock source */
#define LPI2C_CLOCK_SOURCE_DIVIDER (5U)
#define I2C_CLOCK_FREQ ((CLOCK_GetFreq(kCLOCK_Usb1PllClk) / 8) / (LPI2C_CLOCK_SOURCE_DIVIDER + 1U))
#define I2C_BAUDRATE 100000U
#define I2C_RTC_ADDR 0x32
#define I2C_EEPROM_ADDR 0x0
void I2C_Init(void);
status_t I2C_Write(LPI2C_Type *base,uint32_t subAdd,uint8_t *dataBuff,uint16_t dataLen);
uint32_t I2C_Read(LPI2C_Type *base,uint32_t subAdd,uint8_t* dataBuff, uint16_t dataLen);
int rx8010_set_time(uint8_t* asc_date);
int rx8010_get_time(void);
#endif

View File

@ -0,0 +1,295 @@
/*
* The Clear BSD License
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted (subject to the limitations in the disclaimer below) provided
* that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* o Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "board.h"
#include "fsl_debug_console.h"
#include "fsl_lpi2c.h"
#include "i2c_rtc_rx8010.h"
#include "pin_mux.h"
#include "clock_config.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define EXAMPLE_DELAY_COUNT 8000000
#undef GETCHAR
#define GETCHAR getchar
#undef PUTCHAR
#define PUTCHAR putchar
#define rtc_print KPrintf
///////////RX8010///////////
#define RX8010_SEC 0x10
#define RX8010_MIN 0x11
#define RX8010_HOUR 0x12
#define RX8010_WDAY 0x13
#define RX8010_MDAY 0x14
#define RX8010_MONTH 0x15
#define RX8010_YEAR 0x16
#define RX8010_YEAR 0x16
#define RX8010_RESV17 0x17
#define RX8010_ALMIN 0x18
#define RX8010_ALHOUR 0x19
#define RX8010_ALWDAY 0x1A
#define RX8010_TCOUNT0 0x1B
#define RX8010_TCOUNT1 0x1C
#define RX8010_EXT 0x1D
#define RX8010_FLAG 0x1E
#define RX8010_CTRL 0x1F
/* 0x20 to 0x2F are user registers */
#define RX8010_RESV30 0x30
#define RX8010_RESV31 0x31
#define RX8010_IRQ 0x32
#define RX8010_EXT_WADA 0x04 //BIT(3)
#define RX8010_FLAG_VLF 0x02 //BIT(1)
#define RX8010_FLAG_AF 0x04 //BIT(3)
#define RX8010_FLAG_TF 0x08 //BIT(4)
#define RX8010_FLAG_UF 0x10 //BIT(5)
#define RX8010_CTRL_AIE 0x04 //BIT(3)
#define RX8010_CTRL_UIE 0x10 //BIT(5)
#define RX8010_CTRL_STOP 0x20 //BIT(6)
#define RX8010_CTRL_TEST 0x40 //BIT(7)
#define RX8010_ALARM_AE 0x40 //BIT(7)
#define RX8010_TEST_TIME 10000
#define BCD_DATA_LEN 20
// change BIN format to BCD format
#define TO_BCD(_n) (((_n / 10) << 4) | (_n % 10))
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
/*******************************************************************************
* Code
******************************************************************************/
// change BCD format date to BIN format
uint8_t bcd2bin(uint8_t data)
{
int i = 0;
uint8_t ret = 0;
uint8_t mask[4] = {0x01, 0x02, 0x04, 0x08};
//LOW
for(i = 0; i < 4; i++)
{
if(mask[i] & data)
{
ret += mask[i];
}
}
//HIGH
for(i = 0; i < 4; i++)
{
if(mask[i] & (data >> 4))
{
ret += (mask[i] * 10);
}
}
return ret;
}
// 8010 initialization
int rx8010_init(void)
{
uint8_t flag = 0;
uint8_t data = 0;
uint8_t ctrl[2];
int need_clear = 0, err = 0;
err = I2C_Read(I2C_BASE, RX8010_FLAG, &flag, 1);
flag &= ~(RX8010_FLAG_VLF);
err = I2C_Write(I2C_BASE, RX8010_FLAG, &flag, 1);
/* Initialize reserved registers as specified in datasheet */
data = 0xD8;
err = I2C_Write(I2C_BASE, RX8010_RESV17, &data, 1);
data = 0x00;
err = I2C_Write(I2C_BASE, RX8010_RESV30, &data, 1);
data = 0x08;
err = I2C_Write(I2C_BASE, RX8010_RESV31, &data, 1);
data = 0x00;
err = I2C_Write(I2C_BASE, RX8010_IRQ, &data, 1);
err = I2C_Read(I2C_BASE, RX8010_FLAG, ctrl, 2);
if(ctrl[0] & RX8010_FLAG_VLF)
{
rtc_print("\r\n Frequency stop was detected\r\n");
}
if(ctrl[0] & RX8010_FLAG_AF)
{
rtc_print("\r\n Alarm was detected\r\n");
need_clear = 1;
}
if(ctrl[0] & RX8010_FLAG_TF)
{
need_clear = 1;
}
if(ctrl[0] & RX8010_FLAG_UF)
{
need_clear = 1;
}
if(need_clear)
{
ctrl[0] &= ~(RX8010_FLAG_AF | RX8010_FLAG_TF | RX8010_FLAG_UF);
err = I2C_Write(I2C_BASE, RX8010_FLAG, ctrl,1);
if(!err)
{
return err;
}
}
return err;
}
// check format and get BCD format date like 2018-06-21 16:29:30
int get_bcd_date(uint8_t* date, uint8_t* bcd_date)
{
int i;
int temp_date[6];
if(sscanf(date, "20%2d-%2d-%2d %2d:%2d:%2d",
&temp_date[5],
&temp_date[4],
&temp_date[3],
&temp_date[2],
&temp_date[1],
&temp_date[0]) == EOF)
{
rtc_print("i2c %s failed\n", __func__);
return -1;
}
for(i = 0; i < 6; i++)
{
bcd_date[i] = TO_BCD(temp_date[i]);
}
return 0;
}
// setup time
int rx8010_set_time(uint8_t* asc_date)
{
uint8_t bcd_date[6];
int ret, err;
if(get_bcd_date(asc_date, bcd_date))
{
rtc_print("\r\n Date format error! \r\n");
return -1;
}
err = I2C_Write(I2C_BASE, RX8010_SEC, bcd_date, 3);
err |= I2C_Write(I2C_BASE, RX8010_MDAY, &bcd_date[3], 3);
return err;
}
// get rx8010 time
int rx8010_get_time(void)
{
uint8_t date[7];
uint8_t dateRsul[7];
uint8_t flagreg;
int err;
err = I2C_Read(I2C_BASE, RX8010_FLAG, &flagreg, 1);
if(flagreg & RX8010_FLAG_VLF)
{
rtc_print("\r\n Frequency stop was detected\r\n");
return 1;
}
err = I2C_Read(I2C_BASE, RX8010_SEC, date, 7);
dateRsul[0] = bcd2bin(date[RX8010_SEC - RX8010_SEC] & 0x7f);
dateRsul[1] = bcd2bin(date[RX8010_MIN - RX8010_SEC] & 0x7f);
dateRsul[2] = bcd2bin(date[RX8010_HOUR - RX8010_SEC] & 0x3f);
dateRsul[4] = bcd2bin(date[RX8010_MDAY - RX8010_SEC] & 0x3f);
dateRsul[5] = bcd2bin(date[RX8010_MONTH - RX8010_SEC] & 0x1f);
dateRsul[6] = bcd2bin(date[RX8010_YEAR - RX8010_SEC]);
dateRsul[3] = date[RX8010_WDAY - RX8010_SEC] & 0x7f;
rtc_print("RX8010 Time: 20%d%d-%d%d-%d%d %d%d:%d%d:%d%d\r\n",
dateRsul[6]/10, dateRsul[6]%10, dateRsul[5]/10, dateRsul[5]%10, dateRsul[4]/10, dateRsul[4]%10,
dateRsul[2]/10, dateRsul[2]%10, dateRsul[1]/10, dateRsul[1]%10, dateRsul[0]/10, dateRsul[0]%10);
return 0;
}
void test_rtc_rx8010(int argc, char *argv[])
{
BOARD_InitI2C1Pins();
I2C_Init();
rx8010_init();
if(argc == 2)
{
if(rx8010_set_time(argv[1]) == 0)
{
rx8010_get_time();
}
}
else
{
rx8010_get_time();
}
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(3),
rtc, test_rtc_rx8010, i2c rtc "date time");

View File

@ -144,6 +144,8 @@
#define FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE (0)
/* @brief Remove ALT Clock selection feature. */
#define FSL_FEATURE_ADC_SUPPORT_ALTCLK_REMOVE (1)
/* @brief Conversion control count (related to number of registers HCn and Rn). */
#define FSL_FEATURE_ADC_CONVERSION_CONTROL_COUNT (8)
/* ADC_ETC module features */

View File

@ -63,8 +63,6 @@
/* Exported functions ------------------------------------------------------- */
void enet_delay(void);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file connect_i2c.h
* @brief define stm32f407-st-discovery-board i2c function and struct
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
#ifndef CONNECT_I2C_H
#define CONNECT_I2C_H
#include <device.h>
#ifdef __cplusplus
extern "C" {
#endif
int Stm32HwI2cInit(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -38,18 +38,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file enet_ethernetif.h
* @brief ethernet drivers

View File

@ -5,18 +5,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file enet_ethernetif_priv.h
* @brief ethernet drivers

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_cache.h
* @brief cache drivers

View File

@ -5,18 +5,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_clock.h
* @brief clock drivers

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_common.h
* @brief common drivers header

View File

@ -23,7 +23,7 @@
#define _FSL_DEBUGCONSOLE_H_
#include "fsl_common.h"
//#include "serial_manager.h"
#include "serial_manager.h"
/*!
* @addtogroup debugconsole

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_enet.h
* @brief ethernet drivers

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_iomuxc.h
* @brief io mux drivers

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_lpuart.h
* @brief fsl uart drivers

View File

@ -0,0 +1,548 @@
/*
* Copyright 2018 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __SERIAL_MANAGER_H__
#define __SERIAL_MANAGER_H__
/*!
* @addtogroup serialmanager
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
#ifdef DEBUG_CONSOLE_TRANSFER_NON_BLOCKING
/*! @brief Enable or disable serial manager non-blocking mode (1 - enable, 0 - disable) */
#define SERIAL_MANAGER_NON_BLOCKING_MODE (1U)
#else
#ifndef SERIAL_MANAGER_NON_BLOCKING_MODE
#define SERIAL_MANAGER_NON_BLOCKING_MODE (0U)
#endif
#endif
/*! @brief Enable or disable uart port (1 - enable, 0 - disable) */
#ifndef SERIAL_PORT_TYPE_UART
#define SERIAL_PORT_TYPE_UART (1U)
#endif
/*! @brief Enable or disable USB CDC port (1 - enable, 0 - disable) */
#ifndef SERIAL_PORT_TYPE_USBCDC
#define SERIAL_PORT_TYPE_USBCDC (0U)
#endif
/*! @brief Enable or disable SWO port (1 - enable, 0 - disable) */
#ifndef SERIAL_PORT_TYPE_SWO
#define SERIAL_PORT_TYPE_SWO (0U)
#endif
/*! @brief Enable or disable USB CDC virtual port (1 - enable, 0 - disable) */
#ifndef SERIAL_PORT_TYPE_USBCDC_VIRTUAL
#define SERIAL_PORT_TYPE_USBCDC_VIRTUAL (0U)
#endif
/*! @brief Set serial manager write handle size */
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
#define SERIAL_MANAGER_WRITE_HANDLE_SIZE (44U)
#define SERIAL_MANAGER_READ_HANDLE_SIZE (44U)
#else
#define SERIAL_MANAGER_WRITE_HANDLE_SIZE (4U)
#define SERIAL_MANAGER_READ_HANDLE_SIZE (4U)
#endif
#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
#include "serial_port_uart.h"
#endif
#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
#error The serial manager blocking mode cannot be supported for USB CDC.
#endif
#include "serial_port_usb.h"
#endif
#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
#include "serial_port_swo.h"
#endif
#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
#if !(defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
#error The serial manager blocking mode cannot be supported for USB CDC.
#endif
#include "serial_port_usb_virtual.h"
#endif
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP 0U
#if (defined(SERIAL_PORT_TYPE_UART) && (SERIAL_PORT_TYPE_UART > 0U))
#if (SERIAL_PORT_UART_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_UART_HANDLE_SIZE
#endif
#endif
#if (defined(SERIAL_PORT_TYPE_USBCDC) && (SERIAL_PORT_TYPE_USBCDC > 0U))
#if (SERIAL_PORT_USB_CDC_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_CDC_HANDLE_SIZE
#endif
#endif
#if (defined(SERIAL_PORT_TYPE_SWO) && (SERIAL_PORT_TYPE_SWO > 0U))
#if (SERIAL_PORT_SWO_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_SWO_HANDLE_SIZE
#endif
#endif
#if (defined(SERIAL_PORT_TYPE_USBCDC_VIRTUAL) && (SERIAL_PORT_TYPE_USBCDC_VIRTUAL > 0U))
#if (SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE > SERIAL_MANAGER_HANDLE_SIZE_TEMP)
#undef SERIAL_MANAGER_HANDLE_SIZE_TEMP
#define SERIAL_MANAGER_HANDLE_SIZE_TEMP SERIAL_PORT_USB_VIRTUAL_HANDLE_SIZE
#endif
#endif
/*! @brief SERIAL_PORT_UART_HANDLE_SIZE/SERIAL_PORT_USB_CDC_HANDLE_SIZE + serial manager dedicated size */
#if ((defined(SERIAL_MANAGER_HANDLE_SIZE_TEMP) && (SERIAL_MANAGER_HANDLE_SIZE_TEMP > 0U)))
#else
#error SERIAL_PORT_TYPE_UART, SERIAL_PORT_TYPE_USBCDC, SERIAL_PORT_TYPE_SWO and SERIAL_PORT_TYPE_USBCDC_VIRTUAL should not be cleared at same time.
#endif
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
#define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 120U)
#else
#define SERIAL_MANAGER_HANDLE_SIZE (SERIAL_MANAGER_HANDLE_SIZE_TEMP + 12U)
#endif
#define SERIAL_MANAGER_USE_COMMON_TASK (1U)
#define SERIAL_MANAGER_TASK_PRIORITY (2U)
#define SERIAL_MANAGER_TASK_STACK_SIZE (1000U)
typedef void *serial_handle_t;
typedef void *serial_write_handle_t;
typedef void *serial_read_handle_t;
/*! @brief serial port type*/
typedef enum _serial_port_type
{
kSerialPort_Uart = 1U, /*!< Serial port UART */
kSerialPort_UsbCdc, /*!< Serial port USB CDC */
kSerialPort_Swo, /*!< Serial port SWO */
kSerialPort_UsbCdcVirtual, /*!< Serial port USB CDC Virtual */
} serial_port_type_t;
/*! @brief serial manager config structure*/
typedef struct _serial_manager_config
{
uint8_t *ringBuffer; /*!< Ring buffer address, it is used to buffer data received by the hardware.
Besides, the memory space cannot be free during the lifetime of the serial
manager module. */
uint32_t ringBufferSize; /*!< The size of the ring buffer */
serial_port_type_t type; /*!< Serial port type */
void *portConfig; /*!< Serial port configuration */
} serial_manager_config_t;
/*! @brief serial manager error code*/
typedef enum _serial_manager_status
{
kStatus_SerialManager_Success = kStatus_Success, /*!< Success */
kStatus_SerialManager_Error = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 1), /*!< Failed */
kStatus_SerialManager_Busy = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 2), /*!< Busy */
kStatus_SerialManager_Notify = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 3), /*!< Ring buffer is not empty */
kStatus_SerialManager_Canceled =
MAKE_STATUS(kStatusGroup_SERIALMANAGER, 4), /*!< the non-blocking request is canceled */
kStatus_SerialManager_HandleConflict = MAKE_STATUS(kStatusGroup_SERIALMANAGER, 5), /*!< The handle is opened */
kStatus_SerialManager_RingBufferOverflow =
MAKE_STATUS(kStatusGroup_SERIALMANAGER, 6), /*!< The ring buffer is overflowed */
} serial_manager_status_t;
/*! @brief Callback message structure */
typedef struct _serial_manager_callback_message
{
uint8_t *buffer; /*!< Transferred buffer */
uint32_t length; /*!< Transferred data length */
} serial_manager_callback_message_t;
/*! @brief callback function */
typedef void (*serial_manager_callback_t)(void *callbackParam,
serial_manager_callback_message_t *message,
serial_manager_status_t status);
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /* _cplusplus */
/*!
* @brief Initializes a serial manager module with the serial manager handle and the user configuration structure.
*
* This function configures the Serial Manager module with user-defined settings. The user can configure the
* configuration
* structure. The parameter serialHandle is a pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE
* allocated by the caller.
* The Serial Manager module supports two types of serial port, UART (includes UART, USART, LPSCI, LPUART, etc) and USB
* CDC.
* Please refer to #serial_port_type_t for serial port setting. These two types can be set by using
* #serial_manager_config_t.
*
* Example below shows how to use this API to configure the Serial Manager.
* For UART,
* @code
* #define SERIAL_MANAGER_RING_BUFFER_SIZE (256U)
* static uint8_t s_serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
* static serial_handle_t s_serialHandle = &s_serialHandleBuffer[0];
* static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
*
* serial_manager_config_t config;
* serial_port_uart_config_t uartConfig;
* config.type = kSerialPort_Uart;
* config.ringBuffer = &s_ringBuffer[0];
* config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
* uartConfig.instance = 0;
* uartConfig.clockRate = 24000000;
* uartConfig.baudRate = 115200;
* uartConfig.parityMode = kSerialManager_UartParityDisabled;
* uartConfig.stopBitCount = kSerialManager_UartOneStopBit;
* uartConfig.enableRx = 1;
* uartConfig.enableTx = 1;
* config.portConfig = &uartConfig;
* SerialManager_Init(s_serialHandle, &config);
* @endcode
* For USB CDC,
* @code
* #define SERIAL_MANAGER_RING_BUFFER_SIZE (256U)
* static uint8_t s_serialHandleBuffer[SERIAL_MANAGER_HANDLE_SIZE];
* static serial_handle_t s_serialHandle = &s_serialHandleBuffer[0];
* static uint8_t s_ringBuffer[SERIAL_MANAGER_RING_BUFFER_SIZE];
*
* serial_manager_config_t config;
* serial_port_usb_cdc_config_t usbCdcConfig;
* config.type = kSerialPort_UsbCdc;
* config.ringBuffer = &s_ringBuffer[0];
* config.ringBufferSize = SERIAL_MANAGER_RING_BUFFER_SIZE;
* usbCdcConfig.controllerIndex = kSerialManager_UsbControllerKhci0;
* config.portConfig = &usbCdcConfig;
* SerialManager_Init(s_serialHandle, &config);
* @endcode
*
* @param serialHandle Pointer to point to a memory space of size #SERIAL_MANAGER_HANDLE_SIZE allocated by the caller.
* @param config Pointer to user-defined configuration structure.
* @retval kStatus_SerialManager_Error An error occurred.
* @retval kStatus_SerialManager_Success The Serial Manager module initialization succeed.
*/
serial_manager_status_t SerialManager_Init(serial_handle_t serialHandle, serial_manager_config_t *config);
/*!
* @brief De-initializes the serial manager module instance.
*
* This function de-initializes the serial manager module instance. If the opened writing or
* reading handle is not closed, the function will return kStatus_SerialManager_Busy.
*
* @param serialHandle The serial manager module handle pointer.
* @retval kStatus_SerialManager_Success The serial manager de-initialization succeed.
* @retval kStatus_SerialManager_Busy Opened reading or writing handle is not closed.
*/
serial_manager_status_t SerialManager_Deinit(serial_handle_t serialHandle);
/*!
* @brief Opens a writing handle for the serial manager module.
*
* This function Opens a writing handle for the serial manager module. If the serial manager needs to
* be used in different tasks, the task should open a dedicated write handle for itself by calling
* #SerialManager_OpenWriteHandle. Since there can only one buffer for transmission for the writing
* handle at the same time, multiple writing handles need to be opened when the multiple transmission
* is needed for a task.
*
* @param serialHandle The serial manager module handle pointer.
* @param writeHandle The serial manager module writing handle pointer.
* @retval kStatus_SerialManager_Error An error occurred.
* @retval kStatus_SerialManager_HandleConflict The writing handle was opened.
* @retval kStatus_SerialManager_Success The writing handle is opened.
*
* Example below shows how to use this API to write data.
* For task 1,
* @code
* static uint8_t s_serialWriteHandleBuffer1[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
* static serial_write_handle_t s_serialWriteHandle1 = &s_serialWriteHandleBuffer1[0];
* static uint8_t s_nonBlockingWelcome1[] = "This is non-blocking writing log for task1!\r\n";
* SerialManager_OpenWriteHandle(serialHandle, s_serialWriteHandle1);
* SerialManager_InstallTxCallback(s_serialWriteHandle1, Task1_SerialManagerTxCallback, s_serialWriteHandle1);
* SerialManager_WriteNonBlocking(s_serialWriteHandle1, s_nonBlockingWelcome1, sizeof(s_nonBlockingWelcome1) - 1);
* @endcode
* For task 2,
* @code
* static uint8_t s_serialWriteHandleBuffer2[SERIAL_MANAGER_WRITE_HANDLE_SIZE];
* static serial_write_handle_t s_serialWriteHandle2 = &s_serialWriteHandleBuffer2[0];
* static uint8_t s_nonBlockingWelcome2[] = "This is non-blocking writing log for task2!\r\n";
* SerialManager_OpenWriteHandle(serialHandle, s_serialWriteHandle2);
* SerialManager_InstallTxCallback(s_serialWriteHandle2, Task2_SerialManagerTxCallback, s_serialWriteHandle2);
* SerialManager_WriteNonBlocking(s_serialWriteHandle2, s_nonBlockingWelcome2, sizeof(s_nonBlockingWelcome2) - 1);
* @endcode
*/
serial_manager_status_t SerialManager_OpenWriteHandle(serial_handle_t serialHandle, serial_write_handle_t writeHandle);
/*!
* @brief Closes a writing handle for the serial manager module.
*
* This function Closes a writing handle for the serial manager module.
*
* @param writeHandle The serial manager module writing handle pointer.
* @retval kStatus_SerialManager_Success The writing handle is closed.
*/
serial_manager_status_t SerialManager_CloseWriteHandle(serial_write_handle_t writeHandle);
/*!
* @brief Opens a reading handle for the serial manager module.
*
* This function Opens a reading handle for the serial manager module. The reading handle can not be
* opened multiple at the same time. The error code kStatus_SerialManager_Busy would be returned when
* the previous reading handle is not closed. And There can only be one buffer for receiving for the
* reading handle at the same time.
*
* @param serialHandle The serial manager module handle pointer.
* @param readHandle The serial manager module reading handle pointer.
* @retval kStatus_SerialManager_Error An error occurred.
* @retval kStatus_SerialManager_Success The reading handle is opened.
* @retval kStatus_SerialManager_Busy Previous reading handle is not closed.
*
* Example below shows how to use this API to read data.
* @code
* static uint8_t s_serialReadHandleBuffer[SERIAL_MANAGER_READ_HANDLE_SIZE];
* static serial_read_handle_t s_serialReadHandle = &s_serialReadHandleBuffer[0];
* SerialManager_OpenReadHandle(serialHandle, s_serialReadHandle);
* static uint8_t s_nonBlockingBuffer[64];
* SerialManager_InstallRxCallback(s_serialReadHandle, APP_SerialManagerRxCallback, s_serialReadHandle);
* SerialManager_ReadNonBlocking(s_serialReadHandle, s_nonBlockingBuffer, sizeof(s_nonBlockingBuffer));
* @endcode
*/
serial_manager_status_t SerialManager_OpenReadHandle(serial_handle_t serialHandle, serial_read_handle_t readHandle);
/*!
* @brief Closes a reading for the serial manager module.
*
* This function Closes a reading for the serial manager module.
*
* @param readHandle The serial manager module reading handle pointer.
* @retval kStatus_SerialManager_Success The reading handle is closed.
*/
serial_manager_status_t SerialManager_CloseReadHandle(serial_read_handle_t readHandle);
/*!
* @brief Transmits data with the blocking mode.
*
* This is a blocking function, which polls the sending queue, waits for the sending queue to be empty.
* This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
* And There can only one buffer for transmission for the writing handle at the same time.
*
* @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
* cannot be used at the same time.
* And, the function #SerialManager_CancelWriting cannot be used to abort the transmission of this function.
*
* @param writeHandle The serial manager module handle pointer.
* @param buffer Start address of the data to write.
* @param length Length of the data to write.
* @retval kStatus_SerialManager_Success Successfully sent all data.
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
* @retval kStatus_SerialManager_Error An error occurred.
*/
serial_manager_status_t SerialManager_WriteBlocking(serial_write_handle_t writeHandle,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Reads data with the blocking mode.
*
* This is a blocking function, which polls the receiving buffer, waits for the receiving buffer to be full.
* This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
* And There can only one buffer for receiving for the reading handle at the same time.
*
* @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
* cannot be used at the same time.
* And, the function #SerialManager_CancelReading cannot be used to abort the transmission of this function.
*
* @param readHandle The serial manager module handle pointer.
* @param buffer Start address of the data to store the received data.
* @param length The length of the data to be received.
* @retval kStatus_SerialManager_Success Successfully received all data.
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
* @retval kStatus_SerialManager_Error An error occurred.
*/
serial_manager_status_t SerialManager_ReadBlocking(serial_read_handle_t readHandle, uint8_t *buffer, uint32_t length);
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
/*!
* @brief Transmits data with the non-blocking mode.
*
* This is a non-blocking function, which returns directly without waiting for all data to be sent.
* When all data is sent, the module notifies the upper layer through a TX callback function and passes
* the status parameter @ref kStatus_SerialManager_Success.
* This function sends data using an interrupt method. The interrupt of the hardware could not be disabled.
* And There can only one buffer for transmission for the writing handle at the same time.
*
* @note The function #SerialManager_WriteBlocking and the function #SerialManager_WriteNonBlocking
* cannot be used at the same time. And, the TX callback is mandatory before the function could be used.
*
* @param writeHandle The serial manager module handle pointer.
* @param buffer Start address of the data to write.
* @param length Length of the data to write.
* @retval kStatus_SerialManager_Success Successfully sent all data.
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all sent yet.
* @retval kStatus_SerialManager_Error An error occurred.
*/
serial_manager_status_t SerialManager_WriteNonBlocking(serial_write_handle_t writeHandle,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Reads data with the non-blocking mode.
*
* This is a non-blocking function, which returns directly without waiting for all data to be received.
* When all data is received, the module driver notifies the upper layer
* through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Success.
* This function receives data using an interrupt method. The interrupt of the hardware could not be disabled.
* And There can only one buffer for receiving for the reading handle at the same time.
*
* @note The function #SerialManager_ReadBlocking and the function #SerialManager_ReadNonBlocking
* cannot be used at the same time. And, the RX callback is mandatory before the function could be used.
*
* @param readHandle The serial manager module handle pointer.
* @param buffer Start address of the data to store the received data.
* @param length The length of the data to be received.
* @retval kStatus_SerialManager_Success Successfully received all data.
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
* @retval kStatus_SerialManager_Error An error occurred.
*/
serial_manager_status_t SerialManager_ReadNonBlocking(serial_read_handle_t readHandle,
uint8_t *buffer,
uint32_t length);
/*!
* @brief Tries to read data.
*
* The function tries to read data from internal ring buffer. If the ring buffer is not empty, the data will be
* copied from ring buffer to up layer buffer. The copied length is the minimum of the ring buffer and up layer length.
* After the data is copied, the actual data length is passed by the parameter length.
* And There can only one buffer for receiving for the reading handle at the same time.
*
* @param readHandle The serial manager module handle pointer.
* @param buffer Start address of the data to store the received data.
* @param length The length of the data to be received.
* @param receivedLength Length received from the ring buffer directly.
* @retval kStatus_SerialManager_Success Successfully received all data.
* @retval kStatus_SerialManager_Busy Previous transmission still not finished; data not all received yet.
* @retval kStatus_SerialManager_Error An error occurred.
*/
serial_manager_status_t SerialManager_TryRead(serial_read_handle_t readHandle,
uint8_t *buffer,
uint32_t length,
uint32_t *receivedLength);
/*!
* @brief Cancels unfinished send transmission.
*
* The function cancels unfinished send transmission. When the transfer is canceled, the module notifies the upper layer
* through a TX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
*
* @note The function #SerialManager_CancelWriting cannot be used to abort the transmission of
* the function #SerialManager_WriteBlocking.
*
* @param writeHandle The serial manager module handle pointer.
* @retval kStatus_SerialManager_Success Get successfully abort the sending.
* @retval kStatus_SerialManager_Error An error occurred.
*/
serial_manager_status_t SerialManager_CancelWriting(serial_write_handle_t writeHandle);
/*!
* @brief Cancels unfinished receive transmission.
*
* The function cancels unfinished receive transmission. When the transfer is canceled, the module notifies the upper
* layer
* through a RX callback function and passes the status parameter @ref kStatus_SerialManager_Canceled.
*
* @note The function #SerialManager_CancelReading cannot be used to abort the transmission of
* the function #SerialManager_ReadBlocking.
*
* @param readHandle The serial manager module handle pointer.
* @retval kStatus_SerialManager_Success Get successfully abort the receiving.
* @retval kStatus_SerialManager_Error An error occurred.
*/
serial_manager_status_t SerialManager_CancelReading(serial_read_handle_t readHandle);
/*!
* @brief Installs a TX callback and callback parameter.
*
* This function is used to install the TX callback and callback parameter for the serial manager module.
* When any status of TX transmission changed, the driver will notify the upper layer by the installed callback
* function. And the status is also passed as status parameter when the callback is called.
*
* @param writeHandle The serial manager module handle pointer.
* @param callback The callback function.
* @param callbackParam The parameter of the callback function.
* @retval kStatus_SerialManager_Success Successfully install the callback.
*/
serial_manager_status_t SerialManager_InstallTxCallback(serial_write_handle_t writeHandle,
serial_manager_callback_t callback,
void *callbackParam);
/*!
* @brief Installs a RX callback and callback parameter.
*
* This function is used to install the RX callback and callback parameter for the serial manager module.
* When any status of RX transmission changed, the driver will notify the upper layer by the installed callback
* function. And the status is also passed as status parameter when the callback is called.
*
* @param readHandle The serial manager module handle pointer.
* @param callback The callback function.
* @param callbackParam The parameter of the callback function.
* @retval kStatus_SerialManager_Success Successfully install the callback.
*/
serial_manager_status_t SerialManager_InstallRxCallback(serial_read_handle_t readHandle,
serial_manager_callback_t callback,
void *callbackParam);
#endif
/*!
* @brief Prepares to enter low power consumption.
*
* This function is used to prepare to enter low power consumption.
*
* @param serialHandle The serial manager module handle pointer.
* @retval kStatus_SerialManager_Success Successful operation.
*/
serial_manager_status_t SerialManager_EnterLowpower(serial_handle_t serialHandle);
/*!
* @brief Restores from low power consumption.
*
* This function is used to restore from low power consumption.
*
* @param serialHandle The serial manager module handle pointer.
* @retval kStatus_SerialManager_Success Successful operation.
*/
serial_manager_status_t SerialManager_ExitLowpower(serial_handle_t serialHandle);
#if defined(__cplusplus)
}
#endif
/*! @} */
#endif /* __SERIAL_MANAGER_H__ */

View File

@ -0,0 +1,55 @@
/*
* Copyright 2018 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __SERIAL_PORT_UART_H__
#define __SERIAL_PORT_UART_H__
/*!
* @addtogroup serial_port_uart
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief serial port uart handle size*/
#if (defined(SERIAL_MANAGER_NON_BLOCKING_MODE) && (SERIAL_MANAGER_NON_BLOCKING_MODE > 0U))
#define SERIAL_PORT_UART_HANDLE_SIZE (166U)
#else
#define SERIAL_PORT_UART_HANDLE_SIZE (4U)
#endif
/*! @brief serial port uart parity mode*/
typedef enum _serial_port_uart_parity_mode
{
kSerialManager_UartParityDisabled = 0x0U, /*!< Parity disabled */
kSerialManager_UartParityEven = 0x1U, /*!< Parity even enabled */
kSerialManager_UartParityOdd = 0x2U, /*!< Parity odd enabled */
} serial_port_uart_parity_mode_t;
/*! @brief serial port uart stop bit count*/
typedef enum _serial_port_uart_stop_bit_count
{
kSerialManager_UartOneStopBit = 0U, /*!< One stop bit */
kSerialManager_UartTwoStopBit = 1U, /*!< Two stop bits */
} serial_port_uart_stop_bit_count_t;
/*! @brief serial port uart config struct*/
typedef struct _serial_port_uart_config
{
uint32_t clockRate; /*!< clock rate */
uint32_t baudRate; /*!< baud rate */
serial_port_uart_parity_mode_t parityMode; /*!< Parity mode, disabled (default), even, odd */
serial_port_uart_stop_bit_count_t stopBitCount; /*!< Number of stop bits, 1 stop bit (default) or 2 stop bits */
uint8_t instance; /*!< Instance (0 - UART0, 1 - UART1, ...), detail information
please refer to the SOC corresponding RM. */
uint8_t enableRx; /*!< Enable RX */
uint8_t enableTx; /*!< Enable TX */
} serial_port_uart_config_t;
/*! @} */
#endif /* __SERIAL_PORT_UART_H__ */

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
* Copyright 2016 - 2018 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __SERIAL_PORT_USB_H__
#define __SERIAL_PORT_USB_H__
#if defined(FSL_RTOS_FREE_RTOS)
#include "FreeRTOS.h"
#endif
/*!
* @addtogroup serial_port_usb
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @brief serial port usb handle size*/
#define SERIAL_PORT_USB_CDC_HANDLE_SIZE (72)
/*! @brief USB interrupt priority*/
#if defined(__GIC_PRIO_BITS)
#define USB_DEVICE_INTERRUPT_PRIORITY (25U)
#else
#if defined(configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
#define USB_DEVICE_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY)
#else
/* The default value 3 is used to support different ARM Core, such as CM0P, CM4, CM7, and CM33, etc.
* The minimum number of priority bits implemented in the NVIC is 2 on these SOCs. The value of mininum
* priority is 3 (2^2 - 1). So, the default value is 3.
*/
#define USB_DEVICE_INTERRUPT_PRIORITY (3U)
#endif
#endif
/*! @brief USB controller ID */
typedef enum _serial_port_usb_cdc_controller_index
{
kSerialManager_UsbControllerKhci0 = 0U, /*!< KHCI 0U */
kSerialManager_UsbControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs,
this is reserved to be used in the future. */
kSerialManager_UsbControllerEhci0 = 2U, /*!< EHCI 0U */
kSerialManager_UsbControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs,
this is reserved to be used in the future. */
kSerialManager_UsbControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */
kSerialManager_UsbControllerLpcIp3511Fs1 = 5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which
have two IP3511 IPs, this is reserved to be used in the future. */
kSerialManager_UsbControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */
kSerialManager_UsbControllerLpcIp3511Hs1 = 7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which
have two IP3511 IPs, this is reserved to be used in the future. */
kSerialManager_UsbControllerOhci0 = 8U, /*!< OHCI 0U */
kSerialManager_UsbControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs,
this is reserved to be used in the future. */
kSerialManager_UsbControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */
kSerialManager_UsbControllerIp3516Hs1 = 11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two
IP3516HS IPs, this is reserved to be used in the future. */
} serial_port_usb_cdc_controller_index_t;
/*! @brief serial port usb config struct*/
typedef struct _serial_port_usb_cdc_config
{
serial_port_usb_cdc_controller_index_t controllerIndex; /*!< controller index */
} serial_port_usb_cdc_config_t;
/*! @} */
#endif /* __SERIAL_PORT_USB_H__ */

View File

@ -0,0 +1,3 @@
SRC_FILES := fsl_lpspi.c lpspi_interrupt.c connect_flash_spi.c flexspi_nor_flash_ops.c flexspi_nor_polling_transfer.c fsl_flexspi.c
include $(KERNEL_ROOT)/compiler.mk

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2018 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef _APP_H_
#define _APP_H_
/*******************************************************************************
* Definitions
******************************************************************************/
/*${macro:start}*/
#define EXAMPLE_FLEXSPI FLEXSPI
#define FLASH_SIZE 0x2000 /* 64Mb/KByte */
#define EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE
#define FLASH_PAGE_SIZE 256
#define EXAMPLE_SECTOR 0
#define SECTOR_SIZE 0x1000 /* 4K */
#define EXAMPLE_FLEXSPI_CLOCK kCLOCK_FlexSpi
#define NOR_CMD_LUT_SEQ_IDX_READ_NORMAL 7
#define NOR_CMD_LUT_SEQ_IDX_READ_FAST 13
#define NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD 0
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS 1
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 2
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 3
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE 6
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD 4
#define NOR_CMD_LUT_SEQ_IDX_READID 8
#define NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG 9
#define NOR_CMD_LUT_SEQ_IDX_ENTERQPI 10
#define NOR_CMD_LUT_SEQ_IDX_EXITQPI 11
#define NOR_CMD_LUT_SEQ_IDX_READSTATUSREG 12
#define NOR_CMD_LUT_SEQ_IDX_ERASECHIP 5
#define CUSTOM_LUT_LENGTH 60
#define FLASH_QUAD_ENABLE 0x40
#define FLASH_BUSY_STATUS_POL 1
#define FLASH_BUSY_STATUS_OFFSET 0
/*${macro:end}*/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*${prototype:start}*/
void BOARD_InitHardware(void);
static inline void flexspi_clock_init(void)
{
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24); /* Set PLL3 PFD0 clock 360MHZ. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 2); /* flexspi clock 120M. */
}
/*${prototype:end}*/
#endif /* _APP_H_ */

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2020 RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2018-11-27 SummerGift add spi flash port file
*/
/**
* @file connect_flash_spi.c
* @brief support stm32f407-st-discovery-board spi flash function and register to bus framework
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-25
*/
/*************************************************
File name: connect_flash_spi.c
Description: support stm32f407-st-discovery-board spi flash bus register function
Others: take RT-Thread v4.0.2/bsp/stm32/stm32f407-atk-explorer/board/ports/spi-flash-init.c
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
History:
1. Date: 2021-04-25
Author: AIIT XUOS Lab
Modification:
1. support stm32f407-st-discovery-board spi flash register to spi bus
2. support stm32f407-st-discovery-board spi flash init
*************************************************/
//#include "connect_spi.h"
#include "flash_spi.h"
int FlashW25qxxSpiDeviceInit(void)
{
#ifdef BSP_USING_SPI1
// __IO uint32_t tmpreg = 0x00U;
// RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
// tmpreg = RCC->AHB1ENR & RCC_AHB1ENR_GPIOBEN;
// (void)tmpreg;
//
// if (EOK != HwSpiDeviceAttach(SPI_BUS_NAME_1, "spi1_dev0", GPIOB, GPIO_Pin_0)) {
// return ERROR;
// }
//
// if (NONE == SpiFlashInit(SPI_BUS_NAME_1, "spi1_dev0", SPI_1_DRV_NAME, "spi1_W25Q64")) {
// return ERROR;
// }
#endif
return EOK;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,288 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_flexspi.h"
#include "app.h"
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
*****************************************************************************/
extern flexspi_device_config_t deviceconfig;
extern const uint32_t customLUT[CUSTOM_LUT_LENGTH];
/*******************************************************************************
* Code
******************************************************************************/
status_t flexspi_nor_write_enable(FLEXSPI_Type *base, uint32_t baseAddr)
{
flexspi_transfer_t flashXfer;
status_t status;
/* Write enable */
flashXfer.deviceAddress = baseAddr;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
return status;
}
status_t flexspi_nor_wait_bus_busy(FLEXSPI_Type *base)
{
/* Wait status ready. */
bool isBusy;
uint32_t readValue;
status_t status;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG;
flashXfer.data = &readValue;
flashXfer.dataSize = 1;
do
{
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
if (FLASH_BUSY_STATUS_POL)
{
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET))
{
isBusy = true;
}
else
{
isBusy = false;
}
}
else
{
if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET))
{
isBusy = false;
}
else
{
isBusy = true;
}
}
} while (isBusy);
return status;
}
status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base)
{
flexspi_transfer_t flashXfer;
status_t status;
uint32_t writeValue = FLASH_QUAD_ENABLE;
/* Write enable */
status = flexspi_nor_write_enable(base, 0);
if (status != kStatus_Success)
{
return status;
}
/* Enable quad mode. */
flashXfer.deviceAddress = 0;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG;
flashXfer.data = &writeValue;
flashXfer.dataSize = 1;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
return status;
}
status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address)
{
status_t status;
flexspi_transfer_t flashXfer;
/* Write enable */
flashXfer.deviceAddress = address;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITEENABLE;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
flashXfer.deviceAddress = address;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASESECTOR;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
return status;
}
status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src)
{
status_t status;
flexspi_transfer_t flashXfer;
/* Write enable */
status = flexspi_nor_write_enable(base, dstAddr);
if (status != kStatus_Success)
{
return status;
}
/* Prepare page program command */
flashXfer.deviceAddress = dstAddr;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Write;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD;
flashXfer.data = (uint32_t *)src;
flashXfer.dataSize = FLASH_PAGE_SIZE;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
return status;
}
status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId)
{
uint32_t temp;
flexspi_transfer_t flashXfer;
flashXfer.deviceAddress = 0;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Read;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READID;
flashXfer.data = &temp;
flashXfer.dataSize = 1;
status_t status = FLEXSPI_TransferBlocking(base, &flashXfer);
*vendorId = temp;
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
return status;
}
status_t flexspi_nor_erase_chip(FLEXSPI_Type *base)
{
status_t status;
flexspi_transfer_t flashXfer;
/* Write enable */
status = flexspi_nor_write_enable(base, 0);
if (status != kStatus_Success)
{
return status;
}
flashXfer.deviceAddress = 0;
flashXfer.port = kFLEXSPI_PortA1;
flashXfer.cmdType = kFLEXSPI_Command;
flashXfer.SeqNumber = 1;
flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_ERASECHIP;
status = FLEXSPI_TransferBlocking(base, &flashXfer);
if (status != kStatus_Success)
{
return status;
}
status = flexspi_nor_wait_bus_busy(base);
return status;
}
void flexspi_nor_flash_init(FLEXSPI_Type *base)
{
flexspi_config_t config;
flexspi_clock_init();
/*Get FLEXSPI default settings and configure the flexspi. */
FLEXSPI_GetDefaultConfig(&config);
/*Set AHB buffer size for reading data through AHB bus. */
config.ahbConfig.enableAHBPrefetch = true;
config.ahbConfig.enableAHBBufferable = true;
config.ahbConfig.enableReadAddressOpt = true;
config.ahbConfig.enableAHBCachable = true;
config.rxSampleClock = kFLEXSPI_ReadSampleClkLoopbackFromDqsPad;
FLEXSPI_Init(base, &config);
/* Configure flash settings according to serial flash feature. */
FLEXSPI_SetFlashConfig(base, &deviceconfig, kFLEXSPI_PortA1);
/* Update LUT table. */
FLEXSPI_UpdateLUT(base, 0, customLUT, CUSTOM_LUT_LENGTH);
/* Do software reset. */
FLEXSPI_SoftwareReset(base);
}

View File

@ -0,0 +1,237 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2018 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_flexspi.h"
#include "app.h"
#include "fsl_debug_console.h"
#include "fsl_cache.h"
#include "pin_mux.h"
#include "board.h"
#include "clock_config.h"
#include "fsl_common.h"
#include <transform.h>
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*******************************************************************************
* Variables
******************************************************************************/
static uint8_t s_nor_program_buffer[256];
static uint8_t s_nor_read_buffer[256];
extern status_t flexspi_nor_flash_erase_sector(FLEXSPI_Type *base, uint32_t address);
extern status_t flexspi_nor_flash_page_program(FLEXSPI_Type *base, uint32_t dstAddr, const uint32_t *src);
extern status_t flexspi_nor_get_vendor_id(FLEXSPI_Type *base, uint8_t *vendorId);
extern status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base);
extern status_t flexspi_nor_erase_chip(FLEXSPI_Type *base);
extern void flexspi_nor_flash_init(FLEXSPI_Type *base);
/*******************************************************************************
* Code
******************************************************************************/
flexspi_device_config_t deviceconfig = {
.flexspiRootClk = 120000000,
.flashSize = FLASH_SIZE,
.CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle,
.CSInterval = 2,
.CSHoldTime = 3,
.CSSetupTime = 3,
.dataValidTime = 0,
.columnspace = 0,
.enableWordAddress = 0,
.AWRSeqIndex = 0,
.AWRSeqNumber = 0,
.ARDSeqIndex = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD,
.ARDSeqNumber = 1,
.AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle,
.AHBWriteWaitInterval = 0,
};
const uint32_t customLUT[CUSTOM_LUT_LENGTH] = {
/* Normal read mode -SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Fast read mode - SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Fast read quad mode - SDR */
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ(
kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04),
/* Read extend parameters */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Write Enable */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Erase Sector */
[4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
/* Page Program - single mode */
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Page Program - quad mode */
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18),
[4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Read ID */
[4 * NOR_CMD_LUT_SEQ_IDX_READID] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Enable Quad mode */
[4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04),
/* Enter QPI mode */
[4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Exit QPI mode */
[4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xF5, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
/* Read status register */
[4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04),
/* Erase whole chip */
[4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] =
FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0),
};
int test_nor_flash(void)
{
uint32_t i = 0;
status_t status;
uint8_t vendorID = 0;
// BOARD_ConfigMPU();
// BOARD_InitPins();
// BOARD_BootClockRUN();
// BOARD_InitDebugConsole();
BOARD_InitSPIPins();
// SCB_DisableDCache();
// spi_trace();
flexspi_nor_flash_init(EXAMPLE_FLEXSPI);
spi_print("\r\nFLEXSPI example started!\r\n");
/* Get vendor ID. */
status = flexspi_nor_get_vendor_id(EXAMPLE_FLEXSPI, &vendorID);
if (status != kStatus_Success)
{
spi_print("flexspi status %d\r\n", status);
return status;
}
spi_print("Vendor ID: 0x%x\r\n", vendorID);
return 0;
#if !(defined(XIP_EXTERNAL_FLASH))
/* Erase whole chip . */
spi_print("Erasing whole chip over FlexSPI...\r\n");
status = flexspi_nor_erase_chip(EXAMPLE_FLEXSPI);
if (status != kStatus_Success)
{
return status;
}
spi_print("Erase finished !\r\n");
#endif
/* Enter quad mode. */
status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI);
if (status != kStatus_Success)
{
return status;
}
/* Erase sectors. */
spi_print("Erasing Serial NOR over FlexSPI...\r\n");
status = flexspi_nor_flash_erase_sector(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE);
if (status != kStatus_Success)
{
spi_print("Erase sector failure !\r\n");
return -1;
}
memset(s_nor_program_buffer, 0xFFU, sizeof(s_nor_program_buffer));
memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
sizeof(s_nor_read_buffer));
if (memcmp(s_nor_program_buffer, s_nor_read_buffer, sizeof(s_nor_program_buffer)))
{
spi_print("Erase data - read out data value incorrect !\r\n ");
return -1;
}
else
{
spi_print("Erase data - successfully. \r\n");
}
for (i = 0; i < 0xFFU; i++)
{
s_nor_program_buffer[i] = i;
}
status =
flexspi_nor_flash_page_program(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE, (void *)s_nor_program_buffer);
if (status != kStatus_Success)
{
spi_print("Page program failure !\r\n");
return -1;
}
DCACHE_CleanInvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE);
memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE),
sizeof(s_nor_read_buffer));
if (memcmp(s_nor_read_buffer, s_nor_program_buffer, sizeof(s_nor_program_buffer)) != 0)
{
spi_print("Program data - read out data value incorrect !\r\n ");
return -1;
}
else
{
spi_print("Program data - successfully. \r\n");
}
while (1)
{
}
}
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
nor, test_nor_flash, Nor flash test );

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,831 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __FSL_FLEXSPI_H_
#define __FSL_FLEXSPI_H_
#include <stddef.h>
#include "fsl_device_registers.h"
#include "fsl_common.h"
#define spi_print KPrintf
#define spi_trace() KPrintf("lw: [%s][%d] passed!\n", __func__, __LINE__)
/*!
* @addtogroup flexspi
* @{
*/
/*******************************************************************************
* Definitions
******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief FLEXSPI driver version 2.1.1. */
#define FSL_FLEXSPI_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
/*@}*/
#define FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNTn(0)
/*! @breif Formula to form FLEXSPI instructions in LUT table. */
#define FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1) \
(FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) | \
FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
/*! @brief Status structure of FLEXSPI.*/
enum _flexspi_status
{
kStatus_FLEXSPI_Busy = MAKE_STATUS(kStatusGroup_FLEXSPI, 0), /*!< FLEXSPI is busy */
kStatus_FLEXSPI_SequenceExecutionTimeout = MAKE_STATUS(kStatusGroup_FLEXSPI, 1), /*!< Sequence execution timeout
error occurred during FLEXSPI transfer. */
kStatus_FLEXSPI_IpCommandSequenceError = MAKE_STATUS(kStatusGroup_FLEXSPI, 2), /*!< IP command Sequence execution
timeout error occurred during FLEXSPI transfer. */
kStatus_FLEXSPI_IpCommandGrantTimeout = MAKE_STATUS(kStatusGroup_FLEXSPI, 3), /*!< IP command grant timeout error
occurred during FLEXSPI transfer. */
};
/*! @brief CMD definition of FLEXSPI, use to form LUT instruction. */
enum _flexspi_command
{
kFLEXSPI_Command_STOP = 0x00U, /*!< Stop execution, deassert CS. */
kFLEXSPI_Command_SDR = 0x01U, /*!< Transmit Command code to Flash, using SDR mode. */
kFLEXSPI_Command_RADDR_SDR = 0x02U, /*!< Transmit Row Address to Flash, using SDR mode. */
kFLEXSPI_Command_CADDR_SDR = 0x03U, /*!< Transmit Column Address to Flash, using SDR mode. */
kFLEXSPI_Command_MODE1_SDR = 0x04U, /*!< Transmit 1-bit Mode bits to Flash, using SDR mode. */
kFLEXSPI_Command_MODE2_SDR = 0x05U, /*!< Transmit 2-bit Mode bits to Flash, using SDR mode. */
kFLEXSPI_Command_MODE4_SDR = 0x06U, /*!< Transmit 4-bit Mode bits to Flash, using SDR mode. */
kFLEXSPI_Command_MODE8_SDR = 0x07U, /*!< Transmit 8-bit Mode bits to Flash, using SDR mode. */
kFLEXSPI_Command_WRITE_SDR = 0x08U, /*!< Transmit Programming Data to Flash, using SDR mode. */
kFLEXSPI_Command_READ_SDR = 0x09U, /*!< Receive Read Data from Flash, using SDR mode. */
kFLEXSPI_Command_LEARN_SDR = 0x0AU, /*!< Receive Read Data or Preamble bit from Flash, SDR mode. */
kFLEXSPI_Command_DATSZ_SDR = 0x0BU, /*!< Transmit Read/Program Data size (byte) to Flash, SDR mode. */
kFLEXSPI_Command_DUMMY_SDR = 0x0CU, /*!< Leave data lines undriven by FlexSPI controller.*/
kFLEXSPI_Command_DUMMY_RWDS_SDR = 0x0DU, /*!< Leave data lines undriven by FlexSPI controller,
dummy cycles decided by RWDS. */
kFLEXSPI_Command_DDR = 0x21U, /*!< Transmit Command code to Flash, using DDR mode. */
kFLEXSPI_Command_RADDR_DDR = 0x22U, /*!< Transmit Row Address to Flash, using DDR mode. */
kFLEXSPI_Command_CADDR_DDR = 0x23U, /*!< Transmit Column Address to Flash, using DDR mode. */
kFLEXSPI_Command_MODE1_DDR = 0x24U, /*!< Transmit 1-bit Mode bits to Flash, using DDR mode. */
kFLEXSPI_Command_MODE2_DDR = 0x25U, /*!< Transmit 2-bit Mode bits to Flash, using DDR mode. */
kFLEXSPI_Command_MODE4_DDR = 0x26U, /*!< Transmit 4-bit Mode bits to Flash, using DDR mode. */
kFLEXSPI_Command_MODE8_DDR = 0x27U, /*!< Transmit 8-bit Mode bits to Flash, using DDR mode. */
kFLEXSPI_Command_WRITE_DDR = 0x28U, /*!< Transmit Programming Data to Flash, using DDR mode. */
kFLEXSPI_Command_READ_DDR = 0x29U, /*!< Receive Read Data from Flash, using DDR mode. */
kFLEXSPI_Command_LEARN_DDR = 0x2AU, /*!< Receive Read Data or Preamble bit from Flash, DDR mode. */
kFLEXSPI_Command_DATSZ_DDR = 0x2BU, /*!< Transmit Read/Program Data size (byte) to Flash, DDR mode. */
kFLEXSPI_Command_DUMMY_DDR = 0x2CU, /*!< Leave data lines undriven by FlexSPI controller.*/
kFLEXSPI_Command_DUMMY_RWDS_DDR = 0x2DU, /*!< Leave data lines undriven by FlexSPI controller,
dummy cycles decided by RWDS. */
kFLEXSPI_Command_JUMP_ON_CS = 0x1FU, /*!< Stop execution, deassert CS and save operand[7:0] as the
instruction start pointer for next sequence */
};
/*! @brief pad definition of FLEXSPI, use to form LUT instruction. */
typedef enum _flexspi_pad
{
kFLEXSPI_1PAD = 0x00U, /*!< Transmit command/address and transmit/receive data only through DATA0/DATA1. */
kFLEXSPI_2PAD = 0x01U, /*!< Transmit command/address and transmit/receive data only through DATA[1:0]. */
kFLEXSPI_4PAD = 0x02U, /*!< Transmit command/address and transmit/receive data only through DATA[3:0]. */
kFLEXSPI_8PAD = 0x03U, /*!< Transmit command/address and transmit/receive data only through DATA[7:0]. */
} flexspi_pad_t;
/*! @brief FLEXSPI interrupt status flags.*/
typedef enum _flexspi_flags
{
kFLEXSPI_SequenceExecutionTimeoutFlag = FLEXSPI_INTEN_SEQTIMEOUTEN_MASK, /*!< Sequence execution timeout. */
kFLEXSPI_AhbBusTimeoutFlag = FLEXSPI_INTEN_AHBBUSTIMEOUTEN_MASK, /*!< AHB Bus timeout. */
kFLEXSPI_SckStoppedBecauseTxEmptyFlag =
FLEXSPI_INTEN_SCKSTOPBYWREN_MASK, /*!< SCK is stopped during command
sequence because Async TX FIFO empty. */
kFLEXSPI_SckStoppedBecauseRxFullFlag =
FLEXSPI_INTEN_SCKSTOPBYRDEN_MASK, /*!< SCK is stopped during command
sequence because Async RX FIFO full. */
#if !((defined(FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN)) && (FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN))
kFLEXSPI_DataLearningFailedFlag = FLEXSPI_INTEN_DATALEARNFAILEN_MASK, /*!< Data learning failed. */
#endif
kFLEXSPI_IpTxFifoWatermarkEmpltyFlag = FLEXSPI_INTEN_IPTXWEEN_MASK, /*!< IP TX FIFO WaterMark empty. */
kFLEXSPI_IpRxFifoWatermarkAvailableFlag = FLEXSPI_INTEN_IPRXWAEN_MASK, /*!< IP RX FIFO WaterMark available. */
kFLEXSPI_AhbCommandSequenceErrorFlag =
FLEXSPI_INTEN_AHBCMDERREN_MASK, /*!< AHB triggered Command Sequences Error. */
kFLEXSPI_IpCommandSequenceErrorFlag = FLEXSPI_INTEN_IPCMDERREN_MASK, /*!< IP triggered Command Sequences Error. */
kFLEXSPI_AhbCommandGrantTimeoutFlag =
FLEXSPI_INTEN_AHBCMDGEEN_MASK, /*!< AHB triggered Command Sequences Grant Timeout. */
kFLEXSPI_IpCommandGrantTimeoutFlag =
FLEXSPI_INTEN_IPCMDGEEN_MASK, /*!< IP triggered Command Sequences Grant Timeout. */
kFLEXSPI_IpCommandExcutionDoneFlag =
FLEXSPI_INTEN_IPCMDDONEEN_MASK, /*!< IP triggered Command Sequences Execution finished. */
kFLEXSPI_AllInterruptFlags = 0xFFFU, /*!< All flags. */
} flexspi_flags_t;
/*! @brief FLEXSPI sample clock source selection for Flash Reading.*/
typedef enum _flexspi_read_sample_clock
{
kFLEXSPI_ReadSampleClkLoopbackInternally = 0x0U, /*!< Dummy Read strobe generated by FlexSPI Controller
and loopback internally. */
kFLEXSPI_ReadSampleClkLoopbackFromDqsPad = 0x1U, /*!< Dummy Read strobe generated by FlexSPI Controller
and loopback from DQS pad. */
kFLEXSPI_ReadSampleClkLoopbackFromSckPad = 0x2U, /*!< SCK output clock and loopback from SCK pad. */
kFLEXSPI_ReadSampleClkExternalInputFromDqsPad = 0x3U, /*!< Flash provided Read strobe and input from DQS pad. */
} flexspi_read_sample_clock_t;
/*! @brief FLEXSPI interval unit for flash device select.*/
typedef enum _flexspi_cs_interval_cycle_unit
{
kFLEXSPI_CsIntervalUnit1SckCycle = 0x0U, /*!< Chip selection interval: CSINTERVAL * 1 serial clock cycle. */
kFLEXSPI_CsIntervalUnit256SckCycle = 0x1U, /*!< Chip selection interval: CSINTERVAL * 256 serial clock cycle. */
} flexspi_cs_interval_cycle_unit_t;
/*! @brief FLEXSPI AHB wait interval unit for writting.*/
typedef enum _flexspi_ahb_write_wait_unit
{
kFLEXSPI_AhbWriteWaitUnit2AhbCycle = 0x0U, /*!< AWRWAIT unit is 2 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit8AhbCycle = 0x1U, /*!< AWRWAIT unit is 8 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit32AhbCycle = 0x2U, /*!< AWRWAIT unit is 32 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit128AhbCycle = 0x3U, /*!< AWRWAIT unit is 128 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit512AhbCycle = 0x4U, /*!< AWRWAIT unit is 512 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit2048AhbCycle = 0x5U, /*!< AWRWAIT unit is 2048 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit8192AhbCycle = 0x6U, /*!< AWRWAIT unit is 8192 ahb clock cycle. */
kFLEXSPI_AhbWriteWaitUnit32768AhbCycle = 0x7U, /*!< AWRWAIT unit is 32768 ahb clock cycle. */
} flexspi_ahb_write_wait_unit_t;
/*! @brief Error Code when IP command Error detected.*/
typedef enum _flexspi_ip_error_code
{
kFLEXSPI_IpCmdErrorNoError = 0x0U, /*!< No error. */
kFLEXSPI_IpCmdErrorJumpOnCsInIpCmd = 0x2U, /*!< IP command with JMP_ON_CS instruction used. */
kFLEXSPI_IpCmdErrorUnknownOpCode = 0x3U, /*!< Unknown instruction opcode in the sequence. */
kFLEXSPI_IpCmdErrorSdrDummyInDdrSequence = 0x4U, /*!< Instruction DUMMY_SDR/DUMMY_RWDS_SDR
used in DDR sequence. */
kFLEXSPI_IpCmdErrorDdrDummyInSdrSequence = 0x5U, /*!< Instruction DUMMY_DDR/DUMMY_RWDS_DDR
used in SDR sequence. */
kFLEXSPI_IpCmdErrorInvalidAddress = 0x6U, /*!< Flash access start address exceed the whole
flash address range (A1/A2/B1/B2). */
kFLEXSPI_IpCmdErrorSequenceExecutionTimeout = 0xEU, /*!< Sequence execution timeout. */
kFLEXSPI_IpCmdErrorFlashBoundaryAcrosss = 0xFU, /*!< Flash boundary crossed. */
} flexspi_ip_error_code_t;
/*! @brief Error Code when AHB command Error detected.*/
typedef enum _flexspi_ahb_error_code
{
kFLEXSPI_AhbCmdErrorNoError = 0x0U, /*!< No error. */
kFLEXSPI_AhbCmdErrorJumpOnCsInWriteCmd = 0x2U, /*!< AHB Write command with JMP_ON_CS instruction
used in the sequence. */
kFLEXSPI_AhbCmdErrorUnknownOpCode = 0x3U, /*!< Unknown instruction opcode in the sequence. */
kFLEXSPI_AhbCmdErrorSdrDummyInDdrSequence = 0x4U, /*!< Instruction DUMMY_SDR/DUMMY_RWDS_SDR used
in DDR sequence. */
kFLEXSPI_AhbCmdErrorDdrDummyInSdrSequence = 0x5U, /*!< Instruction DUMMY_DDR/DUMMY_RWDS_DDR
used in SDR sequence. */
kFLEXSPI_AhbCmdSequenceExecutionTimeout = 0x6U, /*!< Sequence execution timeout. */
} flexspi_ahb_error_code_t;
/*! @brief FLEXSPI operation port select.*/
typedef enum _flexspi_port
{
kFLEXSPI_PortA1 = 0x0U, /*!< Access flash on A1 port. */
kFLEXSPI_PortA2, /*!< Access flash on A2 port. */
kFLEXSPI_PortB1, /*!< Access flash on B1 port. */
kFLEXSPI_PortB2, /*!< Access flash on B2 port. */
kFLEXSPI_PortCount
} flexspi_port_t;
/*! @brief Trigger source of current command sequence granted by arbitrator.*/
typedef enum _flexspi_arb_command_source
{
kFLEXSPI_AhbReadCommand = 0x0U,
kFLEXSPI_AhbWriteCommand = 0x1U,
kFLEXSPI_IpCommand = 0x2U,
kFLEXSPI_SuspendedCommand = 0x3U,
} flexspi_arb_command_source_t;
typedef enum _flexspi_command_type
{
kFLEXSPI_Command, /*!< FlexSPI operation: Only command, both TX and Rx buffer are ignored. */
kFLEXSPI_Config, /*!< FlexSPI operation: Configure device mode, the TX fifo size is fixed in LUT. */
kFLEXSPI_Read, /* /!< FlexSPI operation: Read, only Rx Buffer is effective. */
kFLEXSPI_Write, /* /!< FlexSPI operation: Read, only Tx Buffer is effective. */
} flexspi_command_type_t;
typedef struct _flexspi_ahbBuffer_config
{
uint8_t priority; /*!< This priority for AHB Master Read which this AHB RX Buffer is assigned. */
uint8_t masterIndex; /*!< AHB Master ID the AHB RX Buffer is assigned. */
uint16_t bufferSize; /*!< AHB buffer size in byte. */
bool enablePrefetch; /*!< AHB Read Prefetch Enable for current AHB RX Buffer corresponding Master, allows
prefetch disable/enable seperately for each master. */
} flexspi_ahbBuffer_config_t;
/*! @brief FLEXSPI configuration structure. */
typedef struct _flexspi_config
{
flexspi_read_sample_clock_t rxSampleClock; /*!< Sample Clock source selection for Flash Reading. */
bool enableSckFreeRunning; /*!< Enable/disable SCK output free-running. */
bool enableCombination; /*!< Enable/disable combining PORT A and B Data Pins
(SIOA[3:0] and SIOB[3:0]) to support Flash Octal mode. */
bool enableDoze; /*!< Enable/disable doze mode support. */
bool enableHalfSpeedAccess; /*!< Enable/disable divide by 2 of the clock for half
speed commands. */
bool enableSckBDiffOpt; /*!< Enable/disable SCKB pad use as SCKA differential clock
output, when enable, Port B flash access is not available. */
bool enableSameConfigForAll; /*!< Enable/disable same configuration for all connected devices
when enabled, same configuration in FLASHA1CRx is applied to all. */
uint16_t seqTimeoutCycle; /*!< Timeout wait cycle for command sequence execution,
timeout after ahbGrantTimeoutCyle*1024 serial root clock cycles. */
uint8_t ipGrantTimeoutCycle; /*!< Timeout wait cycle for IP command grant, timeout after
ipGrantTimeoutCycle*1024 AHB clock cycles. */
uint8_t txWatermark; /*!< FLEXSPI IP transmit watermark value. */
uint8_t rxWatermark; /*!< FLEXSPI receive watermark value. */
struct
{
bool enableAHBWriteIpTxFifo; /*!< Enable AHB bus write access to IP TX FIFO. */
bool enableAHBWriteIpRxFifo; /*!< Enable AHB bus write access to IP RX FIFO. */
uint8_t ahbGrantTimeoutCycle; /*!< Timeout wait cycle for AHB command grant,
timeout after ahbGrantTimeoutCyle*1024 AHB clock cycles. */
uint16_t ahbBusTimeoutCycle; /*!< Timeout wait cycle for AHB read/write access,
timeout after ahbBusTimeoutCycle*1024 AHB clock cycles. */
uint8_t resumeWaitCycle; /*!< Wait cycle for idle state before suspended command sequence
resume, timeout after ahbBusTimeoutCycle AHB clock cycles. */
flexspi_ahbBuffer_config_t buffer[FSL_FEATURE_FLEXSPI_AHB_BUFFER_COUNT]; /*!< AHB buffer size. */
bool enableClearAHBBufferOpt; /*!< Enable/disable automatically clean AHB RX Buffer and TX Buffer
when FLEXSPI returns STOP mode ACK. */
bool enableReadAddressOpt; /*!< Enable/disable remove AHB read burst start address alignment limitation.
when eanble, there is no AHB read burst start address alignment limitation. */
bool enableAHBPrefetch; /*!< Enable/disable AHB read prefetch feature, when enabled, FLEXSPI
will fetch more data than current AHB burst. */
bool enableAHBBufferable; /*!< Enable/disable AHB bufferable write access support, when enabled,
FLEXSPI return before waiting for command excution finished. */
bool enableAHBCachable; /*!< Enable AHB bus cachable read access support. */
} ahbConfig;
} flexspi_config_t;
/*! @brief External device configuration items. */
typedef struct _flexspi_device_config
{
uint32_t flexspiRootClk; /*!< FLEXSPI serial root clock. */
bool isSck2Enabled; /*!< FLEXSPI use SCK2. */
uint32_t flashSize; /*!< Flash size in KByte. */
flexspi_cs_interval_cycle_unit_t CSIntervalUnit; /*!< CS interval unit, 1 or 256 cycle. */
uint16_t CSInterval; /*!< CS line assert interval, mutiply CS interval unit to
get the CS line assert interval cycles. */
uint8_t CSHoldTime; /*!< CS line hold time. */
uint8_t CSSetupTime; /*!< CS line setup time. */
uint8_t dataValidTime; /*!< Data valid time for external device. */
uint8_t columnspace; /*!< Column space size. */
bool enableWordAddress; /*!< If enable word address.*/
uint8_t AWRSeqIndex; /*!< Sequence ID for AHB write command. */
uint8_t AWRSeqNumber; /*!< Sequence number for AHB write command. */
uint8_t ARDSeqIndex; /*!< Sequence ID for AHB read command. */
uint8_t ARDSeqNumber; /*!< Sequence number for AHB read command. */
flexspi_ahb_write_wait_unit_t AHBWriteWaitUnit; /*!< AHB write wait unit. */
uint16_t AHBWriteWaitInterval; /*!< AHB write wait interval, mutiply AHB write interval
unit to get the AHB write wait cycles. */
bool enableWriteMask; /*!< Enable/Disable FLEXSPI drive DQS pin as write mask
when writing to external device. */
} flexspi_device_config_t;
/*! @brief Transfer structure for FLEXSPI. */
typedef struct _flexspi_transfer
{
uint32_t deviceAddress; /*!< Operation device address. */
flexspi_port_t port; /*!< Operation port. */
flexspi_command_type_t cmdType; /*!< Execution command type. */
uint8_t seqIndex; /*!< Sequence ID for command. */
uint8_t SeqNumber; /*!< Sequence number for command. */
uint32_t *data; /*!< Data buffer. */
size_t dataSize; /*!< Data size in bytes. */
} flexspi_transfer_t;
/* Forward declaration of the handle typedef. */
typedef struct _flexspi_handle flexspi_handle_t;
/*! @brief FLEXSPI transfer callback function. */
typedef void (*flexspi_transfer_callback_t)(FLEXSPI_Type *base,
flexspi_handle_t *handle,
status_t status,
void *userData);
/*! @brief Transfer handle structure for FLEXSPI. */
struct _flexspi_handle
{
uint32_t state; /*!< Internal state for FLEXSPI transfer */
uint32_t *data; /*!< Data buffer. */
size_t dataSize; /*!< Remaining Data size in bytes. */
size_t transferTotalSize; /*!< Total Data size in bytes. */
flexspi_transfer_callback_t completionCallback; /*!< Callback for users while transfer finish or error occurred */
void *userData; /*!< FLEXSPI callback function parameter.*/
};
/*******************************************************************************
* API
******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif /*_cplusplus. */
/*!
* @name Initialization and deinitialization
* @{
*/
/*!
* @brief Initializes the FLEXSPI module and internal state.
*
* This function enables the clock for FLEXSPI and also configures the FLEXSPI with the
* input configure parameters. Users should call this function before any FLEXSPI operations.
*
* @param base FLEXSPI peripheral base address.
* @param config FLEXSPI configure structure.
*/
void FLEXSPI_Init(FLEXSPI_Type *base, const flexspi_config_t *config);
/*!
* @brief Gets default settings for FLEXSPI.
*
* @param config FLEXSPI configuration structure.
*/
void FLEXSPI_GetDefaultConfig(flexspi_config_t *config);
/*!
* @brief Deinitializes the FLEXSPI module.
*
* Clears the FLEXSPI state and FLEXSPI module registers.
* @param base FLEXSPI peripheral base address.
*/
void FLEXSPI_Deinit(FLEXSPI_Type *base);
/*!
* @brief Configures the connected device parameter.
*
* This function configures the connected device relevant parameters, such as the size, command, and so on.
* The flash configuration value cannot have a default value. The user needs to configure it according to the
* connected device.
*
* @param base FLEXSPI peripheral base address.
* @param config Flash configuration parameters.
* @param port FLEXSPI Operation port.
*/
void FLEXSPI_SetFlashConfig(FLEXSPI_Type *base, flexspi_device_config_t *config, flexspi_port_t port);
/*!
* @brief Software reset for the FLEXSPI logic.
*
* This function sets the software reset flags for both AHB and buffer domain and
* resets both AHB buffer and also IP FIFOs.
*
* @param base FLEXSPI peripheral base address.
*/
static inline void FLEXSPI_SoftwareReset(FLEXSPI_Type *base)
{
//tst by wly
return;
base->MCR0 |= FLEXSPI_MCR0_SWRESET_MASK;
while (base->MCR0 & FLEXSPI_MCR0_SWRESET_MASK)
{
}
}
/*!
* @brief Enables or disables the FLEXSPI module.
*
* @param base FLEXSPI peripheral base address.
* @param enable True means enable FLEXSPI, false means disable.
*/
static inline void FLEXSPI_Enable(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->MCR0 &= ~FLEXSPI_MCR0_MDIS_MASK;
}
else
{
base->MCR0 |= FLEXSPI_MCR0_MDIS_MASK;
}
}
/* @} */
/*!
* @name Interrupts
* @{
*/
/*!
* @brief Enables the FLEXSPI interrupts.
*
* @param base FLEXSPI peripheral base address.
* @param mask FLEXSPI interrupt source.
*/
static inline void FLEXSPI_EnableInterrupts(FLEXSPI_Type *base, uint32_t mask)
{
base->INTEN |= mask;
}
/*!
* @brief Disable the FLEXSPI interrupts.
*
* @param base FLEXSPI peripheral base address.
* @param mask FLEXSPI interrupt source.
*/
static inline void FLEXSPI_DisableInterrupts(FLEXSPI_Type *base, uint32_t mask)
{
base->INTEN &= ~mask;
}
/* @} */
/*! @name DMA control */
/*@{*/
/*!
* @brief Enables or disables FLEXSPI IP Tx FIFO DMA requests.
*
* @param base FLEXSPI peripheral base address.
* @param enable Enable flag for transmit DMA request. Pass true for enable, false for disable.
*/
static inline void FLEXSPI_EnableTxDMA(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->IPTXFCR |= FLEXSPI_IPTXFCR_TXDMAEN_MASK;
}
else
{
base->IPTXFCR &= ~FLEXSPI_IPTXFCR_TXDMAEN_MASK;
}
}
/*!
* @brief Enables or disables FLEXSPI IP Rx FIFO DMA requests.
*
* @param base FLEXSPI peripheral base address.
* @param enable Enable flag for receive DMA request. Pass true for enable, false for disable.
*/
static inline void FLEXSPI_EnableRxDMA(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->IPRXFCR |= FLEXSPI_IPRXFCR_RXDMAEN_MASK;
}
else
{
base->IPRXFCR &= ~FLEXSPI_IPRXFCR_RXDMAEN_MASK;
}
}
/*!
* @brief Gets FLEXSPI IP tx fifo address for DMA transfer.
*
* @param base FLEXSPI peripheral base address.
* @retval The tx fifo address.
*/
static inline uint32_t FLEXSPI_GetTxFifoAddress(FLEXSPI_Type *base)
{
return (uint32_t)&base->TFDR[0];
}
/*!
* @brief Gets FLEXSPI IP rx fifo address for DMA transfer.
*
* @param base FLEXSPI peripheral base address.
* @retval The rx fifo address.
*/
static inline uint32_t FLEXSPI_GetRxFifoAddress(FLEXSPI_Type *base)
{
return (uint32_t)&base->RFDR[0];
}
/*@}*/
/*! @name FIFO control */
/*@{*/
/*! @brief Clears the FLEXSPI IP FIFO logic.
*
* @param base FLEXSPI peripheral base address.
* @param txFifo Pass true to reset TX FIFO.
* @param rxFifo Pass true to reset RX FIFO.
*/
static inline void FLEXSPI_ResetFifos(FLEXSPI_Type *base, bool txFifo, bool rxFifo)
{
if (txFifo)
{
base->IPTXFCR |= FLEXSPI_IPTXFCR_CLRIPTXF_MASK;
}
if (rxFifo)
{
base->IPRXFCR |= FLEXSPI_IPRXFCR_CLRIPRXF_MASK;
}
}
/*!
* @brief Gets the valid data entries in the FLEXSPI FIFOs.
*
* @param base FLEXSPI peripheral base address.
* @param[out] txCount Pointer through which the current number of bytes in the transmit FIFO is returned.
* Pass NULL if this value is not required.
* @param[out] rxCount Pointer through which the current number of bytes in the receive FIFO is returned.
* Pass NULL if this value is not required.
*/
static inline void FLEXSPI_GetFifoCounts(FLEXSPI_Type *base, size_t *txCount, size_t *rxCount)
{
if (txCount)
{
*txCount = (((base->IPTXFSTS) & FLEXSPI_IPTXFSTS_FILL_MASK) >> FLEXSPI_IPTXFSTS_FILL_SHIFT) * 8U;
}
if (rxCount)
{
*rxCount = (((base->IPRXFSTS) & FLEXSPI_IPRXFSTS_FILL_MASK) >> FLEXSPI_IPRXFSTS_FILL_SHIFT) * 8U;
}
}
/*@}*/
/*!
* @name Status
* @{
*/
/*!
* @brief Get the FLEXSPI interrupt status flags.
*
* @param base FLEXSPI peripheral base address.
* @retval interrupt status flag, use status flag to AND #flexspi_flags_t could get the related status.
*/
static inline uint32_t FLEXSPI_GetInterruptStatusFlags(FLEXSPI_Type *base)
{
return base->INTR;
}
/*!
* @brief Get the FLEXSPI interrupt status flags.
*
* @param base FLEXSPI peripheral base address.
* @param interrupt status flag.
*/
static inline void FLEXSPI_ClearInterruptStatusFlags(FLEXSPI_Type *base, uint32_t mask)
{
base->INTR |= mask;
}
#if !((defined(FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN)) && (FSL_FEATURE_FLEXSPI_HAS_NO_DATA_LEARN))
/*! @brief Gets the sampling clock phase selection after Data Learning.
*
* @param base FLEXSPI peripheral base address.
* @param portAPhase Pointer to a uint8_t type variable to receive the selected clock phase on PORTA.
* @param portBPhase Pointer to a uint8_t type variable to receive the selected clock phase on PORTB.
*/
static inline void FLEXSPI_GetDataLearningPhase(FLEXSPI_Type *base, uint8_t *portAPhase, uint8_t *portBPhase)
{
if (portAPhase)
{
*portAPhase = (base->STS0 & FLEXSPI_STS0_DATALEARNPHASEA_MASK) >> FLEXSPI_STS0_DATALEARNPHASEA_SHIFT;
}
if (portBPhase)
{
*portBPhase = (base->STS0 & FLEXSPI_STS0_DATALEARNPHASEB_MASK) >> FLEXSPI_STS0_DATALEARNPHASEB_SHIFT;
}
}
#endif
/*! @brief Gets the trigger source of current command sequence granted by arbitrator.
*
* @param base FLEXSPI peripheral base address.
* @retval trigger source of current command sequence.
*/
static inline flexspi_arb_command_source_t FLEXSPI_GetArbitratorCommandSource(FLEXSPI_Type *base)
{
return (flexspi_arb_command_source_t)((base->STS0 & FLEXSPI_STS0_ARBCMDSRC_MASK) >> FLEXSPI_STS0_ARBCMDSRC_SHIFT);
}
/*! @brief Gets the error code when IP command error detected.
*
* @param base FLEXSPI peripheral base address.
* @param index Pointer to a uint8_t type variable to receive the sequence index when error detected.
* @retval error code when IP command error detected.
*/
static inline flexspi_ip_error_code_t FLEXSPI_GetIPCommandErrorCode(FLEXSPI_Type *base, uint8_t *index)
{
*index = (base->STS1 & FLEXSPI_STS1_IPCMDERRID_MASK) >> FLEXSPI_STS1_IPCMDERRID_SHIFT;
return (flexspi_ip_error_code_t)((base->STS1 & FLEXSPI_STS1_IPCMDERRCODE_MASK) >> FLEXSPI_STS1_IPCMDERRCODE_SHIFT);
}
/*! @brief Gets the error code when AHB command error detected.
*
* @param base FLEXSPI peripheral base address.
* @param index Pointer to a uint8_t type variable to receive the sequence index when error detected.
* @retval error code when AHB command error detected.
*/
static inline flexspi_ahb_error_code_t FLEXSPI_GetAHBCommandErrorCode(FLEXSPI_Type *base, uint8_t *index)
{
*index = (base->STS1 & FLEXSPI_STS1_AHBCMDERRID_MASK) >> FLEXSPI_STS1_AHBCMDERRID_SHIFT;
return (flexspi_ahb_error_code_t)((base->STS1 & FLEXSPI_STS1_AHBCMDERRCODE_MASK) >>
FLEXSPI_STS1_AHBCMDERRCODE_SHIFT);
}
/*! @brief Returns whether the bus is idle.
*
* @param base FLEXSPI peripheral base address.
* @retval true Bus is idle.
* @retval false Bus is busy.
*/
static inline bool FLEXSPI_GetBusIdleStatus(FLEXSPI_Type *base)
{
return (base->STS0 & FLEXSPI_STS0_ARBIDLE_MASK) && (base->STS0 & FLEXSPI_STS0_SEQIDLE_MASK);
}
/*@}*/
/*!
* @name Bus Operations
* @{
*/
/*! @brief Update read sample clock source
*
* @param base FLEXSPI peripheral base address.
* @param clockSource clockSource of type #flexspi_read_sample_clock_t
*/
void FLEXSPI_UpdateRxSampleClock(FLEXSPI_Type *base, flexspi_read_sample_clock_t clockSource);
/*! @brief Enables/disables the FLEXSPI IP command parallel mode.
*
* @param base FLEXSPI peripheral base address.
* @param enable True means enable parallel mode, false means disable parallel mode.
*/
static inline void FLEXSPI_EnableIPParallelMode(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->IPCR1 |= FLEXSPI_IPCR1_IPAREN_MASK;
}
else
{
base->IPCR1 &= ~FLEXSPI_IPCR1_IPAREN_MASK;
}
}
/*! @brief Enables/disables the FLEXSPI AHB command parallel mode.
*
* @param base FLEXSPI peripheral base address.
* @param enable True means enable parallel mode, false means disable parallel mode.
*/
static inline void FLEXSPI_EnableAHBParallelMode(FLEXSPI_Type *base, bool enable)
{
if (enable)
{
base->AHBCR |= FLEXSPI_AHBCR_APAREN_MASK;
}
else
{
base->AHBCR &= ~FLEXSPI_AHBCR_APAREN_MASK;
}
}
/*! @brief Updates the LUT table.
*
* @param base FLEXSPI peripheral base address.
* @param index From which index start to update. It could be any index of the LUT table, which
* also allows user to update command content inside a command. Each command consists of up to
* 8 instructions and occupy 4*32-bit memory.
* @param cmd Command sequence array.
* @param count Number of sequences.
*/
void FLEXSPI_UpdateLUT(FLEXSPI_Type *base, uint32_t index, const uint32_t *cmd, uint32_t count);
/*!
* @brief Writes data into FIFO.
*
* @param base FLEXSPI peripheral base address
* @param data The data bytes to send
* @param fifoIndex Destination fifo index.
*/
static inline void FLEXSPI_WriteData(FLEXSPI_Type *base, uint32_t data, uint8_t fifoIndex)
{
base->TFDR[fifoIndex] = data;
}
/*!
* @brief Receives data from data FIFO.
*
* @param base FLEXSPI peripheral base address
* @param fifoIndex Source fifo index.
* @return The data in the FIFO.
*/
static inline uint32_t FLEXSPI_ReadData(FLEXSPI_Type *base, uint8_t fifoIndex)
{
return base->RFDR[fifoIndex];
}
/*!
* @brief Sends a buffer of data bytes using blocking method.
* @note This function blocks via polling until all bytes have been sent.
* @param base FLEXSPI peripheral base address
* @param buffer The data bytes to send
* @param size The number of data bytes to send
* @retval kStatus_Success write success without error
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequencen error detected
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
*/
status_t FLEXSPI_WriteBlocking(FLEXSPI_Type *base, uint32_t *buffer, size_t size);
/*!
* @brief Receives a buffer of data bytes using a blocking method.
* @note This function blocks via polling until all bytes have been sent.
* @param base FLEXSPI peripheral base address
* @param buffer The data bytes to send
* @param size The number of data bytes to receive
* @retval kStatus_Success read success without error
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequencen error detected
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
*/
status_t FLEXSPI_ReadBlocking(FLEXSPI_Type *base, uint32_t *buffer, size_t size);
/*!
* @brief Execute command to transfer a buffer data bytes using a blocking method.
* @param base FLEXSPI peripheral base address
* @param xfer pointer to the transfer structure.
* @retval kStatus_Success command transfer success without error
* @retval kStatus_FLEXSPI_SequenceExecutionTimeout sequence execution timeout
* @retval kStatus_FLEXSPI_IpCommandSequenceError IP command sequencen error detected
* @retval kStatus_FLEXSPI_IpCommandGrantTimeout IP command grant timeout detected
*/
status_t FLEXSPI_TransferBlocking(FLEXSPI_Type *base, flexspi_transfer_t *xfer);
/*! @} */
/*!
* @name Transactional
* @{
*/
/*!
* @brief Initializes the FLEXSPI handle which is used in transactional functions.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure to store the transfer state.
* @param callback pointer to user callback function.
* @param userData user parameter passed to the callback function.
*/
void FLEXSPI_TransferCreateHandle(FLEXSPI_Type *base,
flexspi_handle_t *handle,
flexspi_transfer_callback_t callback,
void *userData);
/*!
* @brief Performs a interrupt non-blocking transfer on the FLEXSPI bus.
*
* @note Calling the API returns immediately after transfer initiates. The user needs
* to call FLEXSPI_GetTransferCount to poll the transfer status to check whether
* the transfer is finished. If the return status is not kStatus_FLEXSPI_Busy, the transfer
* is finished. For FLEXSPI_Read, the dataSize should be multiple of rx watermark levle, or
* FLEXSPI could not read data properly.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure which stores the transfer state.
* @param xfer pointer to flexspi_transfer_t structure.
* @retval kStatus_Success Successfully start the data transmission.
* @retval kStatus_FLEXSPI_Busy Previous transmission still not finished.
*/
status_t FLEXSPI_TransferNonBlocking(FLEXSPI_Type *base, flexspi_handle_t *handle, flexspi_transfer_t *xfer);
/*!
* @brief Gets the master transfer status during a interrupt non-blocking transfer.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure which stores the transfer state.
* @param count Number of bytes transferred so far by the non-blocking transaction.
* @retval kStatus_InvalidArgument count is Invalid.
* @retval kStatus_Success Successfully return the count.
*/
status_t FLEXSPI_TransferGetCount(FLEXSPI_Type *base, flexspi_handle_t *handle, size_t *count);
/*!
* @brief Aborts an interrupt non-blocking transfer early.
*
* @note This API can be called at any time when an interrupt non-blocking transfer initiates
* to abort the transfer early.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure which stores the transfer state
*/
void FLEXSPI_TransferAbort(FLEXSPI_Type *base, flexspi_handle_t *handle);
/*!
* @brief Master interrupt handler.
*
* @param base FLEXSPI peripheral base address.
* @param handle pointer to flexspi_handle_t structure.
*/
void FLEXSPI_TransferHandleIRQ(FLEXSPI_Type *base, flexspi_handle_t *handle);
/*! @} */
#if defined(__cplusplus)
}
#endif /*_cplusplus. */
/*@}*/
#endif /* __FSL_FLEXSPI_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,492 @@
/*
* Copyright (c) 2013 - 2015, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file lpspi_interrupt.c
* @brief Demo for SPI function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.1.18
*/
#include "fsl_device_registers.h"
#include "fsl_debug_console.h"
#include "fsl_lpspi.h"
#include "board.h"
#include "fsl_common.h"
#include "pin_mux.h"
#if ((defined FSL_FEATURE_SOC_INTMUX_COUNT) && (FSL_FEATURE_SOC_INTMUX_COUNT))
#include "fsl_intmux.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/* Master related */
#define EXAMPLE_LPSPI_MASTER_BASEADDR (LPSPI3)
#define EXAMPLE_LPSPI_MASTER_IRQN (LPSPI3_IRQn)
#define EXAMPLE_LPSPI_MASTER_IRQHandler (LPSPI3_IRQHandler)
#define EXAMPLE_LPSPI_MASTER_PCS_FOR_INIT (kLPSPI_Pcs0)
#define EXAMPLE_LPSPI_MASTER_PCS_FOR_TRANSFER (kLPSPI_MasterPcs0)
/* Slave related */
#define EXAMPLE_LPSPI_SLAVE_BASEADDR (LPSPI1)
#define EXAMPLE_LPSPI_SLAVE_IRQN (LPSPI1_IRQn)
#define EXAMPLE_LPSPI_SLAVE_IRQHandler (LPSPI1_IRQHandler)
#define EXAMPLE_LPSPI_SLAVE_PCS_FOR_INIT (kLPSPI_Pcs0)
#define EXAMPLE_LPSPI_SLAVE_PCS_FOR_TRANSFER (kLPSPI_SlavePcs0)
/* Select USB1 PLL PFD0 (720 MHz) as lpspi clock source */
#define EXAMPLE_LPSPI_CLOCK_SOURCE_SELECT (1U)
/* Clock divider for master lpspi clock source */
#define EXAMPLE_LPSPI_CLOCK_SOURCE_DIVIDER (7U)
#define EXAMPLE_LPSPI_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (EXAMPLE_LPSPI_CLOCK_SOURCE_DIVIDER + 1U))
#define EXAMPLE_LPSPI_MASTER_CLOCK_FREQ EXAMPLE_LPSPI_CLOCK_FREQ
#define EXAMPLE_LPSPI_SLAVE_CLOCK_FREQ EXAMPLE_LPSPI_CLOCK_FREQ
#define TRANSFER_SIZE (512U) /*! Transfer dataSize .*/
#define TRANSFER_BAUDRATE (500000U) /*! Transfer baudrate - 500k */
#define spi_print KPrintf
#define spi_trace() KPrintf("lw: [%s][%d] passed!\n", __func__, __LINE__)
/*******************************************************************************
* Prototypes
******************************************************************************/
/* LPSPI user callback */
void LPSPI_SlaveUserCallback(LPSPI_Type *base, lpspi_slave_handle_t *handle, status_t status, void *userData);
void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData);
/*******************************************************************************
* Variables
******************************************************************************/
uint8_t masterRxData[TRANSFER_SIZE] = {0};
uint8_t masterTxData[TRANSFER_SIZE] = {0};
uint8_t slaveRxData[TRANSFER_SIZE] = {0};
uint8_t slaveTxData[TRANSFER_SIZE] = {0};
volatile uint32_t slaveTxCount;
volatile uint32_t slaveRxCount;
uint8_t g_slaveRxWatermark;
uint8_t g_slaveFifoSize;
volatile uint32_t masterTxCount;
volatile uint32_t masterRxCount;
uint8_t g_masterRxWatermark;
uint8_t g_masterFifoSize;
volatile bool isSlaveTransferCompleted = false;
volatile bool isMasterTransferCompleted = false;
/*******************************************************************************
* Code
******************************************************************************/
void LPSPI_SlaveUserCallback(LPSPI_Type *base, lpspi_slave_handle_t *handle, status_t status, void *userData)
{
if (status == kStatus_Success)
{
spi_print("This is LPSPI slave transfer completed callback. \r\n");
spi_print("It's a successful transfer. \r\n\r\n");
}
else if (status == kStatus_LPSPI_Error)
{
spi_print("This is LPSPI slave transfer completed callback. \r\n");
spi_print("Error occurred in this transfer. \r\n\r\n");
}
else
{
__NOP();
}
isSlaveTransferCompleted = true;
}
void LPSPI_MasterUserCallback(LPSPI_Type *base, lpspi_master_handle_t *handle, status_t status, void *userData)
{
isMasterTransferCompleted = true;
}
void EXAMPLE_LPSPI_SLAVE_IRQHandler(int vector, void *param)
{
if (slaveRxCount < TRANSFER_SIZE)
{
while (LPSPI_GetRxFifoCount(EXAMPLE_LPSPI_SLAVE_BASEADDR))
{
slaveRxData[slaveRxCount] = LPSPI_ReadData(EXAMPLE_LPSPI_SLAVE_BASEADDR);
slaveRxCount++;
if (slaveTxCount < TRANSFER_SIZE)
{
LPSPI_WriteData(EXAMPLE_LPSPI_SLAVE_BASEADDR, slaveTxData[slaveTxCount]);
slaveTxCount++;
}
if (slaveRxCount == TRANSFER_SIZE)
{
break;
}
}
}
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
if ((TRANSFER_SIZE - slaveRxCount) <= g_slaveRxWatermark)
{
EXAMPLE_LPSPI_SLAVE_BASEADDR->FCR =
(EXAMPLE_LPSPI_SLAVE_BASEADDR->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
LPSPI_FCR_RXWATER(((TRANSFER_SIZE - slaveRxCount) > 1) ? ((TRANSFER_SIZE - slaveRxCount) - 1U) : (0U));
}
/* Check if remaining receive byte count matches user request */
if ((slaveRxCount == TRANSFER_SIZE) && (slaveTxCount == TRANSFER_SIZE))
{
isSlaveTransferCompleted = true;
/* Disable interrupt requests */
LPSPI_DisableInterrupts(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_RxInterruptEnable);
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
DECLARE_HW_IRQ(EXAMPLE_LPSPI_SLAVE_IRQN, EXAMPLE_LPSPI_SLAVE_IRQHandler, NONE);
void EXAMPLE_LPSPI_MASTER_IRQHandler(int vector, void *param)
{
if (masterRxCount < TRANSFER_SIZE)
{
/* First, disable the interrupts to avoid potentially triggering another interrupt
* while reading out the RX FIFO as more data may be coming into the RX FIFO. We'll
* re-enable the interrupts EXAMPLE_LPSPI_MASTER_BASEADDRd on the LPSPI state after reading out the FIFO.
*/
LPSPI_DisableInterrupts(EXAMPLE_LPSPI_MASTER_BASEADDR, kLPSPI_RxInterruptEnable);
while (LPSPI_GetRxFifoCount(EXAMPLE_LPSPI_MASTER_BASEADDR))
{
/*Read out the data*/
masterRxData[masterRxCount] = LPSPI_ReadData(EXAMPLE_LPSPI_MASTER_BASEADDR);
masterRxCount++;
if (masterRxCount == TRANSFER_SIZE)
{
break;
}
}
/* Re-enable the interrupts only if rxCount indicates there is more data to receive,
* else we may get a spurious interrupt.
* */
if (masterRxCount < TRANSFER_SIZE)
{
/* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
LPSPI_EnableInterrupts(EXAMPLE_LPSPI_MASTER_BASEADDR, kLPSPI_RxInterruptEnable);
}
}
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
if ((TRANSFER_SIZE - masterRxCount) <= g_masterRxWatermark)
{
EXAMPLE_LPSPI_MASTER_BASEADDR->FCR =
(EXAMPLE_LPSPI_MASTER_BASEADDR->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
LPSPI_FCR_RXWATER(((TRANSFER_SIZE - masterRxCount) > 1) ? ((TRANSFER_SIZE - masterRxCount) - 1U) : (0U));
}
if (masterTxCount < TRANSFER_SIZE)
{
while ((LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_MASTER_BASEADDR) < g_masterFifoSize) &&
(masterTxCount - masterRxCount < g_masterFifoSize))
{
/*Write the word to TX register*/
LPSPI_WriteData(EXAMPLE_LPSPI_MASTER_BASEADDR, masterTxData[masterTxCount]);
++masterTxCount;
if (masterTxCount == TRANSFER_SIZE)
{
break;
}
}
}
/* Check if we're done with this transfer.*/
if ((masterTxCount == TRANSFER_SIZE) && (masterRxCount == TRANSFER_SIZE))
{
isMasterTransferCompleted = true;
/* Complete the transfer and disable the interrupts */
LPSPI_DisableInterrupts(EXAMPLE_LPSPI_MASTER_BASEADDR, kLPSPI_AllInterruptEnable);
}
/* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
exception return operation might vector to incorrect interrupt */
#if defined __CORTEX_M && (__CORTEX_M == 4U)
__DSB();
#endif
}
DECLARE_HW_IRQ(EXAMPLE_LPSPI_MASTER_IRQN, EXAMPLE_LPSPI_MASTER_IRQHandler, NONE);
void lpspi_config_init(void)
{
lpspi_master_config_t masterConfig;
lpspi_slave_config_t slaveConfig;
/*Master config*/
masterConfig.baudRate = TRANSFER_BAUDRATE;
masterConfig.bitsPerFrame = 8;
masterConfig.cpol = kLPSPI_ClockPolarityActiveHigh;
masterConfig.cpha = kLPSPI_ClockPhaseFirstEdge;
masterConfig.direction = kLPSPI_MsbFirst;
masterConfig.pcsToSckDelayInNanoSec = 1000000000 / masterConfig.baudRate;
masterConfig.lastSckToPcsDelayInNanoSec = 1000000000 / masterConfig.baudRate;
masterConfig.betweenTransferDelayInNanoSec = 1000000000 / masterConfig.baudRate;
masterConfig.whichPcs = EXAMPLE_LPSPI_MASTER_PCS_FOR_INIT;
masterConfig.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
masterConfig.pinCfg = kLPSPI_SdiInSdoOut;
masterConfig.dataOutConfig = kLpspiDataOutRetained;
LPSPI_MasterInit(EXAMPLE_LPSPI_MASTER_BASEADDR, &masterConfig, EXAMPLE_LPSPI_MASTER_CLOCK_FREQ);
/*Slave config*/
slaveConfig.bitsPerFrame = masterConfig.bitsPerFrame;
slaveConfig.cpol = masterConfig.cpol;
slaveConfig.cpha = masterConfig.cpha;
slaveConfig.direction = masterConfig.direction;
slaveConfig.whichPcs = EXAMPLE_LPSPI_SLAVE_PCS_FOR_INIT;
slaveConfig.pcsActiveHighOrLow = masterConfig.pcsActiveHighOrLow;
slaveConfig.pinCfg = kLPSPI_SdiInSdoOut;
slaveConfig.dataOutConfig = kLpspiDataOutRetained;
LPSPI_SlaveInit(EXAMPLE_LPSPI_SLAVE_BASEADDR, &slaveConfig);
}
/*!
* @brief Main function
*/
int test_spi(void)
{
/*Set clock source for LPSPI*/
CLOCK_SetMux(kCLOCK_LpspiMux, EXAMPLE_LPSPI_CLOCK_SOURCE_SELECT);
CLOCK_SetDiv(kCLOCK_LpspiDiv, EXAMPLE_LPSPI_CLOCK_SOURCE_DIVIDER);
spi_print("LPSPI functional interrupt example start.\r\n");
spi_print("This example use one lpspi instance as master and another as slave on one board.\r\n");
spi_print("Master uses interrupt way and slave uses interrupt way.\r\n");
spi_print(
"Note that some LPSPI instances interrupt is in INTMUX ,"
"you should set the intmux when you porting this example accordingly \r\n");
spi_print("Please make sure you make the correct line connection. Basically, the connection is: \r\n");
spi_print("LPSPI_master -- LPSPI_slave \r\n");
spi_print(" CLK -- CLK \r\n");
spi_print(" PCS -- PCS \r\n");
spi_print(" SOUT -- SIN \r\n");
spi_print(" SIN -- SOUT \r\n");
uint32_t errorCount;
uint32_t i;
uint32_t whichPcs;
uint8_t txWatermark;
/*Set up the transfer data*/
for (i = 0; i < TRANSFER_SIZE; i++)
{
masterTxData[i] = i % 256;
masterRxData[i] = 0;
slaveTxData[i] = ~masterTxData[i];
slaveRxData[i] = 0;
}
lpspi_config_init();
/******************Set up slave first ******************/
isSlaveTransferCompleted = false;
slaveTxCount = 0;
slaveRxCount = 0;
whichPcs = EXAMPLE_LPSPI_SLAVE_PCS_FOR_INIT;
/*The TX and RX FIFO sizes are always the same*/
g_slaveFifoSize = LPSPI_GetRxFifoSize(EXAMPLE_LPSPI_SLAVE_BASEADDR);
/*Set the RX and TX watermarks to reduce the ISR times.*/
if (g_slaveFifoSize > 1)
{
txWatermark = 1;
g_slaveRxWatermark = g_slaveFifoSize - 2;
}
else
{
txWatermark = 0;
g_slaveRxWatermark = 0;
}
LPSPI_SetFifoWatermarks(EXAMPLE_LPSPI_SLAVE_BASEADDR, txWatermark, g_slaveRxWatermark);
LPSPI_Enable(EXAMPLE_LPSPI_SLAVE_BASEADDR, false);
EXAMPLE_LPSPI_SLAVE_BASEADDR->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
LPSPI_Enable(EXAMPLE_LPSPI_SLAVE_BASEADDR, true);
/*Flush FIFO , clear status , disable all the interrupts.*/
LPSPI_FlushFifo(EXAMPLE_LPSPI_SLAVE_BASEADDR, true, true);
LPSPI_ClearStatusFlags(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_AllStatusFlag);
LPSPI_DisableInterrupts(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_AllInterruptEnable);
EXAMPLE_LPSPI_SLAVE_BASEADDR->TCR =
(EXAMPLE_LPSPI_SLAVE_BASEADDR->TCR &
~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
LPSPI_TCR_CONT(0) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(0) | LPSPI_TCR_TXMSK(0) | LPSPI_TCR_PCS(whichPcs);
/* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
* and you should also enable the INTMUX interrupt in your application.
*/
EnableIRQ(EXAMPLE_LPSPI_SLAVE_IRQN);
/*TCR is also shared the FIFO , so wait for TCR written.*/
while (LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_SLAVE_BASEADDR) != 0)
{
}
spi_trace();
/*Fill up the TX data in FIFO */
while (LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_SLAVE_BASEADDR) < g_slaveFifoSize)
{
/*Write the word to TX register*/
LPSPI_WriteData(EXAMPLE_LPSPI_SLAVE_BASEADDR, slaveTxData[slaveTxCount]);
++slaveTxCount;
if (slaveTxCount == TRANSFER_SIZE)
{
break;
}
}
spi_trace();
LPSPI_EnableInterrupts(EXAMPLE_LPSPI_SLAVE_BASEADDR, kLPSPI_RxInterruptEnable);
/******************Set up master transfer******************/
isMasterTransferCompleted = false;
masterTxCount = 0;
masterRxCount = 0;
whichPcs = EXAMPLE_LPSPI_MASTER_PCS_FOR_INIT;
/*The TX and RX FIFO sizes are always the same*/
g_masterFifoSize = LPSPI_GetRxFifoSize(EXAMPLE_LPSPI_MASTER_BASEADDR);
/*Set the RX and TX watermarks to reduce the ISR times.*/
if (g_masterFifoSize > 1)
{
txWatermark = 1;
g_masterRxWatermark = g_masterFifoSize - 2;
}
else
{
txWatermark = 0;
g_masterRxWatermark = 0;
}
LPSPI_SetFifoWatermarks(EXAMPLE_LPSPI_MASTER_BASEADDR, txWatermark, g_masterRxWatermark);
LPSPI_Enable(EXAMPLE_LPSPI_MASTER_BASEADDR, false);
EXAMPLE_LPSPI_MASTER_BASEADDR->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
LPSPI_Enable(EXAMPLE_LPSPI_MASTER_BASEADDR, true);
/*Flush FIFO , clear status , disable all the inerrupts.*/
LPSPI_FlushFifo(EXAMPLE_LPSPI_MASTER_BASEADDR, true, true);
LPSPI_ClearStatusFlags(EXAMPLE_LPSPI_MASTER_BASEADDR, kLPSPI_AllStatusFlag);
LPSPI_DisableInterrupts(EXAMPLE_LPSPI_MASTER_BASEADDR, kLPSPI_AllInterruptEnable);
EXAMPLE_LPSPI_MASTER_BASEADDR->TCR =
(EXAMPLE_LPSPI_MASTER_BASEADDR->TCR &
~(LPSPI_TCR_CONT_MASK | LPSPI_TCR_CONTC_MASK | LPSPI_TCR_RXMSK_MASK | LPSPI_TCR_PCS_MASK)) |
LPSPI_TCR_CONT(0) | LPSPI_TCR_CONTC(0) | LPSPI_TCR_RXMSK(0) | LPSPI_TCR_TXMSK(0) | LPSPI_TCR_PCS(whichPcs);
/* Enable the NVIC for LPSPI peripheral. Note that below code is useless if the LPSPI interrupt is in INTMUX ,
* and you should also enable the INTMUX interupt in your application.
*/
EnableIRQ(EXAMPLE_LPSPI_MASTER_IRQN);
/*TCR is also shared the FIFO , so wait for TCR written.*/
while (LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_MASTER_BASEADDR) != 0)
{
}
spi_trace();
/*Fill up the TX data in FIFO */
while ((LPSPI_GetTxFifoCount(EXAMPLE_LPSPI_MASTER_BASEADDR) < g_masterFifoSize) &&
(masterTxCount - masterRxCount < g_masterFifoSize))
{
/*Write the word to TX register*/
LPSPI_WriteData(EXAMPLE_LPSPI_MASTER_BASEADDR, masterTxData[masterTxCount]);
++masterTxCount;
spi_trace();
if (masterTxCount == TRANSFER_SIZE)
{
break;
}
}
spi_trace();
LPSPI_EnableInterrupts(EXAMPLE_LPSPI_MASTER_BASEADDR, kLPSPI_RxInterruptEnable);
/******************Wait for master and slave transfer completed.******************/
while ((!isSlaveTransferCompleted) || (!isMasterTransferCompleted))
{
}
spi_trace();
errorCount = 0;
for (i = 0; i < TRANSFER_SIZE; i++)
{
if (masterTxData[i] != slaveRxData[i])
{
errorCount++;
}
if (slaveTxData[i] != masterRxData[i])
{
errorCount++;
}
}
if (errorCount == 0)
{
spi_print("\r\nLPSPI transfer all data matched! \r\n");
}
else
{
spi_print("\r\nError occurred in LPSPI transfer ! \r\n");
}
LPSPI_Deinit(EXAMPLE_LPSPI_MASTER_BASEADDR);
LPSPI_Deinit(EXAMPLE_LPSPI_SLAVE_BASEADDR);
spi_print("End of example. \r\n");
while (1)
{
}
spi_trace();
}
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
spi, test_spi, SPI test );

View File

@ -6,18 +6,6 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file fsl_lpuart.c
* @brief fsl uart drivers

View File

@ -50,11 +50,11 @@ int UserPrintInfo(unsigned long i);
struct utask
{
char name[NAME_NUM_MAX];
void *func_entry;
void *func_param;
int32_t stack_size;
uint8_t prio;
char name[NAME_NUM_MAX];
void *func_entry;
void *func_param;
int32_t stack_size;
uint8_t prio;
};
typedef struct utask UtaskType;
@ -109,7 +109,7 @@ typedef int32 EventIdType;
EventIdType UserEventCreate(uint8_t flag);
void UserEventDelete(EventIdType event);
x_err_t UserEventTrigger(EventIdType event, uint32_t set);
x_err_t UserEventProcess(EventIdType event, uint32_t set, uint8_t option,
x_err_t UserEventProcess(EventIdType event, uint32_t set, uint8_t option,
int32_t wait_time, uint32_t *Recved);
x_err_t UserEventReinit(EventIdType event);
#endif
@ -162,7 +162,7 @@ int statfs(const char *path, struct statfs *buf);
int Userprintf(const char *fmt, ...);
#define printf Userprintf
#define printf Userprintf
#else
@ -172,11 +172,11 @@ int Userprintf(const char *fmt, ...);
struct utask
{
char name[NAME_NUM_MAX];
void *func_entry;
void *func_param;
int32_t stack_size;
uint8_t prio;
char name[NAME_NUM_MAX];
void *func_entry;
void *func_param;
int32_t stack_size;
uint8_t prio;
};
typedef struct utask UtaskType;
int32_t UserTaskCreate(UtaskType utask);

View File

@ -13,7 +13,7 @@
/**
* @file test_i2c.c
* @brief support to test i2c function
* @version 1.0
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
@ -24,15 +24,15 @@
/*********************************************************************************************************************************************************/
/*
* functionI2C device sample support reading temperature and humidity sensor data and printfing on the terminal
* shell cmdi2c_HS3000_sample i2c1
* shell cmd parami2c device name,if null means default i2c device name
* function: I2C device sample support reading temperature and humidity sensor data and printfing on the terminal
* shell cmd: i2c_HS3000_sample i2c1
* shell cmd param: i2c device name,if null means default i2c device name
*/
#define HS_I2C_BUS_NAME I2C_BUS_NAME_1 /* I2C bus name */
#define HS_I2C_DEV_NAME I2C_1_DEVICE_NAME_0/* I2C device name */
#define HS_I2C_DRV_NAME I2C_DRV_NAME_1 /* I2C driver name */
#define ADDR 0x44 /* slave address */
#define HS_I2C_BUS_NAME I2C_BUS_NAME_1 /* I2C bus name */
#define HS_I2C_DEV_NAME I2C_1_DEVICE_NAME_0 /* I2C device name */
#define HS_I2C_DRV_NAME I2C_DRV_NAME_1 /* I2C driver name */
#define ADDR 0x44 /* slave address */
static struct Bus *i2c_bus = NONE; /* I2C bus handle */
@ -55,7 +55,7 @@ static x_err_t WriteReg(struct HardwareDev *dev)
return EOK;
}
else{
return -ERROR;
return -ERROR;
}
}
@ -89,7 +89,7 @@ static void ReadTempHumi(float *cur_temp, float *cur_humi)
if(EOK != ret){
KPrintf("ReadTempHumi ReadRegs failed\n");
}
*cur_humi = ((temp[0] <<8 | temp[1] )& 0x3fff ) * 100.0 / ( (1 << 14) - 1); /* humidity data */
*cur_temp = ((temp[2] << 8 | temp[3]) >> 2) * 165.0 /( (1 << 14) - 1) - 40.0; /* temperature data */
@ -113,7 +113,7 @@ static void HS3000Init(const char *bus_name, const char *dev_name, const char *
KPrintf("i2c match drv %s %p dev %s %p error\n", drv_name, i2c_bus->owner_driver, dev_name, i2c_bus->owner_haldev);
}
else{
KPrintf("HS3000Init successfully!write %p read %p\n",
KPrintf("HS3000Init successfully!write %p read %p\n",
i2c_bus->owner_haldev->dev_done->write,
i2c_bus->owner_haldev->dev_done->read);
}
@ -144,15 +144,15 @@ void TskHs300xTest()
{
memset(&g_hs300x_data, 0, sizeof(Hs300xDataType));
KPrintf("Tsk create successfully!\n");
while(1)
{
Hs300xRead(&g_hs300x_data);
KPrintf("HS300X:I2C humidity:%d.%d temperature:%d.%d\n",
g_hs300x_data.humi_high,
g_hs300x_data.humi_low,
g_hs300x_data.temp_high,
KPrintf("HS300X:I2C humidity:%d.%d temperature:%d.%d\n",
g_hs300x_data.humi_high,
g_hs300x_data.humi_low,
g_hs300x_data.temp_high,
g_hs300x_data.temp_low);
MdelayKTask(1000);
@ -167,12 +167,14 @@ void Hs300xI2cTest(void)
MdelayKTask(1000);
x_err_t flag;
int32 Tsk_hs300x = KTaskCreate("Tsk_hs300x", TskHs300xTest, NONE, 2048, 10);
flag = StartupKTask(Tsk_hs300x);
int32 Tsk_hs300x = KTaskCreate("Tsk_hs300x", TskHs300xTest, NONE, 2048, 10);
flag = StartupKTask(Tsk_hs300x);
if (EOK != flag){
KPrintf("Hs300xI2cTest StartupKTask failed!\n");
return;
}
KPrintf("Hs300xI2cTest StartupKTask failed!\n");
return;
}
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),
Hs300xI2cTest, Hs300xI2cTest, Test the HS300X using I2C);

View File

@ -1,10 +1,14 @@
SRC_DIR :=
SRC_FILES += bus.c
SRC_FILES += bus.c
ifeq ($(CONFIG_KERNEL_DEVICE),y)
SRC_FILES += device.c
endif
ifeq ($(CONFIG_RESOURCES_ADC),y)
SRC_DIR += adc
endif
ifeq ($(CONFIG_RESOURCES_CAN),y)
SRC_DIR += can
endif

View File

@ -13,7 +13,7 @@
/**
* @file bus_adc.c
* @brief register adc bus function using bus driver framework
* @version 1.1
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-12-28
*/
@ -21,6 +21,8 @@
#include <bus_adc.h>
#include <dev_adc.h>
#if 0
/*Register the ADC BUS*/
int AdcBusInit(struct AdcBus *adc_bus, const char *bus_name)
{
@ -42,7 +44,7 @@ int AdcBusInit(struct AdcBus *adc_bus, const char *bus_name)
return ret;
}
} else {
KPrintf("AdcBusInit BusRegister bus has been register state%u\n", adc_bus->bus.bus_state);
KPrintf("AdcBusInit BusRegister bus has been register state%u\n", adc_bus->bus.bus_state);
}
return ret;
@ -89,7 +91,7 @@ int AdcReleaseBus(struct AdcBus *adc_bus)
int AdcDriverAttachToBus(const char *drv_name, const char *bus_name)
{
NULL_PARAM_CHECK(drv_name);
NULL_PARAM_CHECK(bus_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
@ -120,3 +122,4 @@ int AdcDriverAttachToBus(const char *drv_name, const char *bus_name)
return ret;
}
#endif

View File

@ -13,7 +13,7 @@
/**
* @file dev_adc.c
* @brief register adc dev function using bus driver framework
* @version 1.1
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-12-28
*/
@ -29,16 +29,17 @@ static void AdcDeviceLinkInit()
InitDoubleLinkList(&adcdev_linklist);
}
#if 0
/*Find the register ADC device*/
HardwareDevType AdcDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
DoubleLinklistType *head = &adcdev_linklist;
for (node = head->node_next; node != head; node = node->node_next) {
for (node = head->node_next; node != head; node = node->node_next) {
device = SYS_DOUBLE_LINKLIST_ENTRY(node, struct HardwareDev, dev_link);
if ((!strcmp(device->dev_name, dev_name)) && (dev_type == device->dev_type)) {
return device;
@ -55,7 +56,7 @@ int AdcDeviceRegister(struct AdcHardwareDevice *adc_device, void *adc_param, con
NULL_PARAM_CHECK(adc_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (!dev_link_flag) {
@ -74,7 +75,7 @@ int AdcDeviceRegister(struct AdcHardwareDevice *adc_device, void *adc_param, con
DoubleLinkListInsertNodeAfter(&adcdev_linklist, &(adc_device->haldev.dev_link));
} else {
KPrintf("AdcDeviceRegister device has been register state%u\n", adc_device->haldev.dev_state);
KPrintf("AdcDeviceRegister device has been register state%u\n", adc_device->haldev.dev_state);
}
return ret;
@ -85,7 +86,7 @@ int AdcDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
@ -104,7 +105,7 @@ int AdcDeviceAttachToBus(const char *dev_name, const char *bus_name)
KPrintf("AdcDeviceAttachToBus find adc device error!name %s\n", dev_name);
return ERROR;
}
if (TYPE_ADC_DEV == device->dev_type) {
ret = DeviceRegisterToBus(bus, device);
@ -117,3 +118,5 @@ int AdcDeviceAttachToBus(const char *dev_name, const char *bus_name)
return EOK;
}
#endif

View File

@ -13,7 +13,7 @@
/**
* @file drv_adc.c
* @brief register adc drv function using bus driver framework
* @version 1.1
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-12-28
*/
@ -29,11 +29,12 @@ static void AdcDrvLinkInit()
InitDoubleLinkList(&adcdrv_linklist);
}
#if 0
/*Find the regiter driver*/
DriverType AdcDriverFind(const char *drv_name, enum DriverType_e drv_type)
{
NULL_PARAM_CHECK(drv_name);
struct Driver *driver = NONE;
DoubleLinklistType *node = NONE;
@ -67,3 +68,4 @@ int AdcDriverRegister(struct Driver *driver)
return ret;
}
#endif

View File

@ -12,8 +12,7 @@
/**
* @file bus.c
* @brief 1support bus driver framework2provide bus API
* @version 1.0
* @brief Support bus driver framework provide bus API version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
@ -71,7 +70,7 @@ static int BusMatchDrvDev(struct Driver *driver, struct HardwareDev *device)
* @param dev - dev pointer
* @param drv_name - drv name
* @param configure_info - BusConfigureInfo pointer
* @return successfulEOKfailedERROR
* @return successful:EOK,failed:ERROR
*/
int DeviceObtainBus(struct Bus *bus, struct HardwareDev *dev, const char *drv_name, struct BusConfigureInfo *configure_info)
{
@ -88,7 +87,7 @@ int DeviceObtainBus(struct Bus *bus, struct HardwareDev *dev, const char *drv_na
if(bus->owner_haldev != dev) {
struct Driver *drv = BusFindDriver(bus, drv_name);
configure_info->configure_cmd = OPE_CFG;
drv->configure(drv, configure_info);
@ -104,7 +103,7 @@ int DeviceObtainBus(struct Bus *bus, struct HardwareDev *dev, const char *drv_na
/**
* @Description: support to register bus pointer with linklist
* @param bus - bus pointer
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
int BusRegister(struct Bus *bus)
{
@ -125,7 +124,7 @@ int BusRegister(struct Bus *bus)
/**
* @Description: support to release bus pointer in linklist
* @param bus - bus pointer
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
int BusRelease(struct Bus *bus)
{
@ -147,7 +146,7 @@ int BusRelease(struct Bus *bus)
/**
* @Description: support to unregister bus pointer and delete its linklist node
* @param bus - bus pointer
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
int BusUnregister(struct Bus *bus)
{
@ -164,7 +163,7 @@ int BusUnregister(struct Bus *bus)
* @Description: support to register driver pointer to bus pointer
* @param bus - bus pointer
* @param driver - driver pointer
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
int DriverRegisterToBus(struct Bus *bus, struct Driver *driver)
{
@ -183,12 +182,12 @@ int DriverRegisterToBus(struct Bus *bus, struct Driver *driver)
* @Description: support to register dev pointer to bus pointer
* @param bus - bus pointer
* @param device - device pointer
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
int DeviceRegisterToBus(struct Bus *bus, struct HardwareDev *device)
{
NULL_PARAM_CHECK(bus);
NULL_PARAM_CHECK(device);
NULL_PARAM_CHECK(device);
device->owner_bus = bus;
bus->haldev_cnt++;
@ -202,7 +201,7 @@ int DeviceRegisterToBus(struct Bus *bus, struct HardwareDev *device)
* @Description: support to delete driver pointer from bus pointer
* @param bus - bus pointer
* @param driver - driver pointer
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
int DriverDeleteFromBus(struct Bus *bus, struct Driver *driver)
{
@ -222,12 +221,12 @@ int DriverDeleteFromBus(struct Bus *bus, struct Driver *driver)
* @Description: support to delete dev pointer from bus pointer
* @param bus - bus pointer
* @param device - device pointer
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
int DeviceDeleteFromBus(struct Bus *bus, struct HardwareDev *device)
{
NULL_PARAM_CHECK(bus);
NULL_PARAM_CHECK(device);
NULL_PARAM_CHECK(device);
bus->haldev_cnt--;
@ -241,7 +240,7 @@ int DeviceDeleteFromBus(struct Bus *bus, struct HardwareDev *device)
/**
* @Description: support to find bus pointer by bus name
* @param bus_name - bus name
* @return successfulbus pointerfailedNONE
* @return successful:bus pointer,failed:NONE
*/
BusType BusFind(const char *bus_name)
{
@ -266,7 +265,7 @@ BusType BusFind(const char *bus_name)
* @Description: support to find driver pointer of certain bus by driver name
* @param bus - bus pointer
* @param driver_name - driver name
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
DriverType BusFindDriver(struct Bus *bus, const char *driver_name)
{
@ -292,7 +291,7 @@ DriverType BusFindDriver(struct Bus *bus, const char *driver_name)
* @Description: support to find device pointer of certain bus by device name
* @param bus - bus pointer
* @param device_name - device name
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
HardwareDevType BusFindDevice(struct Bus *bus, const char *device_name)
{
@ -319,7 +318,7 @@ HardwareDevType BusFindDevice(struct Bus *bus, const char *device_name)
* @Description: support to set dev receive function callback
* @param dev - dev pointer
* @param dev_recv_callback - callback function
* @return successfulEOKfailedERROR
* @return successful:EOK,failed:ERROR
*/
uint32 BusDevRecvCallback(struct HardwareDev *dev, int (*dev_recv_callback) (void *dev, x_size_t length))
{
@ -333,7 +332,7 @@ uint32 BusDevRecvCallback(struct HardwareDev *dev, int (*dev_recv_callback) (voi
/**
* @Description: support to open dev
* @param dev - dev pointer
* @return successfulEOKfailedERROR
* @return successful:EOK,failed:ERROR
*/
uint32 BusDevOpen(struct HardwareDev *dev)
{
@ -355,7 +354,7 @@ uint32 BusDevOpen(struct HardwareDev *dev)
/**
* @Description: support to close dev
* @param dev - dev pointer
* @return successfulEOKfailedERROR
* @return successful:EOK,failed:ERROR
*/
uint32 BusDevClose(struct HardwareDev *dev)
{
@ -378,12 +377,12 @@ uint32 BusDevClose(struct HardwareDev *dev)
* @Description: support to write data to dev
* @param dev - dev pointer
* @param write_param - BusBlockWriteParam
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
uint32 BusDevWriteData(struct HardwareDev *dev, struct BusBlockWriteParam *write_param)
{
NULL_PARAM_CHECK(dev);
if (dev->dev_done->write) {
return dev->dev_done->write(dev, write_param);
}
@ -395,12 +394,12 @@ uint32 BusDevWriteData(struct HardwareDev *dev, struct BusBlockWriteParam *write
* @Description: support to read data from dev
* @param dev - dev pointer
* @param read_param - BusBlockReadParam
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
uint32 BusDevReadData(struct HardwareDev *dev, struct BusBlockReadParam *read_param)
{
NULL_PARAM_CHECK(dev);
if (dev->dev_done->read) {
return dev->dev_done->read(dev, read_param);
}
@ -412,7 +411,7 @@ uint32 BusDevReadData(struct HardwareDev *dev, struct BusBlockReadParam *read_pa
* @Description: support to configure drv, include OPE_CFG and OPE_INT
* @param drv - drv pointer
* @param configure_info - BusConfigureInfo
* @return successfulEOKfailedNONE
* @return successful:EOK,failed:NONE
*/
uint32 BusDrvConfigure(struct Driver *drv, struct BusConfigureInfo *configure_info)
{
@ -430,4 +429,4 @@ uint32 BusDrvConfigure(struct Driver *drv, struct BusConfigureInfo *configure_in
}
return ret;
}
}

View File

@ -29,17 +29,6 @@
* Author: Simon Goldschmidt
*
*/
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file sys_arch.c
@ -48,6 +37,7 @@
* @author AIIT XUOS Lab
* @date 2021-05-29
*/
#include "debug.h"
#include <lwip/opt.h>
@ -79,7 +69,6 @@
#include "board.h"
#include "ethernet.h"
#include "enet_ethernetif.h"
#include <transform.h>
char lwip_ipaddr[] = {192, 168, 250, 253};
char lwip_netmask[] = {255, 255, 255, 0};
@ -463,9 +452,10 @@ void lwip_input_thread(void *param)
void lwip_config_input(struct netif *net)
{
pthread_t th_id = 0;
sys_thread_t th_id = 0;
th_id = sys_thread_new("eth_input", lwip_input_thread, net, 4096, 15);
th_id = sys_thread_new("eth_input", lwip_input_thread, net, LWIP_TASK_STACK_SIZE,
LWIP_DEMO_TASK_PRIO);
if (th_id >= 0) {
lw_print("%s %d successfully!\n", __func__, th_id);

View File

@ -29,17 +29,6 @@
* Author: Simon Goldschmidt
*
*/
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file sys_arch.h

View File

@ -1,12 +1,3 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
@ -79,8 +70,8 @@ void lwip_setip_thread(int argc, char *argv[])
pthread_t th_id;
pthread_attr_t attr;
attr.schedparam.sched_priority = 15;
attr.stacksize = 4096;
attr.schedparam.sched_priority = LWIP_DEMO_TASK_PRIO;
attr.stacksize = LWIP_TASK_STACK_SIZE;
if(argc >= 4)
{

View File

@ -1,3 +1,23 @@
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file lwip_demo.h
* @brief lwip demo header
* @version 1.0
* @author AIIT XUOS Lab
* @date 2022.1.18
*/
#ifndef __LWIP_DEMO_H__
#define __LWIP_DEMO_H__

View File

@ -7,6 +7,14 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file lwip_dhcp_demo.c
* @brief Demo for DHCP function
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021.12.15
*/
/*******************************************************************************
* Includes
******************************************************************************/

View File

@ -1,12 +1,3 @@
/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2019 NXP
* All rights reserved.
*
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/*
* Copyright (c) 2021 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
@ -27,7 +18,6 @@
* @date 2021.12.15
*/
/*******************************************************************************
* Includes
******************************************************************************/
@ -46,7 +36,6 @@
#include "pin_mux.h"
#include "clock_config.h"
#include <transform.h>
#include <sys_arch.h>
#include "connect_ethernet.h"
@ -71,14 +60,6 @@ ip4_addr_t ping_addr;
* Code
******************************************************************************/
static void *lwip_ping_test(void *param)
{
IP4_ADDR(&ping_addr, lwip_gwaddr[0], lwip_gwaddr[1], lwip_gwaddr[2], lwip_gwaddr[3]);
ETH_BSP_Config();
lwip_config_net(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
ping_init(&ping_addr);
}
void lwip_ping_thread(int argc, char *argv[])
{
int result = 0;

View File

@ -17,7 +17,6 @@
* @author AIIT XUOS Lab
* @date 2021-05-29
*/
#include <transform.h>
#include <xiuos.h>
#include "board.h"
#include "sys_arch.h"

View File

@ -11,13 +11,12 @@
*/
/**
* @file tcp_echo_socket_demo.c
* @file lwip_udp_demo.c
* @brief One UDP demo based on LwIP
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-05-29
*/
#include <transform.h>
#include <xiuos.h>
#include "board.h"
#include "sys_arch.h"
@ -95,8 +94,7 @@ __exit:
void *lwip_udp_send_run(int argc, char *argv[])
{
int result = 0;
pthread_t th_id;
pthread_attr_t attr;
sys_thread_t th_id;
memset(udp_send_msg, 0, sizeof(udp_send_msg));
@ -118,7 +116,7 @@ void *lwip_udp_send_run(int argc, char *argv[])
ETH_BSP_Config();
lwip_config_tcp(lwip_ipaddr, lwip_netmask, lwip_gwaddr);
sys_thread_new("udp socket send", lwip_udp_send, NULL, 4096, 25);
sys_thread_new("udp socket send", lwip_udp_send, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),

View File

@ -13,7 +13,7 @@
/**
* @file dev_adc.h
* @brief define adc dev function using bus driver framework
* @version 1.1
* @version 1.1
* @author AIIT XUOS Lab
* @date 2021-12-28
*/

View File

@ -13,7 +13,7 @@
/**
* @file flash_spi.h
* @brief define spi-flash dev function using bus driver framework
* @version 1.0
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/

View File

@ -13,7 +13,7 @@
/**
* @file dev_spi.c
* @brief register spi dev function using bus driver framework
* @version 1.0
* @version 1.0
* @author AIIT XUOS Lab
* @date 2021-04-24
*/
@ -36,7 +36,7 @@ static uint32 SpiDeviceOpen(void *dev)
SpiDevConfigureCs(dev, 1, 0);
return EOK;
}
}
static uint32 SpiDeviceClose(void *dev)
{
@ -45,7 +45,7 @@ static uint32 SpiDeviceClose(void *dev)
SpiDevConfigureCs(dev, 0, 1);
return EOK;
}
}
static uint32 SpiDeviceWrite(void *dev, struct BusBlockWriteParam *write_param)
{
@ -120,7 +120,7 @@ static const struct HalDevDone dev_done =
HardwareDevType SpiDeviceFind(const char *dev_name, enum DevType dev_type)
{
NULL_PARAM_CHECK(dev_name);
struct HardwareDev *device = NONE;
DoubleLinklistType *node = NONE;
@ -142,7 +142,7 @@ int SpiDeviceRegister(struct SpiHardwareDevice *spi_device, void *spi_param, con
NULL_PARAM_CHECK(spi_device);
NULL_PARAM_CHECK(device_name);
x_err_t ret = EOK;
x_err_t ret = EOK;
static x_bool dev_link_flag = RET_FALSE;
if (!dev_link_flag) {
@ -164,7 +164,7 @@ int SpiDeviceRegister(struct SpiHardwareDevice *spi_device, void *spi_param, con
DoubleLinkListInsertNodeAfter(&spidev_linklist, &(spi_device->haldev.dev_link));
} else {
KPrintf("SpiDeviceRegister device has been register state%u\n", spi_device->haldev.dev_state);
KPrintf("SpiDeviceRegister device has been register state%u\n", spi_device->haldev.dev_state);
}
return ret;
@ -174,7 +174,7 @@ int SpiDeviceAttachToBus(const char *dev_name, const char *bus_name)
{
NULL_PARAM_CHECK(dev_name);
NULL_PARAM_CHECK(bus_name);
x_err_t ret = EOK;
struct Bus *bus;
@ -185,7 +185,7 @@ int SpiDeviceAttachToBus(const char *dev_name, const char *bus_name)
KPrintf("SpiDeviceAttachToBus find spi bus error!name %s\n", bus_name);
return ERROR;
}
if (TYPE_SPI_BUS == bus->bus_type) {
device = SpiDeviceFind(dev_name, TYPE_SPI_DEV);
if (NONE == device) {