Added PixArt sensor.

This commit is contained in:
imi415 2022-07-20 00:10:20 +08:00
parent e94ac8ebb3
commit 256cb0eace
11 changed files with 279 additions and 5 deletions

View File

@ -52,6 +52,7 @@ set(TARGET_SOURCES
"board/peripherals.c"
"board/pin_mux.c"
"src/main.c"
"src/pah8001_impl.c"
)
set(TARGET_C_DEFINES
@ -77,6 +78,7 @@ set(TARGET_C_INCLUDES
# Shared libraries linked with application
set(TARGET_LIBS
"power_cm4_hardabi"
"pah8001"
)
# Shared library and linker script search paths
@ -105,6 +107,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TARGET_CFLAGS_HARDWARE} -Wall -
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} ${CMAKE_C_FLAGS} -x assembler-with-cpp")
set(CMAKE_EXE_LINKER_FLAGS "-specs=nano.specs -specs=nosys.specs -Wl,--gc-sections -Wl,--print-memory-usage -lc -lm -lnosys ")
add_subdirectory(lib/pixart_pah8001ei)
# Shared sources, includes and definitions
add_compile_definitions(${TARGET_C_DEFINES})

View File

@ -40,6 +40,11 @@
<data>true</data>
</feature>
</dependency>
<dependency resourceType="Peripheral" resourceId="I2C0" description="Peripheral I2C0 is not initialized" problem_level="1" source="Pins:BOARD_InitPins">
<feature name="initialized" evaluation="equal" configuration="cm4">
<data>true</data>
</feature>
</dependency>
<dependency resourceType="SWComponent" resourceId="platform.drivers.common" description="Pins initialization requires the COMMON Driver in the project." problem_level="2" source="Pins:BOARD_InitPins">
<feature name="enabled" evaluation="equal" configuration="cm4">
<data>true</data>
@ -49,6 +54,8 @@
<pins>
<pin peripheral="USART0" signal="RXD" pin_num="31" pin_signal="PIO0_0/U0_RXD/SPI0_SSEL0/CT32B0_CAP0/SCT0_OUT3"/>
<pin peripheral="USART0" signal="TXD" pin_num="32" pin_signal="PIO0_1/U0_TXD/SPI0_SSEL1/CT32B0_CAP1/SCT0_OUT1"/>
<pin peripheral="I2C0" signal="SCL" pin_num="1" pin_signal="PIO0_23/I2C0_SCL/CT32B0_CAP0"/>
<pin peripheral="I2C0" signal="SDA" pin_num="2" pin_signal="PIO0_24/I2C0_SDA/CT32B0_CAP1/CT32B0_MAT0"/>
</pins>
</function>
</functions_list>
@ -117,6 +124,18 @@
<dcdx_configurations/>
</dcdx>
<periphs name="Peripherals" version="11.0" enabled="true" update_project_code="true">
<dependencies>
<dependency resourceType="SWComponent" resourceId="platform.drivers.lpc_i2c" description="I2C Driver not found in the toolchain/IDE project. Project will not compile!" problem_level="2" source="Peripherals">
<feature name="enabled" evaluation="equal">
<data type="Boolean">true</data>
</feature>
</dependency>
<dependency resourceType="SWComponent" resourceId="platform.drivers.lpc_i2c" description="Unsupported version of the I2C Driver in the toolchain/IDE project. Required: ${required_value}, actual: ${actual_value}. Project might not compile correctly." problem_level="1" source="Peripherals">
<feature name="version" evaluation="greaterOrEqual">
<data type="Version">2.0.2</data>
</feature>
</dependency>
</dependencies>
<generated_project_files>
<file path="board/peripherals.c" update_enabled="true"/>
<file path="board/peripherals.h" update_enabled="true"/>
@ -128,7 +147,23 @@
<functional_group name="BOARD_InitPeripherals" uuid="bf976c30-387a-4c02-956c-44a37954526e" called_from_default_init="true" id_prefix="" core="cm4">
<description></description>
<options/>
<dependencies/>
<dependencies>
<dependency resourceType="PeripheralUnifiedSignal" resourceId="I2C0.i2c_scl" description="Signal I2C serial clock of the peripheral I2C0 is not routed." problem_level="1" source="Peripherals:BOARD_InitPeripherals">
<feature name="routed" evaluation="">
<data type="Boolean">true</data>
</feature>
</dependency>
<dependency resourceType="PeripheralUnifiedSignal" resourceId="I2C0.i2c_sda" description="Signal I2C serial data of the peripheral I2C0 is not routed." problem_level="1" source="Peripherals:BOARD_InitPeripherals">
<feature name="routed" evaluation="">
<data type="Boolean">true</data>
</feature>
</dependency>
<dependency resourceType="ClockOutput" resourceId="ASYNCAPB_clock" description="Async APB clock is inactive." problem_level="2" source="Peripherals:BOARD_InitPeripherals">
<feature name="frequency" evaluation="greaterThan">
<data type="Frequency" unit="Hz">0</data>
</feature>
</dependency>
</dependencies>
<instances>
<instance name="NVIC" uuid="95540aad-a83e-4f89-94d4-464eb84246d4" type="nvic" type_id="nvic_57b5eef3774cc60acaede6f5b8bddc67" mode="general" peripheral="NVIC" enabled="true" comment="" custom_name_enabled="false" editing_lock="false">
<config_set name="nvic">
@ -136,6 +171,18 @@
<array name="interrupts"/>
</config_set>
</instance>
<instance name="I2C0" uuid="8c158812-8c36-435e-96a5-53333b28b733" type="lpc_i2c" type_id="lpc_i2c_f5051a0134792729f1007113ec6ddccd" mode="I2C_Polling" peripheral="I2C0" enabled="true" comment="" custom_name_enabled="false" editing_lock="false">
<config_set name="fsl_i2c">
<setting name="i2c_mode" value="kI2C_Master"/>
<setting name="clockSource" value="FunctionClock"/>
<setting name="clockSourceFreq" value="BOARD_BootClockRUN"/>
<struct name="i2c_master_config">
<setting name="enableMaster" value="true"/>
<setting name="baudRate_Bps" value="100000"/>
<setting name="enableTimeout" value="false"/>
</struct>
</config_set>
</instance>
</instances>
</functional_group>
</functional_groups>

View File

@ -76,12 +76,48 @@ instance:
static void NVIC_init(void) {
} */
/***********************************************************************************************************************
* I2C0 initialization code
**********************************************************************************************************************/
/* clang-format off */
/* TEXT BELOW IS USED AS SETTING FOR TOOLS *************************************
instance:
- name: 'I2C0'
- type: 'lpc_i2c'
- mode: 'I2C_Polling'
- custom_name_enabled: 'false'
- type_id: 'lpc_i2c_f5051a0134792729f1007113ec6ddccd'
- functional_group: 'BOARD_InitPeripherals'
- peripheral: 'I2C0'
- config_sets:
- fsl_i2c:
- i2c_mode: 'kI2C_Master'
- clockSource: 'FunctionClock'
- clockSourceFreq: 'BOARD_BootClockRUN'
- i2c_master_config:
- enableMaster: 'true'
- baudRate_Bps: '100000'
- enableTimeout: 'false'
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/
/* clang-format on */
const i2c_master_config_t I2C0_config = {
.enableMaster = true,
.baudRate_Bps = 100000UL,
.enableTimeout = false
};
static void I2C0_init(void) {
/* Initialization function */
I2C_MasterInit(I2C0_PERIPHERAL, &I2C0_config, I2C0_CLOCK_SOURCE);
}
/***********************************************************************************************************************
* Initialization functions
**********************************************************************************************************************/
void BOARD_InitPeripherals(void)
{
/* Initialize components */
I2C0_init();
}
/***********************************************************************************************************************

View File

@ -10,11 +10,27 @@
* Included files
**********************************************************************************************************************/
#include "fsl_common.h"
#include "fsl_i2c.h"
#if defined(__cplusplus)
extern "C" {
#endif /* __cplusplus */
/***********************************************************************************************************************
* Definitions
**********************************************************************************************************************/
/* Definitions for BOARD_InitPeripherals functional group */
/* BOARD_InitPeripherals defines for I2C0 */
/* Definition of peripheral ID */
#define I2C0_PERIPHERAL ((I2C_Type *)I2C0)
/* Definition of the clock source frequency */
#define I2C0_CLOCK_SOURCE 12000000UL
/***********************************************************************************************************************
* Global variables
**********************************************************************************************************************/
extern const i2c_master_config_t I2C0_config;
/***********************************************************************************************************************
* Initialization functions
**********************************************************************************************************************/

View File

@ -38,6 +38,8 @@ BOARD_InitPins:
- pin_list:
- {pin_num: '31', peripheral: USART0, signal: RXD, pin_signal: PIO0_0/U0_RXD/SPI0_SSEL0/CT32B0_CAP0/SCT0_OUT3}
- {pin_num: '32', peripheral: USART0, signal: TXD, pin_signal: PIO0_1/U0_TXD/SPI0_SSEL1/CT32B0_CAP1/SCT0_OUT1}
- {pin_num: '1', peripheral: I2C0, signal: SCL, pin_signal: PIO0_23/I2C0_SCL/CT32B0_CAP0}
- {pin_num: '2', peripheral: I2C0, signal: SDA, pin_signal: PIO0_24/I2C0_SDA/CT32B0_CAP1/CT32B0_MAT0}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS ***********
*/
/* clang-format on */
@ -77,6 +79,30 @@ void BOARD_InitPins(void)
/* Select Analog/Digital mode.
* : Digital mode. */
| IOCON_PIO_DIGIMODE(PIO01_DIGIMODE_DIGITAL));
IOCON->PIO[0][23] = ((IOCON->PIO[0][23] &
/* Mask bits to zero which are setting */
(~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))
/* Selects pin function.
* : PORT023 (pin 1) is configured as I2C0_SCL. */
| IOCON_PIO_FUNC(PIO023_FUNC_ALT1)
/* Select Analog/Digital mode.
* : Digital mode. */
| IOCON_PIO_DIGIMODE(PIO023_DIGIMODE_DIGITAL));
IOCON->PIO[0][24] = ((IOCON->PIO[0][24] &
/* Mask bits to zero which are setting */
(~(IOCON_PIO_FUNC_MASK | IOCON_PIO_DIGIMODE_MASK)))
/* Selects pin function.
* : PORT024 (pin 2) is configured as I2C0_SDA. */
| IOCON_PIO_FUNC(PIO024_FUNC_ALT1)
/* Select Analog/Digital mode.
* : Digital mode. */
| IOCON_PIO_DIGIMODE(PIO024_DIGIMODE_DIGITAL));
}
/***********************************************************************************************************************
* EOF

View File

@ -25,10 +25,14 @@ extern "C" {
*/
void BOARD_InitBootPins(void);
#define PIO00_DIGIMODE_DIGITAL 0x01u /*!<@brief Select Analog/Digital mode.: Digital mode. */
#define PIO00_FUNC_ALT1 0x01u /*!<@brief Selects pin function.: Alternative connection 1. */
#define PIO01_DIGIMODE_DIGITAL 0x01u /*!<@brief Select Analog/Digital mode.: Digital mode. */
#define PIO01_FUNC_ALT1 0x01u /*!<@brief Selects pin function.: Alternative connection 1. */
#define PIO00_DIGIMODE_DIGITAL 0x01u /*!<@brief Select Analog/Digital mode.: Digital mode. */
#define PIO00_FUNC_ALT1 0x01u /*!<@brief Selects pin function.: Alternative connection 1. */
#define PIO01_DIGIMODE_DIGITAL 0x01u /*!<@brief Select Analog/Digital mode.: Digital mode. */
#define PIO01_FUNC_ALT1 0x01u /*!<@brief Selects pin function.: Alternative connection 1. */
#define PIO023_DIGIMODE_DIGITAL 0x01u /*!<@brief Select Analog/Digital mode.: Digital mode. */
#define PIO023_FUNC_ALT1 0x01u /*!<@brief Selects pin function.: Alternative connection 1. */
#define PIO024_DIGIMODE_DIGITAL 0x01u /*!<@brief Select Analog/Digital mode.: Digital mode. */
#define PIO024_FUNC_ALT1 0x01u /*!<@brief Selects pin function.: Alternative connection 1. */
/*!
* @brief Configures pin routing and optionally pin electrical features.

View File

@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.10)
project(pah8001)
set(PAH8001_SOURCES
"src/pixart_pah8001ei.c"
)
set(PAH8001_INCLUDES
"include"
)
add_library(${PROJECT_NAME} ${PAH8001_SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC ${PAH8001_INCLUDES})

View File

@ -0,0 +1,29 @@
#ifndef PIXART_PAH8001EI_H
#define PIXART_PAH8001EI_H
#include <stddef.h>
#include <stdint.h>
typedef enum {
PAH_RET_OK,
PAH_RET_FAIL,
} pah_ret_t;
typedef pah_ret_t (*pah_ops_init_t)(void *pdev);
typedef pah_ret_t (*pah_ops_read_t)(void *pdev, uint8_t reg, uint8_t *value, uint16_t len);
typedef pah_ret_t (*pah_ops_write_t)(void *pdev, uint8_t reg, uint8_t *value, uint16_t len);
typedef struct {
pah_ops_init_t init;
pah_ops_read_t read;
pah_ops_write_t write;
} pah_ops_t;
typedef struct {
pah_ops_t ops;
void *pdev;
} pah_t;
pah_ret_t pah8001_init(pah_t *pah);
#endif

View File

@ -0,0 +1,27 @@
#include "pixart_pah8001ei.h"
#define PAH8001_R_CONFIG 0x06
#define PAH8001_R_CONFIG_RESET_Pos 7
#define PAH8001_R_CONFIG_RESET_Msk (1U << PAH8001_R_CONFIG_RESET_Pos)
#define PAH8001_R_CONFIG_POWERDOWN_Pos 3
#define PAH8001_R_CONFIG_POWERDOWN_Msk (1U << PAH8001_R_CONFIG_POWERDOWN_Pos)
#define PAH8001_ERROR_CHECK(x) \
if (x != PAH_RET_OK) return PAH_RET_FAIL
static pah_ret_t pah8001_reset(pah_t *pah) {
uint8_t wdata = PAH8001_R_CONFIG_RESET_Msk | 2U;
PAH8001_ERROR_CHECK(pah->ops.write(pah->pdev, PAH8001_R_CONFIG, &wdata, 0x01));
wdata = PAH8001_R_CONFIG_POWERDOWN_Msk | 2U;
PAH8001_ERROR_CHECK(pah->ops.write(pah->pdev, PAH8001_R_CONFIG, &wdata, 0x01));
return PAH_RET_OK;
}
pah_ret_t pah8001_init(pah_t *pah) {
PAH8001_ERROR_CHECK(pah->ops.init(pah->pdev));
PAH8001_ERROR_CHECK(pah8001_reset(pah));
return PAH_RET_OK;
}

View File

@ -5,6 +5,21 @@
#include "fsl_debug_console.h"
#include "pixart_pah8001ei.h"
pah_ret_t pah8001_impl_init(void *pdev);
pah_ret_t pah8001_impl_write(void *pdev, uint8_t reg, uint8_t *value, uint16_t len);
pah_ret_t pah8001_impl_read(void *pdev, uint8_t reg, uint8_t *value, uint16_t len);
pah_t s_pah = {
.ops = {
.init = pah8001_impl_init,
.write = pah8001_impl_write,
.read = pah8001_impl_read,
},
.pdev = NULL,
};
int main(void) {
BOARD_InitBootPins();
BOARD_BootClockRUN();
@ -14,6 +29,8 @@ int main(void) {
PRINTF("Hello world!!\r\n");
pah8001_init(&s_pah);
for(;;) {
__WFI();
}

55
src/pah8001_impl.c Normal file
View File

@ -0,0 +1,55 @@
#include "fsl_i2c.h"
#include "pixart_pah8001ei.h"
#define PAH8001_SLAVE_ADDRESS 0x33
#define PAH8001_I2C_INSTANCE I2C0
pah_ret_t pah8001_impl_init(void *pdev) {
/* I2C initialization by tool. */
return PAH_RET_OK;
}
pah_ret_t pah8001_impl_write(void *pdev, uint8_t reg, uint8_t *value, uint16_t len) {
i2c_master_transfer_t xfer = {
.slaveAddress = PAH8001_SLAVE_ADDRESS,
.subaddress = reg,
.subaddressSize = 1U,
.direction = kI2C_Write,
.data = value,
.dataSize = len,
.flags = kI2C_TransferDefaultFlag,
};
if (I2C_MasterTransferBlocking(PAH8001_I2C_INSTANCE, &xfer) != kStatus_Success) {
return PAH_RET_FAIL;
}
if(I2C_MasterStop(PAH8001_I2C_INSTANCE) != kStatus_Success) {
return PAH_RET_FAIL;
}
return PAH_RET_OK;
}
pah_ret_t pah8001_impl_read(void *pdev, uint8_t reg, uint8_t *value, uint16_t len) {
i2c_master_transfer_t xfer = {
.slaveAddress = PAH8001_SLAVE_ADDRESS,
.subaddress = reg,
.subaddressSize = 1U,
.direction = kI2C_Read,
.data = value,
.dataSize = len,
.flags = kI2C_TransferDefaultFlag,
};
if (I2C_MasterTransferBlocking(I2C0, &xfer) != kStatus_Success) {
return PAH_RET_FAIL;
}
if(I2C_MasterStop(PAH8001_I2C_INSTANCE) != kStatus_Success) {
return PAH_RET_FAIL;
}
return PAH_RET_OK;
}