From 256cb0eaceff17d56d0a30200707dd69d8179564 Mon Sep 17 00:00:00 2001 From: imi415 Date: Wed, 20 Jul 2022 00:10:20 +0800 Subject: [PATCH] Added PixArt sensor. --- CMakeLists.txt | 3 + LPC54102J512_M4F.mex | 49 ++++++++++++++++- board/peripherals.c | 36 ++++++++++++ board/peripherals.h | 16 ++++++ board/pin_mux.c | 26 +++++++++ board/pin_mux.h | 12 ++-- lib/pixart_pah8001ei/CMakeLists.txt | 14 +++++ .../include/pixart_pah8001ei.h | 29 ++++++++++ lib/pixart_pah8001ei/src/pixart_pah8001ei.c | 27 +++++++++ src/main.c | 17 ++++++ src/pah8001_impl.c | 55 +++++++++++++++++++ 11 files changed, 279 insertions(+), 5 deletions(-) create mode 100644 lib/pixart_pah8001ei/CMakeLists.txt create mode 100644 lib/pixart_pah8001ei/include/pixart_pah8001ei.h create mode 100644 lib/pixart_pah8001ei/src/pixart_pah8001ei.c create mode 100644 src/pah8001_impl.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 67906f8..c673f5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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}) diff --git a/LPC54102J512_M4F.mex b/LPC54102J512_M4F.mex index f3a6acb..e6eebbb 100644 --- a/LPC54102J512_M4F.mex +++ b/LPC54102J512_M4F.mex @@ -40,6 +40,11 @@ true + + + true + + true @@ -49,6 +54,8 @@ + + @@ -117,6 +124,18 @@ + + + + true + + + + + 2.0.2 + + + @@ -128,7 +147,23 @@ - + + + + true + + + + + true + + + + + 0 + + + @@ -136,6 +171,18 @@ + + + + + + + + + + + + diff --git a/board/peripherals.c b/board/peripherals.c index 1f9bd43..03401de 100644 --- a/board/peripherals.c +++ b/board/peripherals.c @@ -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(); } /*********************************************************************************************************************** diff --git a/board/peripherals.h b/board/peripherals.h index 2a75809..2a6ff44 100644 --- a/board/peripherals.h +++ b/board/peripherals.h @@ -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 **********************************************************************************************************************/ diff --git a/board/pin_mux.c b/board/pin_mux.c index 92768d4..1718c18 100644 --- a/board/pin_mux.c +++ b/board/pin_mux.c @@ -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 diff --git a/board/pin_mux.h b/board/pin_mux.h index d1a077e..13f637c 100644 --- a/board/pin_mux.h +++ b/board/pin_mux.h @@ -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. diff --git a/lib/pixart_pah8001ei/CMakeLists.txt b/lib/pixart_pah8001ei/CMakeLists.txt new file mode 100644 index 0000000..601e992 --- /dev/null +++ b/lib/pixart_pah8001ei/CMakeLists.txt @@ -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}) \ No newline at end of file diff --git a/lib/pixart_pah8001ei/include/pixart_pah8001ei.h b/lib/pixart_pah8001ei/include/pixart_pah8001ei.h new file mode 100644 index 0000000..171b572 --- /dev/null +++ b/lib/pixart_pah8001ei/include/pixart_pah8001ei.h @@ -0,0 +1,29 @@ +#ifndef PIXART_PAH8001EI_H +#define PIXART_PAH8001EI_H + +#include +#include + +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 \ No newline at end of file diff --git a/lib/pixart_pah8001ei/src/pixart_pah8001ei.c b/lib/pixart_pah8001ei/src/pixart_pah8001ei.c new file mode 100644 index 0000000..9881d14 --- /dev/null +++ b/lib/pixart_pah8001ei/src/pixart_pah8001ei.c @@ -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; +} \ No newline at end of file diff --git a/src/main.c b/src/main.c index 029076f..fe03676 100644 --- a/src/main.c +++ b/src/main.c @@ -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(); } diff --git a/src/pah8001_impl.c b/src/pah8001_impl.c new file mode 100644 index 0000000..5301bd2 --- /dev/null +++ b/src/pah8001_impl.c @@ -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; +} \ No newline at end of file