forked from xuos/xiuos
Merge branch 'develop' of https://git.trustie.net/wwg666/xiuos into develop
This commit is contained in:
@@ -23,6 +23,7 @@ Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support imxrt1052-board MPU、clock、memory init
|
||||
2. support imxrt1052-board uart、semc、sdio driver init
|
||||
3. support imxrt1052-board I2C, SPI, ADC, RTC driver init
|
||||
*************************************************/
|
||||
|
||||
#include "fsl_common.h"
|
||||
@@ -67,6 +68,9 @@ int MountSDCard(void)
|
||||
|
||||
#include <connect_ethernet.h>
|
||||
#include <connect_uart.h>
|
||||
#include <connect_adc.h>
|
||||
#include <connect_spi.h>
|
||||
#include <connect_rtc.h>
|
||||
|
||||
#define NVIC_PRIORITYGROUP_0 0x00000007U /*!< 0 bits for pre-emption priority
|
||||
4 bits for subpriority */
|
||||
@@ -660,6 +664,18 @@ void InitBoardHardware()
|
||||
Imrt1052HwUartInit();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_ADC
|
||||
Imrt1052HwAdcInit();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SPI
|
||||
Imrt1052HwSpiInit();
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_RTC
|
||||
Imrt1052HwRtcInit();
|
||||
#endif
|
||||
|
||||
InstallConsole(KERNEL_CONSOLE_BUS_NAME, KERNEL_CONSOLE_DRV_NAME, KERNEL_CONSOLE_DEVICE_NAME);
|
||||
|
||||
#ifdef BSP_USING_SDIO
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
export CROSS_COMPILE ?=/usr/bin/arm-none-eabi-
|
||||
|
||||
export CFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb
|
||||
export CFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g -fgnu89-inline -Wa,-mimplicit-it=thumb
|
||||
export AFLAGS := -c -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -x assembler-with-cpp -Wa,-mimplicit-it=thumb -gdwarf-2
|
||||
|
||||
### if use USB function, use special lds file because USB uses ITCM
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_USB),y)
|
||||
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_ok1052-c.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link-usb.lds
|
||||
else
|
||||
export LFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_ok1052-c.map,-cref,-u,Reset_Handler -T $(BSP_ROOT)/link.lds
|
||||
export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g
|
||||
endif
|
||||
|
||||
export CXXFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Dgcc -O0 -gdwarf-2 -g
|
||||
|
||||
export APPLFLAGS := -mcpu=cortex-m7 -mthumb -ffunction-sections -fdata-sections -Wl,--gc-sections,-Map=XiZi_app.map,-cref,-u, -T $(BSP_ROOT)/link_userspace.lds
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Executable
+250
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
** ###################################################################
|
||||
** Processors: MIMXRT1052CVJ5B
|
||||
** MIMXRT1052CVL5B
|
||||
** MIMXRT1052DVJ6B
|
||||
** MIMXRT1052DVL6B
|
||||
**
|
||||
** Compiler: GNU C Compiler
|
||||
** Reference manual: IMXRT1050RM Rev.1, 03/2018
|
||||
** Version: rev. 1.0, 2018-09-21
|
||||
** Build: b180921
|
||||
**
|
||||
** Abstract:
|
||||
** Linker file for the GNU C Compiler
|
||||
**
|
||||
** Copyright 2016 Freescale Semiconductor, Inc.
|
||||
** Copyright 2016-2018 NXP
|
||||
** All rights reserved.
|
||||
**
|
||||
** SPDX-License-Identifier: BSD-3-Clause
|
||||
**
|
||||
** http: www.nxp.com
|
||||
** mail: support@nxp.com
|
||||
**
|
||||
** ###################################################################
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @file link.lds
|
||||
* @brief ok1052-c Linker script
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-05-28
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: link.lds
|
||||
Description: ok1052-c Linker script
|
||||
Others: take MIMXRT1052xxxxx_flexspi_nor.ld for references
|
||||
History:
|
||||
1. Date: 2021-05-28
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. add shell cmd table and g_service_table
|
||||
*************************************************/
|
||||
|
||||
/* Entry Point */
|
||||
ENTRY(Reset_Handler)
|
||||
|
||||
HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400;
|
||||
STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x1000;
|
||||
|
||||
/* Specify the memory areas */
|
||||
MEMORY
|
||||
{
|
||||
m_interrupts (RX) : ORIGIN = 0x60002000, LENGTH = 0x00000400
|
||||
m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00
|
||||
m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000
|
||||
m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000
|
||||
}
|
||||
|
||||
/* Define output sections */
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
/* The startup code goes first into internal RAM */
|
||||
.interrupts :
|
||||
{
|
||||
__VECTOR_TABLE = .;
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.isr_vector)) /* Startup code */
|
||||
. = ALIGN(4);
|
||||
} > m_interrupts
|
||||
|
||||
__VECTOR_RAM = __VECTOR_TABLE;
|
||||
__RAM_VECTOR_TABLE_SIZE_BYTES = 0x0;
|
||||
|
||||
/* The program code and other data goes into internal RAM */
|
||||
.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.text) /* .text sections (code) */
|
||||
*(.text*) /* .text* sections (code) */
|
||||
*(.rodata) /* .rodata sections (constants, strings, etc.) */
|
||||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
|
||||
*(.glue_7) /* glue arm to thumb code */
|
||||
*(.glue_7t) /* glue thumb to arm code */
|
||||
*(.eh_frame)
|
||||
KEEP (*(.init))
|
||||
KEEP (*(.fini))
|
||||
. = ALIGN(4);
|
||||
|
||||
|
||||
/* section information for shell */
|
||||
. = ALIGN(4);
|
||||
_shell_command_start = .;
|
||||
KEEP (*(shellCommand))
|
||||
_shell_command_end = .;
|
||||
. = ALIGN(4);
|
||||
|
||||
__isrtbl_idx_start = .;
|
||||
KEEP(*(.isrtbl.idx))
|
||||
__isrtbl_start = .;
|
||||
KEEP(*(.isrtbl))
|
||||
__isrtbl_end = .;
|
||||
. = ALIGN(4);
|
||||
|
||||
PROVIDE(g_service_table_start = ABSOLUTE(.));
|
||||
KEEP(*(.g_service_table))
|
||||
PROVIDE(g_service_table_end = ABSOLUTE(.));
|
||||
} > m_text
|
||||
|
||||
.ARM.extab :
|
||||
{
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
} > m_text
|
||||
|
||||
.ARM :
|
||||
{
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx*)
|
||||
__exidx_end = .;
|
||||
} > m_text
|
||||
|
||||
.ctors :
|
||||
{
|
||||
__CTOR_LIST__ = .;
|
||||
/* gcc uses crtbegin.o to find the start of
|
||||
the constructors, so we make sure it is
|
||||
first. Because this is a wildcard, it
|
||||
doesn't matter if the user does not
|
||||
actually link against crtbegin.o; the
|
||||
linker won't look for a file to match a
|
||||
wildcard. The wildcard also means that it
|
||||
doesn't matter which directory crtbegin.o
|
||||
is in. */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*crtbegin?.o(.ctors))
|
||||
/* We don't want to include the .ctor section from
|
||||
from the crtend.o file until after the sorted ctors.
|
||||
The .ctor section from the crtend file contains the
|
||||
end of ctors marker and it must be last */
|
||||
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
__CTOR_END__ = .;
|
||||
} > m_text
|
||||
|
||||
.dtors :
|
||||
{
|
||||
__DTOR_LIST__ = .;
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*crtbegin?.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
__DTOR_END__ = .;
|
||||
} > m_text
|
||||
|
||||
.preinit_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||
KEEP (*(.preinit_array*))
|
||||
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||
} > m_text
|
||||
|
||||
.init_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__init_array_start = .);
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array*))
|
||||
PROVIDE_HIDDEN (__init_array_end = .);
|
||||
} > m_text
|
||||
|
||||
.fini_array :
|
||||
{
|
||||
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
KEEP (*(.fini_array*))
|
||||
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||
} > m_text
|
||||
|
||||
__etext = .; /* define a global symbol at end of code */
|
||||
__DATA_ROM = .; /* Symbol is used by startup for data initialization */
|
||||
|
||||
.data : AT(__DATA_ROM)
|
||||
{
|
||||
. = ALIGN(4);
|
||||
__DATA_RAM = .;
|
||||
__data_start__ = .; /* create a global symbol at data start */
|
||||
*(m_usb_dma_init_data)
|
||||
*(.data) /* .data sections */
|
||||
*(.data*) /* .data* sections */
|
||||
KEEP(*(.jcr*))
|
||||
. = ALIGN(4);
|
||||
__data_end__ = .; /* define a global symbol at data end */
|
||||
} > m_data
|
||||
|
||||
__NDATA_ROM = __DATA_ROM + (__data_end__ - __data_start__);
|
||||
.ncache.init : AT(__NDATA_ROM)
|
||||
{
|
||||
__noncachedata_start__ = .; /* create a global symbol at ncache data start */
|
||||
*(NonCacheable.init)
|
||||
. = ALIGN(4);
|
||||
__noncachedata_init_end__ = .; /* create a global symbol at initialized ncache data end */
|
||||
} > m_data
|
||||
. = __noncachedata_init_end__;
|
||||
.ncache :
|
||||
{
|
||||
*(NonCacheable)
|
||||
. = ALIGN(4);
|
||||
__noncachedata_end__ = .; /* define a global symbol at ncache data end */
|
||||
} > m_data
|
||||
|
||||
__DATA_END = __NDATA_ROM + (__noncachedata_init_end__ - __noncachedata_start__);
|
||||
text_end = ORIGIN(m_text) + LENGTH(m_text);
|
||||
ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data")
|
||||
|
||||
/* Uninitialized data section */
|
||||
.bss :
|
||||
{
|
||||
/* This is used by the startup in order to initialize the .bss section */
|
||||
. = ALIGN(4);
|
||||
__START_BSS = .;
|
||||
__bss_start__ = .;
|
||||
*(m_usb_dma_noninit_data)
|
||||
*(.bss)
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
__bss_end__ = .;
|
||||
__END_BSS = .;
|
||||
} > m_data
|
||||
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
stack_start = .;
|
||||
. += STACK_SIZE;
|
||||
stack_end = .;
|
||||
__StackTop = .;
|
||||
heap_start = .;
|
||||
} > m_data
|
||||
|
||||
PROVIDE(heap_end = ORIGIN(m_data) + LENGTH(m_data));
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
||||
@@ -241,9 +241,9 @@ SECTIONS
|
||||
stack_end = .;
|
||||
__StackTop = .;
|
||||
heap_start = .;
|
||||
} > m_data
|
||||
} > m_data2
|
||||
|
||||
PROVIDE(heap_end = ORIGIN(m_data) + LENGTH(m_data));
|
||||
PROVIDE(heap_end = ORIGIN(m_data2) + LENGTH(m_data2));
|
||||
|
||||
.ARM.attributes 0 : { *(.ARM.attributes) }
|
||||
}
|
||||
|
||||
@@ -11,6 +11,50 @@ 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
|
||||
|
||||
if BSP_USING_ADC
|
||||
source "$BSP_DIR/third_party_driver/adc/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_SPI
|
||||
bool "Using SPI device"
|
||||
default y
|
||||
select RESOURCES_SPI
|
||||
|
||||
if BSP_USING_SPI
|
||||
source "$BSP_DIR/third_party_driver/spi/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_RTC
|
||||
bool "Using RTC device"
|
||||
default n
|
||||
select RESOURCES_RTC
|
||||
if BSP_USING_RTC
|
||||
source "$BSP_DIR/third_party_driver/rtc/Kconfig"
|
||||
endif
|
||||
|
||||
menuconfig BSP_USING_SEMC
|
||||
bool "Using SEMC device"
|
||||
default n
|
||||
|
||||
@@ -8,10 +8,27 @@ 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
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_RTC),y)
|
||||
SRC_DIR += rtc
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(CONFIG_BSP_USING_SDIO),y)
|
||||
SRC_DIR += sdio
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
config BSP_USING_ADC1
|
||||
bool "Enable ADC1"
|
||||
default y
|
||||
if BSP_USING_ADC1
|
||||
config ADC_BUS_NAME_1
|
||||
string "adc bus 1 name"
|
||||
default "adc1"
|
||||
config ADC_DRV_NAME_1
|
||||
string "adc bus 1 driver name"
|
||||
default "adc1_drv"
|
||||
config ADC_1_DEVICE_NAME_0
|
||||
string "adc bus 1 device name"
|
||||
default "adc1_dev"
|
||||
endif
|
||||
|
||||
config BSP_USING_ADC2
|
||||
bool "Enable ADC2"
|
||||
default y
|
||||
if BSP_USING_ADC2
|
||||
config ADC_BUS_NAME_2
|
||||
string "adc bus 2 name"
|
||||
default "adc2"
|
||||
config ADC_DRV_NAME_2
|
||||
string "adc bus 2 driver name"
|
||||
default "adc2_drv"
|
||||
config ADC_2_DEVICE_NAME_0
|
||||
string "adc bus 2 device name"
|
||||
default "adc2_dev"
|
||||
endif
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := fsl_adc.c connect_adc.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_adc.c
|
||||
* @brief Demo for ADC function
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.1.18
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "fsl_adc.h"
|
||||
#include "fsl_common.h"
|
||||
#include "dev_adc.h"
|
||||
#include "bus_adc.h"
|
||||
#include "connect_adc.h"
|
||||
|
||||
#define ADC1_BASE_ADDR ADC1
|
||||
#define ADC1_IRQ ADC1_IRQn
|
||||
#define ADC1_USER_CHANNEL 3U
|
||||
#define ADC1_CHANNEL_GROUP 0U
|
||||
|
||||
#define ADC2_BASE_ADDR ADC2
|
||||
#define ADC2_IRQ ADC2_IRQn
|
||||
#define ADC2_USER_CHANNEL 4U
|
||||
#define ADC2_CHANNEL_GROUP 0U
|
||||
|
||||
#define adc_print KPrintf
|
||||
|
||||
volatile bool adc1_flag;
|
||||
volatile uint32_t adc1_val;
|
||||
volatile uint32_t adc1_irq_cnt;
|
||||
volatile bool adc2_flag;
|
||||
volatile uint32_t adc2_val;
|
||||
volatile uint32_t adc2_irq_cnt;
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void ADC1_IRQHandler(int vector, void *param)
|
||||
{
|
||||
adc1_flag = true;
|
||||
/* Read conversion result to clear the conversion completed flag. */
|
||||
adc1_val = ADC_GetChannelConversionValue(ADC1_BASE_ADDR, ADC1_CHANNEL_GROUP);
|
||||
adc1_irq_cnt++;
|
||||
/* 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, ADC1_IRQHandler, NONE);
|
||||
|
||||
void ADC2_IRQHandler(int vector, void *param)
|
||||
{
|
||||
adc2_flag = true;
|
||||
/* Read conversion result to clear the conversion completed flag. */
|
||||
adc2_val = ADC_GetChannelConversionValue(ADC2_BASE_ADDR, ADC2_CHANNEL_GROUP);
|
||||
adc2_irq_cnt++;
|
||||
/* 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(ADC2_IRQn, ADC2_IRQHandler, NONE);
|
||||
|
||||
uint32 Imrt1052AdcOpen(void *dev)
|
||||
{
|
||||
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
|
||||
adc_config_t adc_cfg;
|
||||
|
||||
#ifdef BSP_USING_ADC1
|
||||
if (0 == strncmp(adc_dev->haldev.dev_name, ADC_1_DEVICE_NAME_0, NAME_NUM_MAX)) {
|
||||
EnableIRQ(ADC1_IRQn);
|
||||
ADC_GetDefaultConfig(&adc_cfg);
|
||||
ADC_Init(ADC1, &adc_cfg);
|
||||
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
|
||||
ADC_EnableHardwareTrigger(ADC1, false);
|
||||
#endif
|
||||
/* Do auto hardware calibration. */
|
||||
if (kStatus_Success == ADC_DoAutoCalibration(ADC1))
|
||||
{
|
||||
adc_print("ADC_DoAntoCalibration() Done.\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
adc_print("ADC_DoAutoCalibration() Failed.\r\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_ADC2
|
||||
if (0 == strncmp(adc_dev->haldev.dev_name, ADC_2_DEVICE_NAME_0, NAME_NUM_MAX)) {
|
||||
EnableIRQ(ADC2_IRQn);
|
||||
ADC_GetDefaultConfig(&adc_cfg);
|
||||
ADC_Init(ADC2, &adc_cfg);
|
||||
#if !(defined(FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE) && FSL_FEATURE_ADC_SUPPORT_HARDWARE_TRIGGER_REMOVE)
|
||||
ADC_EnableHardwareTrigger(ADC2, false);
|
||||
#endif
|
||||
/* Do auto hardware calibration. */
|
||||
if (kStatus_Success == ADC_DoAutoCalibration(ADC2))
|
||||
{
|
||||
adc_print("ADC_DoAntoCalibration() Done.\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
adc_print("ADC_DoAutoCalibration() Failed.\r\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
uint32 Imrt1052AdcClose(void *dev)
|
||||
{
|
||||
return EOK;
|
||||
}
|
||||
|
||||
uint32 Imrt1052AdcRead(void *dev, struct BusBlockReadParam *read_param)
|
||||
{
|
||||
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)dev;
|
||||
adc_channel_config_t ch_cfg;
|
||||
|
||||
#ifdef BSP_USING_ADC1
|
||||
if (0 == strncmp(adc_dev->haldev.dev_name, ADC_1_DEVICE_NAME_0, NAME_NUM_MAX)) {
|
||||
/* Configure the user channel and interrupt. */
|
||||
ch_cfg.channelNumber = ADC1_USER_CHANNEL;
|
||||
ch_cfg.enableInterruptOnConversionCompleted = true;
|
||||
adc1_irq_cnt = 0U; /* Clear the interrupt counter. */
|
||||
adc1_flag = false;
|
||||
ADC_SetChannelConfig(ADC1, ADC1_CHANNEL_GROUP, &ch_cfg);
|
||||
while (adc1_flag == false);
|
||||
|
||||
adc_print("ADC Value: %d\r\n", adc1_val);
|
||||
adc_print("ADC Interrupt Counter: %d\r\n", adc1_irq_cnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_ADC2
|
||||
if (0 == strncmp(adc_dev->haldev.dev_name, ADC_2_DEVICE_NAME_0, NAME_NUM_MAX)) {
|
||||
/* Configure the user channel and interrupt. */
|
||||
ch_cfg.channelNumber = ADC2_USER_CHANNEL;
|
||||
ch_cfg.enableInterruptOnConversionCompleted = true;
|
||||
adc2_irq_cnt = 0U; /* Clear the interrupt counter. */
|
||||
adc2_flag = false;
|
||||
ADC_SetChannelConfig(ADC2, ADC2_CHANNEL_GROUP, &ch_cfg);
|
||||
while (adc2_flag == false);
|
||||
|
||||
adc_print("ADC Value: %d\r\n", adc2_val);
|
||||
adc_print("ADC Interrupt Counter: %d\r\n", adc2_irq_cnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
return adc1_val;
|
||||
}
|
||||
|
||||
static uint32 Imrt1052AdcDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(configure_info);
|
||||
|
||||
x_err_t ret = EOK;
|
||||
uint8 adc_channel;
|
||||
|
||||
struct AdcDriver *adc_drv = (struct AdcDriver *)drv;
|
||||
struct AdcHardwareDevice *adc_dev = (struct AdcHardwareDevice *)adc_drv->driver.owner_bus->owner_haldev;
|
||||
struct Imrt1052HwAdc *adc_cfg = (struct Imrt1052HwAdc *)adc_dev->haldev.private_data;
|
||||
|
||||
switch (configure_info->configure_cmd)
|
||||
{
|
||||
case OPE_CFG:
|
||||
adc_cfg->adc_channel = *(uint8 *)configure_info->private_data;
|
||||
if (adc_cfg->adc_channel > 18) {
|
||||
KPrintf("Imrt1052AdcDrvConfigure set adc channel(0-18) %u error!", adc_cfg->adc_channel);
|
||||
adc_cfg->adc_channel = 0;
|
||||
ret = ERROR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct AdcDevDone dev_done =
|
||||
{
|
||||
Imrt1052AdcOpen,
|
||||
Imrt1052AdcClose,
|
||||
NONE,
|
||||
Imrt1052AdcRead,
|
||||
};
|
||||
|
||||
int Imrt1052HwAdcInit(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
#ifdef BSP_USING_ADC1
|
||||
static struct AdcBus adc1_bus;
|
||||
static struct AdcDriver adc1_drv;
|
||||
static struct AdcHardwareDevice adc1_dev;
|
||||
static struct Imrt1052HwAdc adc1_cfg;
|
||||
|
||||
adc1_drv.configure = Imrt1052AdcDrvConfigure;
|
||||
|
||||
ret = AdcBusInit(&adc1_bus, ADC_BUS_NAME_1);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 bus init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = AdcDriverInit(&adc1_drv, ADC_DRV_NAME_1);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 driver init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
ret = AdcDriverAttachToBus(ADC_DRV_NAME_1, ADC_BUS_NAME_1);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 driver attach error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
adc1_dev.adc_dev_done = &dev_done;
|
||||
|
||||
ret = AdcDeviceRegister(&adc1_dev, (void *)&adc1_cfg, ADC_1_DEVICE_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = AdcDeviceAttachToBus(ADC_1_DEVICE_NAME_0, ADC_BUS_NAME_1);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_ADC2
|
||||
static struct AdcBus adc2_bus;
|
||||
static struct AdcDriver adc2_drv;
|
||||
static struct AdcHardwareDevice adc2_dev;
|
||||
static struct Imrt1052HwAdc adc2_cfg;
|
||||
|
||||
adc2_drv.configure = Imrt1052AdcDrvConfigure;
|
||||
|
||||
ret = AdcBusInit(&adc2_bus, ADC_BUS_NAME_2);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC2 bus init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = AdcDriverInit(&adc2_drv, ADC_DRV_NAME_2);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC2 driver init error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
ret = AdcDriverAttachToBus(ADC_DRV_NAME_2, ADC_BUS_NAME_2);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC2 driver attach error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
adc2_dev.adc_dev_done = &dev_done;
|
||||
|
||||
ret = AdcDeviceRegister(&adc2_dev, (void *)&adc2_cfg, ADC_2_DEVICE_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC2 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = AdcDeviceAttachToBus(ADC_2_DEVICE_NAME_0, ADC_BUS_NAME_2);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC2 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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_ */
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -749,6 +749,115 @@ BOARD_InitPins:
|
||||
* Description : Configures pin routing and optionally pin electrical features.
|
||||
*
|
||||
* END ****************************************************************************************************************/
|
||||
|
||||
void BOARD_InitSPIPins ( void )
|
||||
{
|
||||
IOMUXC_SetPinMux (
|
||||
IOMUXC_GPIO_AD_B1_15_LPSPI3_SCK, /* GPIO_AD_B0_00 is configured as LPSPI3_SCK */
|
||||
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux (
|
||||
IOMUXC_GPIO_AD_B1_14_LPSPI3_SDO, /* GPIO_AD_B0_01 is configured as LPSPI3_SDO */
|
||||
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux (
|
||||
IOMUXC_GPIO_AD_B1_13_LPSPI3_SDI, /* GPIO_AD_B0_02 is configured as LPSPI3_SDI */
|
||||
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux (
|
||||
IOMUXC_GPIO_AD_B1_12_LPSPI3_PCS0, /* GPIO_AD_B0_03 is configured as LPSPI3_PCS0 */
|
||||
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux (
|
||||
IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK, /* GPIO_SD_B0_00 is configured as LPSPI1_SCK */
|
||||
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux (
|
||||
IOMUXC_GPIO_SD_B0_01_LPSPI1_PCS0, /* GPIO_SD_B0_01 is configured as LPSPI1_PCS0 */
|
||||
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux (
|
||||
IOMUXC_GPIO_SD_B0_02_LPSPI1_SDO, /* GPIO_SD_B0_02 is configured as LPSPI1_SDO */
|
||||
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||
IOMUXC_SetPinMux (
|
||||
IOMUXC_GPIO_SD_B0_03_LPSPI1_SDI, /* GPIO_SD_B0_03 is configured as LPSPI1_SDI */
|
||||
0U ); /* Software Input On Field: Input Path is determined by functionality */
|
||||
|
||||
IOMUXC_SetPinConfig (
|
||||
IOMUXC_GPIO_SD_B0_00_LPSPI1_SCK, /* GPIO_AD_B0_00 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_B1_14_LPSPI3_SDO, /* GPIO_AD_B0_01 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_B1_13_LPSPI3_SDI, /* GPIO_AD_B0_02 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_B1_12_LPSPI3_PCS0, /* GPIO_AD_B0_03 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_B0_00_LPSPI1_SCK, /* GPIO_SD_B0_00 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_B0_01_LPSPI1_PCS0, /* GPIO_SD_B0_01 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_B0_02_LPSPI1_SDO, /* GPIO_SD_B0_02 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_B0_03_LPSPI1_SDI, /* GPIO_SD_B0_03 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 */
|
||||
}
|
||||
void BOARD_InitPins(void) {
|
||||
CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */
|
||||
|
||||
@@ -964,6 +1073,36 @@ void BOARD_InitPins(void) {
|
||||
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
|
||||
**********************************************************************************************************************/
|
||||
|
||||
@@ -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
|
||||
******************************************************************************/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
@@ -1,3 +1,3 @@
|
||||
SRC_FILES := fsl_gpio.c
|
||||
SRC_FILES := connect_gpio.c fsl_gpio.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := connect_i2c.c connect_i2c_eeprom.c hardware_i2c.c fsl_lpi2c.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* 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 ok1052-c i2c function and register to bus framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: connect_i2c.c
|
||||
Description: support ok1052-c 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: 2022-03-01
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support ok1052-c i2c bit configure, write and read
|
||||
2. support ok1052-c i2c bus device and driver register
|
||||
*************************************************/
|
||||
|
||||
#include <board.h>
|
||||
#include "bus_serial.h"
|
||||
#include "connect_i2c.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
|
||||
#ifndef BSP_USING_I2C1
|
||||
#define BSP_USING_I2C1
|
||||
#endif
|
||||
|
||||
static uint32 I2cWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
|
||||
{
|
||||
status_t ret;
|
||||
Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data;
|
||||
ret = I2cHardwareWrite(param->base, param->slave_addr, param->sub_addr, msg->buf, msg->len);
|
||||
if(kStatus_Success == ret)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32 I2cReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg)
|
||||
{
|
||||
status_t ret;
|
||||
Stm32I2cType *param = (Stm32I2cType *)i2c_dev->haldev.private_data;
|
||||
ret = I2cHardwareRead(param->base, i2c_dev->i2c_dev_addr, param->sub_addr, msg->buf, msg->len);
|
||||
if(kStatus_Success == ret)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
i2c_print("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) {
|
||||
i2c_print("BoardI2cBusInit 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) {
|
||||
i2c_print("BoardI2cBusInit 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) {
|
||||
i2c_print("BoardI2cBusInit 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) {
|
||||
i2c_print("BoardI2cDevBend 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) {
|
||||
i2c_print("BoardI2cDevBend 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) {
|
||||
i2c_print("board_i2c_Init error ret %u\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = BoardI2cDevBend();
|
||||
if (EOK != ret) {
|
||||
i2c_print("board_i2c_Init error ret %u\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_i2c_eeprom.h
|
||||
* @brief ok1052-c eeprom relative codes
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include "connect_i2c.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
#include "pin_mux.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define I2C_EEPROM_BASE LPI2C1
|
||||
#define I2C_EEPROM_ADDR (0xA0 >> 1)
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void I2cEEpromTestWrite(void)
|
||||
{
|
||||
uint8_t dat[8] = {0};
|
||||
|
||||
if(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||
{
|
||||
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] ++;
|
||||
}
|
||||
|
||||
if(I2cHardwareWrite(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||
{
|
||||
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(I2cHardwareRead(I2C_EEPROM_BASE, I2C_EEPROM_ADDR, 0, dat, 8) == kStatus_Success)
|
||||
{
|
||||
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 I2cEEpromTest(void)
|
||||
{
|
||||
Stm32HwI2cInit();
|
||||
BOARD_InitI2C1Pins();
|
||||
I2cHardwareInit();
|
||||
I2cEEpromTestWrite();
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(0),
|
||||
eeprom, I2cEEpromTest, test i2c eeprom);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* 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 hardware_i2c.c
|
||||
* @brief ok1052-c i2c relative codes
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
|
||||
#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
|
||||
|
||||
void I2cHardwareInit(void)
|
||||
{
|
||||
lpi2c_master_config_t masterConfig = {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);
|
||||
}
|
||||
|
||||
status_t I2cHardwareWrite(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuff, uint16_t dataLen)
|
||||
{
|
||||
lpi2c_master_transfer_t xfer;
|
||||
xfer.slaveAddress = slave_addr;
|
||||
xfer.direction = kLPI2C_Write;
|
||||
xfer.subaddress = subAdd;
|
||||
xfer.subaddressSize = 0x01;
|
||||
xfer.data = dataBuff;
|
||||
xfer.dataSize = dataLen;
|
||||
xfer.flags = kLPI2C_TransferDefaultFlag;
|
||||
return LPI2C_MasterTransferBlocking(base, &xfer);
|
||||
}
|
||||
|
||||
status_t I2cHardwareRead(LPI2C_Type* base, uint16_t slave_addr, uint32_t subAdd, uint8_t* dataBuffer, uint16_t dataLen)
|
||||
{
|
||||
lpi2c_master_transfer_t masterXfer = {0};
|
||||
masterXfer.slaveAddress = slave_addr;
|
||||
masterXfer.direction = kLPI2C_Read;
|
||||
masterXfer.subaddress = subAdd;
|
||||
masterXfer.subaddressSize = 0x01;
|
||||
masterXfer.data = dataBuffer;
|
||||
masterXfer.dataSize = dataLen;
|
||||
masterXfer.flags = kLPI2C_TransferDefaultFlag;
|
||||
return LPI2C_MasterTransferBlocking(base, &masterXfer);
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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_adc.h
|
||||
* @brief define stm32f407-st-discovery adc function and struct
|
||||
* @version 1.1
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-12-28
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_ADC_H
|
||||
#define CONNECT_ADC_H
|
||||
|
||||
#include <device.h>
|
||||
|
||||
struct Imrt1052HwAdc
|
||||
{
|
||||
void *ADCx;
|
||||
uint8 adc_channel;
|
||||
};
|
||||
|
||||
int Imrt1052HwAdcInit(void);
|
||||
|
||||
#endif
|
||||
@@ -1,26 +1,5 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file connect_ethernet.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.0.0
|
||||
* @date 31-October-2011
|
||||
* @brief STM32F4x7 Ethernet hardware configuration.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
/*
|
||||
* 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:
|
||||
@@ -39,37 +18,22 @@
|
||||
* @date 2021-12-7
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __ETH_BSP_H
|
||||
#define __ETH_BSP_H
|
||||
#ifndef __CONNECT_ETHERNET_H_
|
||||
#define __CONNECT_ETHERNET_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
|
||||
#ifndef sourceClock
|
||||
#define sourceClock CLOCK_GetFreq(kCLOCK_CoreSysClk)
|
||||
#endif
|
||||
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
|
||||
void enet_delay(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F4x7_ETH_BSP_H */
|
||||
#endif
|
||||
|
||||
|
||||
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_gpio.h
|
||||
* @brief define ok1052-c gpio function and struct
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
#ifndef __CONNECT_GPIO_H_
|
||||
#define __CONNECT_GPIO_H_
|
||||
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int Stm32HwGpioInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
|
||||
typedef struct Stm32I2c
|
||||
{
|
||||
LPI2C_Type* base;
|
||||
uint16_t slave_addr;
|
||||
uint32_t sub_addr;
|
||||
}Stm32I2cType;
|
||||
|
||||
#define i2c_print KPrintf
|
||||
|
||||
int Stm32HwI2cInit(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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_rtc.h
|
||||
* @brief define ok1052-c rtc function and structure
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
#ifndef __CONNECT_RTC_H_
|
||||
#define __CONNECT_RTC_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
#include "fsl_lpi2c.h"
|
||||
|
||||
#define I2C_RTC_BASE LPI2C1
|
||||
#define I2C_RTC_ADDR 0x32
|
||||
|
||||
void RtcI2cInit(void);
|
||||
status_t RtcI2cWrite(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size);
|
||||
uint32_t RtcI2cRead(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size);
|
||||
|
||||
int Imrt1052HwRtcInit(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2020 AIIT XUOS Lab
|
||||
* XiUOS is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_spi.h
|
||||
* @brief define stm32f407-st-discovery-board spi function and struct
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2021-04-25
|
||||
*/
|
||||
|
||||
#ifndef CONNECT_SPI_H
|
||||
#define CONNECT_SPI_H
|
||||
|
||||
#include <device.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SPI_USING_RX_DMA_FLAG (1<<0)
|
||||
#define SPI_USING_TX_DMA_FLAG (1<<1)
|
||||
|
||||
struct Stm32HwSpi
|
||||
{
|
||||
LPSPI_Type *base;
|
||||
uint8_t irq;
|
||||
uint8_t mode;
|
||||
void *priv_data;
|
||||
};
|
||||
|
||||
struct Stm32Spi
|
||||
{
|
||||
LPSPI_Type *instance;
|
||||
char *bus_name;
|
||||
struct SpiBus spi_bus;
|
||||
};
|
||||
|
||||
int Imrt1052HwSpiInit(void);
|
||||
x_err_t HwSpiDeviceAttach(const char *bus_name, const char *device_name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#define _FSL_DEBUGCONSOLE_H_
|
||||
|
||||
#include "fsl_common.h"
|
||||
//#include "serial_manager.h"
|
||||
#include "serial_manager.h"
|
||||
|
||||
/*!
|
||||
* @addtogroup debugconsole
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
+548
@@ -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__ */
|
||||
+55
@@ -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__ */
|
||||
+76
@@ -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__ */
|
||||
@@ -0,0 +1,11 @@
|
||||
if BSP_USING_RTC
|
||||
config RTC_BUS_NAME
|
||||
string "rtc bus name"
|
||||
default "rtc"
|
||||
config RTC_DRV_NAME
|
||||
string "rtc bus driver name"
|
||||
default "rtc_drv"
|
||||
config RTC_DEVICE_NAME
|
||||
string "rtc bus device name"
|
||||
default "rtc_dev"
|
||||
endif
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := hardware_rtc.c connect_rtc.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_rtc.c
|
||||
* @brief ok1052-c rtc function and structure
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: connect_rtc.c
|
||||
Description: support ok1052-c rtc configure and spi bus register function
|
||||
|
||||
History:
|
||||
1. Date: 2022-03-01
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. change command for XUOS
|
||||
*************************************************/
|
||||
|
||||
#include "board.h"
|
||||
#include "bus_rtc.h"
|
||||
#include "pin_mux.h"
|
||||
#include "dev_rtc.h"
|
||||
#include "connect_rtc.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define rtc_print KPrintf
|
||||
|
||||
#define MAX_TIME_STR_SIZE 50
|
||||
|
||||
///////////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 RtcInit(void)
|
||||
{
|
||||
uint8_t flag = 0;
|
||||
uint8_t data = 0;
|
||||
uint8_t ctrl[2];
|
||||
int need_clear = 0, err = 0;
|
||||
err = RtcI2cRead(I2C_RTC_BASE, RX8010_FLAG, &flag, 1);
|
||||
flag &= ~(RX8010_FLAG_VLF);
|
||||
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_FLAG, &flag, 1);
|
||||
/* Initialize reserved registers as specified in datasheet */
|
||||
data = 0xD8;
|
||||
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV17, &data, 1);
|
||||
data = 0x00;
|
||||
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV30, &data, 1);
|
||||
data = 0x08;
|
||||
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_RESV31, &data, 1);
|
||||
data = 0x00;
|
||||
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_IRQ, &data, 1);
|
||||
err = RtcI2cRead(I2C_RTC_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 = RtcI2cWrite(I2C_RTC_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 RtcGetBcdDate(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 RtcSetTime(uint8_t* asc_date)
|
||||
{
|
||||
uint8_t bcd_date[6];
|
||||
int ret, err;
|
||||
|
||||
if(RtcGetBcdDate(asc_date, bcd_date))
|
||||
{
|
||||
rtc_print("\r\n Date format error! \r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = RtcI2cWrite(I2C_RTC_BASE, RX8010_SEC, bcd_date, 3);
|
||||
err |= RtcI2cWrite(I2C_RTC_BASE, RX8010_MDAY, &bcd_date[3], 3);
|
||||
return err;
|
||||
}
|
||||
|
||||
// get rx8010 time
|
||||
int RtcGetTime(struct tm *ct)
|
||||
{
|
||||
uint8_t rtc_data[7];
|
||||
uint8_t time_str[7];
|
||||
uint8_t flag_reg;
|
||||
int err;
|
||||
err = RtcI2cRead(I2C_RTC_BASE, RX8010_FLAG, &flag_reg, 1);
|
||||
|
||||
if(flag_reg & RX8010_FLAG_VLF)
|
||||
{
|
||||
rtc_print("\r\n Frequency stop was detected\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = RtcI2cRead(I2C_RTC_BASE, RX8010_SEC, rtc_data, 7);
|
||||
time_str[0] = bcd2bin(rtc_data[RX8010_SEC - RX8010_SEC] & 0x7f);
|
||||
time_str[1] = bcd2bin(rtc_data[RX8010_MIN - RX8010_SEC] & 0x7f);
|
||||
time_str[2] = bcd2bin(rtc_data[RX8010_HOUR - RX8010_SEC] & 0x3f);
|
||||
time_str[4] = bcd2bin(rtc_data[RX8010_MDAY - RX8010_SEC] & 0x3f);
|
||||
time_str[5] = bcd2bin(rtc_data[RX8010_MONTH - RX8010_SEC] & 0x1f);
|
||||
time_str[6] = bcd2bin(rtc_data[RX8010_YEAR - RX8010_SEC]);
|
||||
time_str[3] = rtc_data[RX8010_WDAY - RX8010_SEC] & 0x7f;
|
||||
|
||||
rtc_print("RX8010 Time: 20%d%d-%d%d-%d%d %d%d:%d%d:%d%d\r\n",
|
||||
time_str[6]/10, time_str[6]%10, time_str[5]/10, time_str[5]%10, time_str[4]/10, time_str[4]%10,
|
||||
time_str[2]/10, time_str[2]%10, time_str[1]/10, time_str[1]%10, time_str[0]/10, time_str[0]%10);
|
||||
|
||||
ct->tm_year = time_str[6];
|
||||
ct->tm_mon = time_str[5];
|
||||
ct->tm_mday = time_str[4];
|
||||
ct->tm_wday = time_str[3];
|
||||
ct->tm_hour = time_str[2];
|
||||
ct->tm_min = time_str[1];
|
||||
ct->tm_sec = time_str[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GetWeekDay(int year, int month, int day)
|
||||
{
|
||||
if(month==1||month==2)
|
||||
{
|
||||
year -=1;
|
||||
month +=12;
|
||||
}
|
||||
|
||||
return (day+1+2*month+3*(month+1)/5+year+(year/4)-year/100+year/400)%7+1;
|
||||
}
|
||||
|
||||
static uint32 RtcConfigure(void* drv, struct BusConfigureInfo* configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
struct RtcDriver* rtc_drv = (struct RtcDriver*)drv;
|
||||
struct RtcDrvConfigureParam* drv_param = (struct RtcDrvConfigureParam*)configure_info->private_data;
|
||||
int cmd = drv_param->rtc_operation_cmd;
|
||||
time_t* time = drv_param->time;
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case OPER_RTC_GET_TIME:
|
||||
{
|
||||
struct tm ct;
|
||||
RtcGetTime(&ct);
|
||||
*time = mktime(&ct);
|
||||
}
|
||||
break;
|
||||
|
||||
case OPER_RTC_SET_TIME:
|
||||
{
|
||||
char time_str[MAX_TIME_STR_SIZE] = {0};
|
||||
struct tm *ct = localtime(time);
|
||||
strftime(time_str, MAX_TIME_STR_SIZE, "%y-%m-%d %H:%M:%S", ct);
|
||||
RtcSetTime(time_str);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
int RtcConfiguration(void)
|
||||
{
|
||||
BOARD_InitI2C1Pins();
|
||||
RtcI2cInit();
|
||||
RtcInit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*manage the rtc device operations*/
|
||||
static const struct RtcDevDone dev_done =
|
||||
{
|
||||
.open = NONE,
|
||||
.close = NONE,
|
||||
.write = NONE,
|
||||
.read = NONE,
|
||||
};
|
||||
|
||||
static int BoardRtcBusInit(struct RtcBus* rtc_bus, struct RtcDriver* rtc_driver)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
/*Init the rtc bus */
|
||||
ret = RtcBusInit(rtc_bus, RTC_BUS_NAME);
|
||||
|
||||
if(EOK != ret)
|
||||
{
|
||||
KPrintf("hw_rtc_init RtcBusInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Init the rtc driver*/
|
||||
ret = RtcDriverInit(rtc_driver, RTC_DRV_NAME);
|
||||
|
||||
if(EOK != ret)
|
||||
{
|
||||
KPrintf("hw_rtc_init RtcDriverInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Attach the rtc driver to the rtc bus*/
|
||||
ret = RtcDriverAttachToBus(RTC_DRV_NAME, RTC_BUS_NAME);
|
||||
|
||||
if(EOK != ret)
|
||||
{
|
||||
KPrintf("hw_rtc_init RtcDriverAttachToBus error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*Attach the rtc device to the rtc bus*/
|
||||
static int BoardRtcDevBend(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
static struct RtcHardwareDevice rtc_device;
|
||||
memset(&rtc_device, 0, sizeof(struct RtcHardwareDevice));
|
||||
rtc_device.dev_done = &(dev_done);
|
||||
ret = RtcDeviceRegister(&rtc_device, NONE, RTC_DEVICE_NAME);
|
||||
|
||||
if(EOK != ret)
|
||||
{
|
||||
KPrintf("hw_rtc_init RtcDeviceInit device %s error %d\n", RTC_DEVICE_NAME, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = RtcDeviceAttachToBus(RTC_DEVICE_NAME, RTC_BUS_NAME);
|
||||
|
||||
if(EOK != ret)
|
||||
{
|
||||
KPrintf("hw_rtc_init RtcDeviceAttachToBus device %s error %d\n", RTC_DEVICE_NAME, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Imrt1052HwRtcInit(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
static struct RtcBus rtc_bus;
|
||||
memset(&rtc_bus, 0, sizeof(struct RtcBus));
|
||||
static struct RtcDriver rtc_driver;
|
||||
memset(&rtc_driver, 0, sizeof(struct RtcDriver));
|
||||
rtc_driver.configure = &(RtcConfigure);
|
||||
ret = BoardRtcBusInit(&rtc_bus, &rtc_driver);
|
||||
|
||||
if(EOK != ret)
|
||||
{
|
||||
KPrintf("hw_rtc_init error ret %u\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = BoardRtcDevBend();
|
||||
|
||||
if(EOK != ret)
|
||||
{
|
||||
KPrintf("hw_rtc_init error ret %u\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
RtcConfiguration();
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RtcTestRx8010(int argc, char* argv[])
|
||||
{
|
||||
if(argc == 2)
|
||||
{
|
||||
if(RtcSetTime(argv[1]) == 0)
|
||||
{
|
||||
RtcGetTime(NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RtcGetTime(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)| SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN)| SHELL_CMD_PARAM_NUM(3),
|
||||
rtc, RtcTestRx8010, i2c rtc "date time");
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 hardware_rtc.c
|
||||
* @brief I2C RTC drivers
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022.1.18
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: hardware_rtc.c
|
||||
Description: support ok1052-c rtc driver I2C function
|
||||
|
||||
History:
|
||||
1. Date: 2022-01-18
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support ok1052-c rtc
|
||||
*************************************************/
|
||||
|
||||
#include "connect_rtc.h"
|
||||
#include "connect_i2c.h"
|
||||
|
||||
void RtcI2cInit()
|
||||
{
|
||||
I2cHardwareInit();
|
||||
}
|
||||
|
||||
status_t RtcI2cWrite(LPI2C_Type *base, uint32_t sub_addr, uint8_t *buf, uint16_t size)
|
||||
{
|
||||
return I2cHardwareWrite(base, I2C_RTC_ADDR, sub_addr, buf, size);
|
||||
}
|
||||
|
||||
uint32_t RtcI2cRead(LPI2C_Type *base,uint32_t sub_addr,uint8_t* buf, uint16_t size)
|
||||
{
|
||||
return I2cHardwareRead(base, I2C_RTC_ADDR, sub_addr, buf, size);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
config BSP_USING_SPI1
|
||||
bool "Enable SPI1"
|
||||
default y
|
||||
if BSP_USING_SPI1
|
||||
config SPI_1_BUS_NAME
|
||||
string "spi1 bus name"
|
||||
default "spi1"
|
||||
config SPI_1_DRV_NAME
|
||||
string "spi bus 1 driver name"
|
||||
default "spi1_drv"
|
||||
config SPI_1_DEV_NAME_0
|
||||
string "spi bus 1 device name"
|
||||
default "spi1_dev"
|
||||
endif
|
||||
|
||||
config BSP_USING_SPI2
|
||||
bool "Enable SPI2"
|
||||
default y
|
||||
if BSP_USING_SPI2
|
||||
config SPI_2_BUS_NAME
|
||||
string "spi2 bus name"
|
||||
default "spi2"
|
||||
config SPI_2_DRV_NAME
|
||||
string "spi bus 2 driver name"
|
||||
default "spi2_drv"
|
||||
config SPI_2_DEV_NAME_0
|
||||
string "spi bus 2 device name"
|
||||
default "spi2_dev"
|
||||
endif
|
||||
|
||||
config BSP_USING_SPI3
|
||||
bool "Enable SPI3"
|
||||
default y
|
||||
if BSP_USING_SPI3
|
||||
config SPI_3_BUS_NAME
|
||||
string "spi3 bus name"
|
||||
default "spi3"
|
||||
config SPI_3_DRV_NAME
|
||||
string "spi bus 3 driver name"
|
||||
default "spi3_drv"
|
||||
config SPI_3_DEV_NAME_0
|
||||
string "spi bus 3 device name"
|
||||
default "spi3_dev"
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_FILES := fsl_lpspi.c connect_spi.c connect_flash_spi.c
|
||||
|
||||
include $(KERNEL_ROOT)/compiler.mk
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 ok1052-c-board spi flash function and register to bus framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: connect_flash_spi.c
|
||||
Description: support ok1052-c-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: 2022-03-01
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. for ok1052-c compilation
|
||||
*************************************************/
|
||||
|
||||
#include "flash_spi.h"
|
||||
|
||||
int FlashW25qxxSpiDeviceInit(void)
|
||||
{
|
||||
#ifdef BSP_USING_SPI1
|
||||
|
||||
#endif
|
||||
return EOK;
|
||||
}
|
||||
@@ -0,0 +1,959 @@
|
||||
/*
|
||||
* Copyright (c) 2020 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018-11-5 SummerGift first version
|
||||
* 2018-12-11 greedyhao Porting for stm32f7xx
|
||||
* 2019-01-03 zylx modify DMA initialization and spixfer function
|
||||
* 2020-01-15 whj4674672 Porting for stm32h7xx
|
||||
* 2020-06-18 thread-liu Porting for stm32mp1xx
|
||||
* 2020-10-14 Dozingfiretruck Porting for stm32wbxx
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file connect_spi.c
|
||||
* @brief support ok1052-c spi function and register to bus framework
|
||||
* @version 1.0
|
||||
* @author AIIT XUOS Lab
|
||||
* @date 2022-03-01
|
||||
*/
|
||||
|
||||
/*************************************************
|
||||
File name: connect_spi.c
|
||||
Description: support ok1052-c spi configure and spi bus register function
|
||||
Others: take RT-Thread v4.0.2/bsp/stm32/libraries/HAL_Drivers/drv_spi.c for references
|
||||
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
||||
History:
|
||||
1. Date: 2022-03-01
|
||||
Author: AIIT XUOS Lab
|
||||
Modification:
|
||||
1. support ok1052-c spi configure, write and read
|
||||
2. support ok1052-c spi bus device and driver register
|
||||
3. add ok1052-c spi test letter command
|
||||
*************************************************/
|
||||
|
||||
#include "board.h"
|
||||
#include "connect_spi.h"
|
||||
#include "fsl_lpspi.h"
|
||||
#include "pin_mux.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Definitions
|
||||
******************************************************************************/
|
||||
|
||||
#define SPI_PCS_FOR_INIT (kLPSPI_Pcs0)
|
||||
|
||||
/* Select USB1 PLL PFD0 (720 MHz) as lpspi clock source */
|
||||
#define SPI_CLOCK_SOURCE_SELECT (1U)
|
||||
|
||||
/* Clock divider for master lpspi clock source */
|
||||
#define SPI_CLOCK_SOURCE_DIVIDER (7U)
|
||||
|
||||
#define SPI_CLOCK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (SPI_CLOCK_SOURCE_DIVIDER + 1U))
|
||||
|
||||
#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__)
|
||||
|
||||
typedef struct __spi_transfer_t
|
||||
{
|
||||
uint32_t size;
|
||||
volatile uint32_t cnt;
|
||||
uint8_t water;
|
||||
uint8_t fifo;
|
||||
volatile bool completed;
|
||||
uint8_t buf[TRANSFER_SIZE];
|
||||
}spi_transfer_t;
|
||||
|
||||
#if defined(BSP_USING_SPI1)
|
||||
struct Stm32Spi spi1;
|
||||
spi_transfer_t spi1_rx_data;
|
||||
spi_transfer_t spi1_tx_data;
|
||||
#endif
|
||||
|
||||
#if defined(BSP_USING_SPI2)
|
||||
struct Stm32Spi spi2;
|
||||
spi_transfer_t spi2_rx_data;
|
||||
spi_transfer_t spi2_tx_data;
|
||||
#endif
|
||||
|
||||
#if defined(BSP_USING_SPI3)
|
||||
struct Stm32Spi spi3;
|
||||
spi_transfer_t spi3_rx_data;
|
||||
spi_transfer_t spi3_tx_data;
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
* Code
|
||||
******************************************************************************/
|
||||
|
||||
void LPSPI1_IRQHandler(int vector, void *param)
|
||||
{
|
||||
LPSPI_Type *spi_base = LPSPI1;
|
||||
int rx_size = spi1_rx_data.size < TRANSFER_SIZE ? spi1_rx_data.size : TRANSFER_SIZE;
|
||||
int tx_size = spi1_tx_data.size < TRANSFER_SIZE ? spi1_tx_data.size : TRANSFER_SIZE;
|
||||
|
||||
if (spi1_rx_data.cnt < rx_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 on the LPSPI state after reading out the FIFO.
|
||||
*/
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||
|
||||
while (LPSPI_GetRxFifoCount(spi_base))
|
||||
{
|
||||
/*Read out the data*/
|
||||
spi1_rx_data.buf[spi1_rx_data.cnt] = LPSPI_ReadData(spi_base);
|
||||
spi1_rx_data.cnt++;
|
||||
|
||||
if (spi1_rx_data.cnt == rx_size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-enable the interrupts only if rxCount indicates there is more data to receive,
|
||||
* else we may get a spurious interrupt.
|
||||
* */
|
||||
if (spi1_rx_data.cnt < rx_size)
|
||||
{
|
||||
/* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
|
||||
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||
}
|
||||
}
|
||||
|
||||
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
|
||||
if ((rx_size - spi1_rx_data.cnt) <= spi1_rx_data.water)
|
||||
{
|
||||
spi_base->FCR =
|
||||
(spi_base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
|
||||
LPSPI_FCR_RXWATER(((rx_size - spi1_rx_data.cnt) > 1) ? ((rx_size - spi1_rx_data.cnt) - 1U) : (0U));
|
||||
}
|
||||
|
||||
if (spi1_tx_data.cnt < tx_size)
|
||||
{
|
||||
while ((LPSPI_GetTxFifoCount(spi_base) < spi1_tx_data.fifo) &&
|
||||
(spi1_tx_data.cnt - spi1_rx_data.cnt < spi1_tx_data.fifo))
|
||||
{
|
||||
/*Write the word to TX register*/
|
||||
LPSPI_WriteData(spi_base, spi1_tx_data.buf[spi1_tx_data.cnt]);
|
||||
spi1_tx_data.cnt++;
|
||||
|
||||
if (spi1_tx_data.cnt == tx_size)
|
||||
{
|
||||
spi1_tx_data.completed = true;
|
||||
/* Complete the transfer and disable the interrupts */
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we're done with this transfer.*/
|
||||
if ((spi1_tx_data.cnt == tx_size) && (spi1_rx_data.cnt == tx_size))
|
||||
{
|
||||
spi1_tx_data.completed = true;
|
||||
/* Complete the transfer and disable the interrupts */
|
||||
LPSPI_DisableInterrupts(spi_base, 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(LPSPI1_IRQn, LPSPI1_IRQHandler, NONE);
|
||||
|
||||
void LPSPI2_IRQHandler(int vector, void *param)
|
||||
{
|
||||
LPSPI_Type *spi_base = LPSPI2;
|
||||
int rx_size = spi2_rx_data.size < TRANSFER_SIZE ? spi2_rx_data.size : TRANSFER_SIZE;
|
||||
int tx_size = spi2_tx_data.size < TRANSFER_SIZE ? spi2_tx_data.size : TRANSFER_SIZE;
|
||||
|
||||
if (spi2_rx_data.cnt < rx_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 on the LPSPI state after reading out the FIFO.
|
||||
*/
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||
|
||||
while (LPSPI_GetRxFifoCount(spi_base))
|
||||
{
|
||||
/*Read out the data*/
|
||||
spi2_rx_data.buf[spi2_rx_data.cnt] = LPSPI_ReadData(spi_base);
|
||||
spi2_rx_data.cnt++;
|
||||
|
||||
if (spi2_rx_data.cnt == rx_size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-enable the interrupts only if rxCount indicates there is more data to receive,
|
||||
* else we may get a spurious interrupt.
|
||||
* */
|
||||
if (spi2_rx_data.cnt < rx_size)
|
||||
{
|
||||
/* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
|
||||
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||
}
|
||||
}
|
||||
|
||||
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
|
||||
if ((rx_size - spi2_rx_data.cnt) <= spi2_rx_data.water)
|
||||
{
|
||||
spi_base->FCR =
|
||||
(spi_base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
|
||||
LPSPI_FCR_RXWATER(((rx_size - spi2_rx_data.cnt) > 1) ? ((rx_size - spi2_rx_data.cnt) - 1U) : (0U));
|
||||
}
|
||||
|
||||
if (spi2_tx_data.cnt < tx_size)
|
||||
{
|
||||
while ((LPSPI_GetTxFifoCount(spi_base) < spi2_tx_data.fifo) &&
|
||||
(spi2_tx_data.cnt - spi2_rx_data.cnt < spi2_tx_data.fifo))
|
||||
{
|
||||
/*Write the word to TX register*/
|
||||
LPSPI_WriteData(spi_base, spi2_tx_data.buf[spi2_tx_data.cnt]);
|
||||
spi2_tx_data.cnt++;
|
||||
|
||||
if (spi2_tx_data.cnt == tx_size)
|
||||
{
|
||||
spi2_tx_data.completed = true;
|
||||
/* Complete the transfer and disable the interrupts */
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we're done with this transfer.*/
|
||||
if ((spi2_tx_data.cnt == tx_size) && (spi2_rx_data.cnt == tx_size))
|
||||
{
|
||||
spi2_tx_data.completed = true;
|
||||
/* Complete the transfer and disable the interrupts */
|
||||
LPSPI_DisableInterrupts(spi_base, 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(LPSPI2_IRQn, LPSPI2_IRQHandler, NONE);
|
||||
|
||||
void LPSPI3_IRQHandler(int vector, void *param)
|
||||
{
|
||||
LPSPI_Type *spi_base = LPSPI3;
|
||||
int rx_size = spi3_rx_data.size < TRANSFER_SIZE ? spi3_rx_data.size : TRANSFER_SIZE;
|
||||
int tx_size = spi3_tx_data.size < TRANSFER_SIZE ? spi3_tx_data.size : TRANSFER_SIZE;
|
||||
|
||||
if (spi3_rx_data.cnt < rx_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 on the LPSPI state after reading out the FIFO.
|
||||
*/
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||
|
||||
while (LPSPI_GetRxFifoCount(spi_base))
|
||||
{
|
||||
/*Read out the data*/
|
||||
spi3_rx_data.buf[spi3_rx_data.cnt] = LPSPI_ReadData(spi_base);
|
||||
spi3_rx_data.cnt++;
|
||||
|
||||
if (spi3_rx_data.cnt == rx_size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Re-enable the interrupts only if rxCount indicates there is more data to receive,
|
||||
* else we may get a spurious interrupt.
|
||||
* */
|
||||
if (spi3_rx_data.cnt < rx_size)
|
||||
{
|
||||
/* Set the TDF and RDF interrupt enables simultaneously to avoid race conditions */
|
||||
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||
}
|
||||
}
|
||||
|
||||
/*Update rxWatermark. There isn't RX interrupt for the last datas if the RX count is not greater than rxWatermark.*/
|
||||
if ((rx_size - spi3_rx_data.cnt) <= spi3_rx_data.water)
|
||||
{
|
||||
spi_base->FCR =
|
||||
(spi_base->FCR & (~LPSPI_FCR_RXWATER_MASK)) |
|
||||
LPSPI_FCR_RXWATER(((rx_size - spi3_rx_data.cnt) > 1) ? ((rx_size - spi3_rx_data.cnt) - 1U) : (0U));
|
||||
}
|
||||
|
||||
if (spi3_tx_data.cnt < tx_size)
|
||||
{
|
||||
while ((LPSPI_GetTxFifoCount(spi_base) < spi3_tx_data.fifo) &&
|
||||
(spi3_tx_data.cnt - spi3_rx_data.cnt < spi3_tx_data.fifo))
|
||||
{
|
||||
/*Write the word to TX register*/
|
||||
LPSPI_WriteData(spi_base, spi3_tx_data.buf[spi3_tx_data.cnt]);
|
||||
spi3_tx_data.cnt++;
|
||||
|
||||
if (spi3_tx_data.cnt == tx_size)
|
||||
{
|
||||
spi3_tx_data.completed = true;
|
||||
/* Complete the transfer and disable the interrupts */
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if we're done with this transfer.*/
|
||||
if ((spi3_tx_data.cnt == tx_size) && (spi3_rx_data.cnt == tx_size))
|
||||
{
|
||||
spi3_tx_data.completed = true;
|
||||
/* Complete the transfer and disable the interrupts */
|
||||
LPSPI_DisableInterrupts(spi_base, 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(LPSPI3_IRQn, LPSPI3_IRQHandler, NONE);
|
||||
|
||||
void SpiMasterInit(LPSPI_Type *base)
|
||||
{
|
||||
lpspi_master_config_t cfg;
|
||||
|
||||
/*Master config*/
|
||||
cfg.baudRate = TRANSFER_BAUDRATE;
|
||||
cfg.bitsPerFrame = 8;
|
||||
cfg.cpol = kLPSPI_ClockPolarityActiveHigh;
|
||||
cfg.cpha = kLPSPI_ClockPhaseFirstEdge;
|
||||
cfg.direction = kLPSPI_MsbFirst;
|
||||
|
||||
cfg.pcsToSckDelayInNanoSec = 1000000000 / cfg.baudRate;
|
||||
cfg.lastSckToPcsDelayInNanoSec = 1000000000 / cfg.baudRate;
|
||||
cfg.betweenTransferDelayInNanoSec = 1000000000 / cfg.baudRate;
|
||||
|
||||
cfg.whichPcs = SPI_PCS_FOR_INIT;
|
||||
cfg.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
|
||||
|
||||
cfg.pinCfg = kLPSPI_SdiInSdoOut;
|
||||
cfg.dataOutConfig = kLpspiDataOutRetained;
|
||||
|
||||
LPSPI_MasterInit(base, &cfg, SPI_CLOCK_FREQ);
|
||||
}
|
||||
|
||||
void SpiSlaveInit(LPSPI_Type *base)
|
||||
{
|
||||
lpspi_slave_config_t cfg;
|
||||
|
||||
/*Slave config*/
|
||||
cfg.bitsPerFrame = 8;
|
||||
cfg.cpol = kLPSPI_ClockPolarityActiveHigh;
|
||||
cfg.cpha = kLPSPI_ClockPhaseFirstEdge;
|
||||
cfg.direction = kLPSPI_MsbFirst;
|
||||
|
||||
cfg.whichPcs = SPI_PCS_FOR_INIT;
|
||||
cfg.pcsActiveHighOrLow = kLPSPI_PcsActiveLow;
|
||||
|
||||
cfg.pinCfg = kLPSPI_SdiInSdoOut;
|
||||
cfg.dataOutConfig = kLpspiDataOutRetained;
|
||||
|
||||
LPSPI_SlaveInit(base, &cfg);
|
||||
}
|
||||
|
||||
int SpiHwParamInit(struct Stm32HwSpi *spi_param)
|
||||
{
|
||||
LPSPI_Type *spi_base = spi_param->base;
|
||||
uint32_t whichPcs = kLPSPI_Pcs0;
|
||||
uint8_t fifo_size, tx_water, rx_water;
|
||||
|
||||
/*The TX and RX FIFO sizes are always the same*/
|
||||
fifo_size = LPSPI_GetRxFifoSize(spi_base);
|
||||
|
||||
/*Set the RX and TX watermarks to reduce the ISR times.*/
|
||||
if (fifo_size > 1)
|
||||
{
|
||||
tx_water = 1;
|
||||
rx_water = fifo_size - 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
tx_water = 0;
|
||||
rx_water = 0;
|
||||
}
|
||||
|
||||
LPSPI_SetFifoWatermarks(spi_base, tx_water, rx_water);
|
||||
|
||||
LPSPI_Enable(spi_base, false);
|
||||
spi_base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
|
||||
LPSPI_Enable(spi_base, true);
|
||||
|
||||
/*Flush FIFO , clear status , disable all the inerrupts.*/
|
||||
LPSPI_FlushFifo(spi_base, true, true);
|
||||
LPSPI_ClearStatusFlags(spi_base, kLPSPI_AllStatusFlag);
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||
|
||||
spi_base->TCR =
|
||||
(spi_base->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(spi_param->irq);
|
||||
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||
}
|
||||
|
||||
int SpiReadData(struct Stm32HwSpi *spi_param, uint8_t *buf, int len)
|
||||
{
|
||||
int fifo_size;
|
||||
int timeout = 50; // wait for read SPI data
|
||||
LPSPI_Type *spi_base = spi_param->base;
|
||||
|
||||
BOARD_InitSPIPins();
|
||||
|
||||
/*Set clock source for LPSPI*/
|
||||
CLOCK_SetMux(kCLOCK_LpspiMux, SPI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_SetDiv(kCLOCK_LpspiDiv, SPI_CLOCK_SOURCE_DIVIDER);
|
||||
|
||||
uint32_t errorCount;
|
||||
uint32_t i;
|
||||
uint32_t whichPcs;
|
||||
uint8_t txWatermark;
|
||||
|
||||
BOARD_InitSPIPins();
|
||||
|
||||
/*Set clock source for LPSPI*/
|
||||
CLOCK_SetMux(kCLOCK_LpspiMux, SPI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_SetDiv(kCLOCK_LpspiDiv, SPI_CLOCK_SOURCE_DIVIDER);
|
||||
|
||||
/*Set up the transfer data*/
|
||||
for (i = 0; i < TRANSFER_SIZE; i++)
|
||||
{
|
||||
spi1_rx_data.buf[i] = 0;
|
||||
}
|
||||
|
||||
SpiSlaveInit(spi_base);
|
||||
|
||||
/******************Set up slave first ******************/
|
||||
spi1_rx_data.completed = false;
|
||||
spi1_rx_data.cnt = 0;
|
||||
spi1_rx_data.size = len;
|
||||
whichPcs = SPI_PCS_FOR_INIT;
|
||||
|
||||
/*The TX and RX FIFO sizes are always the same*/
|
||||
spi1_rx_data.fifo = LPSPI_GetRxFifoSize(spi_base);
|
||||
|
||||
/*Set the RX and TX watermarks to reduce the ISR times.*/
|
||||
if (spi1_rx_data.fifo > 1)
|
||||
{
|
||||
txWatermark = 1;
|
||||
spi1_rx_data.water = spi1_rx_data.fifo - 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
txWatermark = 0;
|
||||
spi1_rx_data.water = 0;
|
||||
}
|
||||
|
||||
LPSPI_SetFifoWatermarks(spi_base, txWatermark, spi1_rx_data.water);
|
||||
|
||||
LPSPI_Enable(spi_base, false);
|
||||
spi_base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
|
||||
LPSPI_Enable(spi_base, true);
|
||||
|
||||
/*Flush FIFO , clear status , disable all the interrupts.*/
|
||||
LPSPI_FlushFifo(spi_base, true, true);
|
||||
LPSPI_ClearStatusFlags(spi_base, kLPSPI_AllStatusFlag);
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||
|
||||
spi_base->TCR =
|
||||
(spi_base->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(spi_param->irq);
|
||||
LPSPI_EnableInterrupts(spi_base, kLPSPI_RxInterruptEnable);
|
||||
|
||||
/******************Wait for slave transfer completed.******************/
|
||||
while((spi1_rx_data.cnt < (len - 1)) && (timeout--))
|
||||
{
|
||||
MdelayKTask(100);
|
||||
}
|
||||
|
||||
if(buf && (len <= TRANSFER_SIZE))
|
||||
{
|
||||
memcpy(buf, spi1_rx_data.buf, len);
|
||||
}
|
||||
|
||||
LPSPI_Deinit(spi_base);
|
||||
}
|
||||
|
||||
void SpiWriteData(struct Stm32HwSpi *spi_param, const uint8_t *buf, uint16_t len)
|
||||
{
|
||||
uint32_t errorCount;
|
||||
uint32_t i;
|
||||
uint32_t whichPcs;
|
||||
uint8_t txWatermark;
|
||||
LPSPI_Type *spi_base = spi_param->base;
|
||||
int timeout = 1000; // wait for write SPI data
|
||||
|
||||
BOARD_InitSPIPins();
|
||||
|
||||
/*Set clock source for LPSPI*/
|
||||
CLOCK_SetMux(kCLOCK_LpspiMux, SPI_CLOCK_SOURCE_SELECT);
|
||||
CLOCK_SetDiv(kCLOCK_LpspiDiv, SPI_CLOCK_SOURCE_DIVIDER);
|
||||
/*Set up the transfer data*/
|
||||
memcpy(spi1_tx_data.buf, buf, len);
|
||||
|
||||
SpiMasterInit(spi_base);
|
||||
|
||||
spi1_rx_data.size = len;
|
||||
spi1_tx_data.size = len;
|
||||
spi1_tx_data.completed = false;
|
||||
spi1_tx_data.cnt = 0;
|
||||
spi1_rx_data.cnt = 0;
|
||||
whichPcs = SPI_PCS_FOR_INIT;
|
||||
|
||||
/*The TX and RX FIFO sizes are always the same*/
|
||||
spi1_tx_data.fifo = LPSPI_GetRxFifoSize(spi_base);
|
||||
|
||||
/*Set the RX and TX watermarks to reduce the ISR times.*/
|
||||
if (spi1_tx_data.fifo > 1)
|
||||
{
|
||||
txWatermark = 1;
|
||||
spi1_rx_data.water = spi1_tx_data.fifo - 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
txWatermark = 0;
|
||||
spi1_rx_data.water = 0;
|
||||
}
|
||||
|
||||
LPSPI_SetFifoWatermarks(spi_base, txWatermark, spi1_rx_data.water);
|
||||
|
||||
LPSPI_Enable(spi_base, false);
|
||||
spi_base->CFGR1 &= (~LPSPI_CFGR1_NOSTALL_MASK);
|
||||
LPSPI_Enable(spi_base, true);
|
||||
|
||||
/*Flush FIFO , clear status , disable all the inerrupts.*/
|
||||
LPSPI_FlushFifo(spi_base, true, true);
|
||||
LPSPI_ClearStatusFlags(spi_base, kLPSPI_AllStatusFlag);
|
||||
LPSPI_DisableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||
|
||||
spi_base->TCR =
|
||||
(spi_base->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(spi_param->irq);
|
||||
LPSPI_EnableInterrupts(spi_base, kLPSPI_AllInterruptEnable);
|
||||
|
||||
while((spi1_tx_data.cnt < (spi1_tx_data.size - 1)) && (timeout--))
|
||||
{
|
||||
MdelayKTask(10);
|
||||
}
|
||||
|
||||
spi_print("SPI: master rx %d tx %d size %d completed s %d m %d!\r\n", spi1_rx_data.cnt,
|
||||
spi1_tx_data.cnt, spi1_tx_data.size, spi1_rx_data.completed, spi1_tx_data.completed);
|
||||
|
||||
LPSPI_Deinit(spi_base);
|
||||
}
|
||||
|
||||
static uint32 Stm32SpiWriteData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
||||
{
|
||||
int state;
|
||||
x_size_t message_length, already_send_length;
|
||||
uint16 send_length;
|
||||
const uint8 *write_buf;
|
||||
|
||||
NULL_PARAM_CHECK(spi_dev);
|
||||
NULL_PARAM_CHECK(spi_datacfg);
|
||||
|
||||
struct Stm32Spi *StmSpi = CONTAINER_OF(spi_dev->haldev.owner_bus, struct Stm32Spi, spi_bus);
|
||||
struct Stm32HwSpi *StmCfg = (struct Stm32HwSpi *) spi_dev->haldev.private_data;
|
||||
|
||||
while(NONE != spi_datacfg) {
|
||||
|
||||
message_length = spi_datacfg->length;
|
||||
write_buf = spi_datacfg->tx_buff;
|
||||
while (message_length) {
|
||||
if (message_length > 65535){
|
||||
send_length = 65535;
|
||||
message_length = message_length - 65535;
|
||||
} else {
|
||||
send_length = message_length;
|
||||
message_length = 0;
|
||||
}
|
||||
|
||||
/* calculate the start address */
|
||||
already_send_length = spi_datacfg->length - send_length - message_length;
|
||||
write_buf = (uint8 *)spi_datacfg->tx_buff + already_send_length;
|
||||
|
||||
if (spi_datacfg->tx_buff) {
|
||||
SpiWriteData(StmCfg, spi_datacfg->tx_buff, send_length);
|
||||
}
|
||||
|
||||
if (state != 0) {
|
||||
KPrintf("spi write error : %d\n", state);
|
||||
spi_datacfg->length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
spi_datacfg = spi_datacfg->next;
|
||||
}
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
static uint32 Stm32SpiReadData(struct SpiHardwareDevice *spi_dev, struct SpiDataStandard *spi_datacfg)
|
||||
{
|
||||
int state;
|
||||
x_size_t message_length, already_send_length;
|
||||
uint16 read_length, spi_read_length = 0;
|
||||
uint8 *read_buf;
|
||||
|
||||
NULL_PARAM_CHECK(spi_dev);
|
||||
NULL_PARAM_CHECK(spi_datacfg);
|
||||
|
||||
struct Stm32Spi *StmSpi = CONTAINER_OF(spi_dev->haldev.owner_bus, struct Stm32Spi, spi_bus);
|
||||
struct Stm32HwSpi *StmCfg = (struct Stm32HwSpi *) spi_dev->haldev.private_data;
|
||||
|
||||
while (NONE != spi_datacfg) {
|
||||
message_length = spi_datacfg->length;
|
||||
read_buf = spi_datacfg->rx_buff;
|
||||
while (message_length) {
|
||||
if (message_length > 65535) {
|
||||
read_length = 65535;
|
||||
message_length = message_length - 65535;
|
||||
} else {
|
||||
read_length = message_length;
|
||||
message_length = 0;
|
||||
}
|
||||
|
||||
/* calculate the start address */
|
||||
already_send_length = spi_datacfg->length - read_length - message_length;
|
||||
read_buf = (uint8 *)spi_datacfg->rx_buff + already_send_length;
|
||||
|
||||
if (spi_datacfg->rx_buff) {
|
||||
memset(read_buf, 0xff, read_length);
|
||||
SpiReadData(StmCfg, read_buf, read_length);
|
||||
}
|
||||
|
||||
if (state != 0) {
|
||||
KPrintf("spi read error : %d\n", state);
|
||||
spi_datacfg->length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
spi_read_length += spi_datacfg->length;
|
||||
spi_datacfg = spi_datacfg->next;
|
||||
}
|
||||
|
||||
return spi_read_length;
|
||||
}
|
||||
|
||||
static const struct SpiDevDone spi_dev_done =
|
||||
{
|
||||
.dev_open = NONE,
|
||||
.dev_close = NONE,
|
||||
.dev_write = Stm32SpiWriteData,
|
||||
.dev_read = Stm32SpiReadData,
|
||||
};
|
||||
|
||||
static x_err_t Stm32SpiInit(struct Stm32Spi *spi_drv, struct SpiMasterParam *cfg)
|
||||
{
|
||||
NULL_PARAM_CHECK(spi_drv);
|
||||
NULL_PARAM_CHECK(cfg);
|
||||
}
|
||||
|
||||
static uint32 SpiDrvInit(struct SpiDriver *spi_drv)
|
||||
{
|
||||
NULL_PARAM_CHECK(spi_drv);
|
||||
|
||||
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data);
|
||||
|
||||
struct Stm32Spi *StmSpi = CONTAINER_OF(spi_drv->driver.owner_bus, struct Stm32Spi, spi_bus);
|
||||
|
||||
return Stm32SpiInit(StmSpi, dev_param->spi_master_param);
|
||||
}
|
||||
|
||||
static uint32 SpiDrvConfigure(struct SpiDriver *spi_drv, struct SpiMasterParam *spi_param)
|
||||
{
|
||||
NULL_PARAM_CHECK(spi_drv);
|
||||
NULL_PARAM_CHECK(spi_param);
|
||||
|
||||
SpiDeviceParam *dev_param = (SpiDeviceParam *)(spi_drv->driver.private_data);
|
||||
|
||||
dev_param->spi_master_param = spi_param;
|
||||
dev_param->spi_master_param->spi_work_mode = dev_param->spi_master_param->spi_work_mode & SPI_MODE_MASK;
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
/*Configure the spi device param, make sure struct (configure_info->private_data) = (SpiMasterParam)*/
|
||||
static uint32 Stm32SpiDrvConfigure(void *drv, struct BusConfigureInfo *configure_info)
|
||||
{
|
||||
NULL_PARAM_CHECK(drv);
|
||||
NULL_PARAM_CHECK(configure_info);
|
||||
|
||||
x_err_t ret = EOK;
|
||||
struct SpiDriver *spi_drv = (struct SpiDriver *)drv;
|
||||
struct SpiMasterParam *spi_param;
|
||||
|
||||
switch (configure_info->configure_cmd)
|
||||
{
|
||||
case OPE_INT:
|
||||
ret = SpiDrvInit(spi_drv);
|
||||
break;
|
||||
case OPE_CFG:
|
||||
spi_param = (struct SpiMasterParam *)configure_info->private_data;
|
||||
ret = SpiDrvConfigure(spi_drv, spi_param);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int BoardSpiBusInit(struct Stm32Spi *stm32spi_bus, struct SpiDriver *spi_driver, char* drv_name)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
|
||||
/*Init the spi bus */
|
||||
ret = SpiBusInit(&stm32spi_bus->spi_bus, stm32spi_bus->bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_Spi_init SpiBusInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Init the spi driver*/
|
||||
ret = SpiDriverInit(spi_driver, drv_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_Spi_init SpiDriverInit error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/*Attach the spi driver to the spi bus*/
|
||||
ret = SpiDriverAttachToBus(drv_name, stm32spi_bus->bus_name);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_Spi_init SpiDriverAttachToBus error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int Stm32HwSpiBusInit(void)
|
||||
{
|
||||
x_err_t ret = EOK;
|
||||
struct Stm32Spi *StmSpiBus;
|
||||
|
||||
#ifdef BSP_USING_SPI1
|
||||
StmSpiBus = &spi1;
|
||||
StmSpiBus->instance = LPSPI1;
|
||||
StmSpiBus->bus_name = SPI_1_BUS_NAME;
|
||||
StmSpiBus->spi_bus.private_data = &spi1;
|
||||
|
||||
static struct SpiDriver spi_driver_1;
|
||||
memset(&spi_driver_1, 0, sizeof(struct SpiDriver));
|
||||
|
||||
spi_driver_1.configure = &(Stm32SpiDrvConfigure);
|
||||
|
||||
ret = BoardSpiBusInit(StmSpiBus, &spi_driver_1, SPI_1_DRV_NAME);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_Spi_Init spi_bus_init %s error ret %u\n", StmSpiBus->bus_name, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static struct SpiHardwareDevice spi1_dev;
|
||||
static struct Stm32HwSpi spi1_cfg;
|
||||
|
||||
spi1_cfg.base = StmSpiBus->instance;
|
||||
spi1_cfg.irq = LPSPI1_IRQn;
|
||||
spi1_dev.spi_dev_done = &spi_dev_done;
|
||||
|
||||
ret = SpiDeviceRegister(&spi1_dev, (void *)&spi1_cfg, SPI_1_DEV_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = SpiDeviceAttachToBus(SPI_1_DEV_NAME_0, SPI_1_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SPI2
|
||||
StmSpiBus = &spi2;
|
||||
StmSpiBus->instance = LPSPI2;
|
||||
StmSpiBus->bus_name = SPI_2_BUS_NAME;
|
||||
StmSpiBus->spi_bus.private_data = &spi2;
|
||||
|
||||
static struct SpiDriver spi_driver_2;
|
||||
memset(&spi_driver_2, 0, sizeof(struct SpiDriver));
|
||||
|
||||
spi_driver_2.configure = &(Stm32SpiDrvConfigure);
|
||||
|
||||
ret = BoardSpiBusInit(StmSpiBus, &spi_driver_2, SPI_2_DRV_NAME);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_Spi_Init spi_bus_init %s error ret %u\n", StmSpiBus->bus_name, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static struct SpiHardwareDevice spi2_dev;
|
||||
static struct Stm32HwSpi spi2_cfg;
|
||||
|
||||
spi2_cfg.base = StmSpiBus->instance;
|
||||
spi2_cfg.irq = LPSPI2_IRQn;
|
||||
spi2_dev.spi_dev_done = &spi_dev_done;
|
||||
|
||||
ret = SpiDeviceRegister(&spi2_dev, (void *)&spi2_cfg, SPI_2_DEV_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = SpiDeviceAttachToBus(SPI_2_DEV_NAME_0, SPI_2_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef BSP_USING_SPI3
|
||||
StmSpiBus = &spi3;
|
||||
StmSpiBus->instance = LPSPI3;
|
||||
StmSpiBus->bus_name = SPI_3_BUS_NAME;
|
||||
StmSpiBus->spi_bus.private_data = &spi3;
|
||||
|
||||
static struct SpiDriver spi_driver_3;
|
||||
memset(&spi_driver_3, 0, sizeof(struct SpiDriver));
|
||||
|
||||
spi_driver_3.configure = &(Stm32SpiDrvConfigure);
|
||||
|
||||
ret = BoardSpiBusInit(StmSpiBus, &spi_driver_3, SPI_3_DRV_NAME);
|
||||
if (EOK != ret) {
|
||||
KPrintf("Board_Spi_Init spi_bus_init %s error ret %u\n", StmSpiBus->bus_name, ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static struct SpiHardwareDevice spi3_dev;
|
||||
static struct Stm32HwSpi spi3_cfg;
|
||||
|
||||
spi3_cfg.base = StmSpiBus->instance;
|
||||
spi3_cfg.irq = LPSPI3_IRQn;
|
||||
spi3_dev.spi_dev_done = &spi_dev_done;
|
||||
|
||||
ret = SpiDeviceRegister(&spi3_dev, (void *)&spi3_cfg, SPI_3_DEV_NAME_0);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
ret = SpiDeviceAttachToBus(SPI_3_DEV_NAME_0, SPI_3_BUS_NAME);
|
||||
if (ret != EOK) {
|
||||
KPrintf("ADC1 device register error %d\n", ret);
|
||||
return ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
return EOK;
|
||||
}
|
||||
|
||||
x_err_t HwSpiDeviceAttach(const char *bus_name, const char *device_name)
|
||||
{
|
||||
NULL_PARAM_CHECK(bus_name);
|
||||
NULL_PARAM_CHECK(device_name);
|
||||
|
||||
x_err_t result;
|
||||
struct SpiHardwareDevice *spi_device;
|
||||
static SpiDeviceParam spi_dev_param;
|
||||
memset(&spi_dev_param, 0, sizeof(SpiDeviceParam));
|
||||
|
||||
/* attach the device to spi bus*/
|
||||
spi_device = (struct SpiHardwareDevice *)x_malloc(sizeof(struct SpiHardwareDevice));
|
||||
CHECK(spi_device);
|
||||
memset(spi_device, 0, sizeof(struct SpiHardwareDevice));
|
||||
|
||||
spi_device->spi_dev_done = &spi_dev_done;
|
||||
|
||||
result = SpiDeviceRegister(spi_device, (void *)&spi_dev_param, device_name);
|
||||
if (result != EOK) {
|
||||
SYS_ERR("%s device %p register faild, %d\n", device_name, spi_device, result);
|
||||
}
|
||||
|
||||
result = SpiDeviceAttachToBus(device_name, bus_name);
|
||||
if (result != EOK) {
|
||||
SYS_ERR("%s attach to %s faild, %d\n", device_name, bus_name, result);
|
||||
}
|
||||
|
||||
CHECK(result == EOK);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int Imrt1052HwSpiInit(void)
|
||||
{
|
||||
return Stm32HwSpiBusInit();
|
||||
}
|
||||
|
||||
void SpiReadTest(void *arg)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t test_buf[32] = {0};
|
||||
struct Stm32HwSpi spi_param;
|
||||
spi_param.base = LPSPI1;
|
||||
spi_param.irq = LPSPI1_IRQn;
|
||||
|
||||
SpiReadData(&spi_param, test_buf, 32);
|
||||
|
||||
for(i = 0; i < sizeof(test_buf) ;i ++)
|
||||
{
|
||||
spi_print("%d - %x\n", i, test_buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
||||
spiread, SpiReadTest, SPI Read);
|
||||
|
||||
void SpiWriteTest(void *arg)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t test_buf[100] = {0};
|
||||
struct Stm32HwSpi spi_param;
|
||||
spi_param.base = LPSPI1;
|
||||
spi_param.irq = LPSPI1_IRQn;
|
||||
|
||||
for(i = 0; i < sizeof(test_buf) ;i ++)
|
||||
{
|
||||
test_buf[i] = i;
|
||||
}
|
||||
|
||||
SpiWriteData(&spi_param, test_buf, 100);
|
||||
}
|
||||
|
||||
SHELL_EXPORT_CMD (SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
|
||||
spiwrite, SpiWriteTest, SPI Write );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user