diff --git a/arch/arm/src/am335x/Kconfig b/arch/arm/src/am335x/Kconfig index 43c2de66537..c37ab91713d 100644 --- a/arch/arm/src/am335x/Kconfig +++ b/arch/arm/src/am335x/Kconfig @@ -98,6 +98,7 @@ config AM335X_LCDC bool "LCD controller" default n depends on VIDEO && EXPERIMENTAL + select LCD select VIDEO_EDID config AM335X_TSC @@ -274,21 +275,6 @@ config AM335X_LCDC_FB_SIZE ---help--- Size of the video RAM frame buffer. Default: 1Mb. -config AM335X_LCDC_USE_CLKIN - bool "Use optional input clock" - default n - -config AM335X_LCDC_CLKIN_FREQUENCY - int "Input clock frequency" - default 0 - depends on AM335X_LCDC_USE_CLKIN - -config AM335X_LCDC_REFRESH_FREQ - int "LCD refesh rate (Hz)" - default 50 - ---help--- - LCD refesh rate (Hz) - choice prompt "Bits per pixel" default AM335X_LCDC_BPP16_565 @@ -319,13 +305,6 @@ config AM335X_LCDC_BPP32 endchoice -config AM335X_LCDC_BGR - bool "Blue-Green-Red color order" - default n - depends on !AM335X_LCDC_MONOCHROME - ---help--- - This option selects BGR color order vs. default RGB - config AM335X_LCDC_BACKCOLOR hex "Initial background color" default 0x0 diff --git a/arch/arm/src/am335x/am335x_clockconfig.c b/arch/arm/src/am335x/am335x_clockconfig.c index 50e8a8b7f80..380c07fe7b2 100644 --- a/arch/arm/src/am335x/am335x_clockconfig.c +++ b/arch/arm/src/am335x/am335x_clockconfig.c @@ -40,7 +40,7 @@ #include #include "up_arch.h" -#include "hardware/am335x_cm.h" +#include "hardware/am335x_prcm.h" #include "am335x_config.h" #include "am335x_clockconfig.h" diff --git a/arch/arm/src/am335x/am335x_edid.c b/arch/arm/src/am335x/am335x_edid.c index 1d5aed8d177..fd4d226e80a 100644 --- a/arch/arm/src/am335x/am335x_edid.c +++ b/arch/arm/src/am335x/am335x_edid.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/am335x/am335x_wdog.c + * arch/arm/src/am335x/am335x_edid.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -82,7 +82,7 @@ ****************************************************************************/ static uint32_t - am335x_videomode_vrefresh(FAR const struct edid_videomode_s *videomode) + am335x_videomode_vrefresh(FAR const struct videomode_s *videomode) { uint32_t refresh; @@ -113,7 +113,7 @@ static uint32_t ****************************************************************************/ static bool - am335x_videomode_valid(FAR const struct edid_videomode_s *videomode) + am335x_videomode_valid(FAR const struct videomode_s *videomode) { size_t fbstride; size_t fbsize; @@ -216,10 +216,10 @@ static bool * ****************************************************************************/ -static const struct edid_videomode_s * +static const struct videomode_s * am335x_lcd_pickmode(FAR struct edid_info_s *ei) { - FAR const struct edid_videomode_s *videomode; + FAR const struct videomode_s *videomode; int n; /* Get standard VGA as default */ @@ -242,7 +242,7 @@ static const struct edid_videomode_s * * are sorted on closest match to that mode. */ - edid_sort_modes(ei->edid_modes, &ei->edid_preferred_mode, ei->edid_nmodes); + sort_videomodes(ei->edid_modes, &ei->edid_preferred_mode, ei->edid_nmodes); /* Pick the first valid mode in the list */ @@ -280,7 +280,7 @@ static const struct edid_videomode_s * * ****************************************************************************/ -void am335x_lcd_videomode(FAR const struct edid_videomode_s *videomode, +void am335x_lcd_videomode(FAR const struct videomode_s *videomode, FAR struct am335x_panel_info_s *panel) { lcdinfo("Detected videomode: %dx%d @ %dKHz\n", @@ -355,9 +355,9 @@ void am335x_lcd_videomode(FAR const struct edid_videomode_s *videomode, void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len, FAR struct am335x_panel_info_s *panel, - FAR struct edid_videomode_s *selected) + FAR const struct videomode_s **selected) { - FAR const struct edid_videomode_s *videomode = NULL; + FAR const struct videomode_s *videomode = NULL; struct edid_info_s ei; /* Do we have EDID data? */ @@ -380,7 +380,7 @@ void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len, if (videomode == NULL) { - videomode = edid_mode_lookup("640x480x60"); + videomode = videomode_lookup_by_name("640x480x60"); DEBUGASSERT(videomode != NULL); } @@ -392,6 +392,6 @@ void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len, if (selected != NULL) { - memcpy(selected, videomode, sizeof(struct edid_videomode_s)); + *selected = videomode; } } diff --git a/arch/arm/src/am335x/am335x_gpio.h b/arch/arm/src/am335x/am335x_gpio.h index b2f74107024..8cb6c94f3ff 100644 --- a/arch/arm/src/am335x/am335x_gpio.h +++ b/arch/arm/src/am335x/am335x_gpio.h @@ -45,7 +45,7 @@ #include #include -#include "hardware/am335x_control.h" +#include "hardware/am335x_scm.h" #include "hardware/am335x_gpio.h" /************************************************************************************ diff --git a/arch/arm/src/am335x/am335x_lcdc.c b/arch/arm/src/am335x/am335x_lcdc.c index f629ed932ad..aebca6d358d 100644 --- a/arch/arm/src/am335x/am335x_lcdc.c +++ b/arch/arm/src/am335x/am335x_lcdc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * arch/arm/src/am225x/am335x_lcd.c + * arch/arm/src/am225x/am335x_lcdc.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -56,7 +56,7 @@ #include #include "up_arch.h" -#include "hardware/am335x_cm.h" +#include "hardware/am335x_prcm.h" #include "am335x_pinmux.h" #include "am335x_config.h" #include "am335x_gpio.h" diff --git a/arch/arm/src/am335x/am335x_lcdc.h b/arch/arm/src/am335x/am335x_lcdc.h index 03a59663d1a..79e63943f3c 100644 --- a/arch/arm/src/am335x/am335x_lcdc.h +++ b/arch/arm/src/am335x/am335x_lcdc.h @@ -251,9 +251,9 @@ void am335x_lcdclear(nxgl_mxpixel_t color); * ****************************************************************************/ -struct edid_videomode_s; /* Forward reference */ +struct videomode_s; /* Forward reference */ -void am335x_lcd_videomode(FAR const struct edid_videomode_s *videomode, +void am335x_lcd_videomode(FAR const struct videomode_s *videomode, FAR struct am335x_panel_info_s *panel); /**************************************************************************** @@ -281,7 +281,7 @@ void am335x_lcd_videomode(FAR const struct edid_videomode_s *videomode, void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len, FAR struct am335x_panel_info_s *panel, - FAR struct edid_videomode_s *selected); + FAR const struct videomode_s **selected); /**************************************************************************** * Name: am335x_backlight diff --git a/arch/arm/src/am335x/am335x_pinmux.h b/arch/arm/src/am335x/am335x_pinmux.h index 70c5fa00671..d4de8afc457 100644 --- a/arch/arm/src/am335x/am335x_pinmux.h +++ b/arch/arm/src/am335x/am335x_pinmux.h @@ -42,7 +42,7 @@ #include -#include "hardware/am335x_control.h" +#include "hardware/am335x_scm.h" #include "hardware/am335x_pinmux.h" /**************************************************************************** diff --git a/arch/arm/src/am335x/am335x_sysclk.c b/arch/arm/src/am335x/am335x_sysclk.c index b812d37ae8d..a575ad04b62 100644 --- a/arch/arm/src/am335x/am335x_sysclk.c +++ b/arch/arm/src/am335x/am335x_sysclk.c @@ -43,24 +43,13 @@ #include #include "up_arch.h" -#include "hardware/am335x_memorymap.h" +#include "hardware/am335x_scm.h" #include "am335x_sysclk.h" /**************************************************************************** * Pre-processor definitions ****************************************************************************/ -/* REVISIT: These belong in a control module register header file */ - -#define AM335X_SCM_CTRL_STATUS_OFFSET 0x40 -#define AM335X_SCM_CTRL_STATUS (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_CTRL_STATUS_OFFSET) -#define SCM_CTRL_STATUS_SYSBOOT1_SHIFT (22) /* Bits 22-23: Crystal clock frequency selection */ -#define SCM_CTRL_STATUS_SYSBOOT1_MASK (3 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) -# define SCM_CTRL_STATUS_SYSBOOT1_19p2MHZ (0 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) -# define SCM_CTRL_STATUS_SYSBOOT1_24MHZ (1 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) -# define SCM_CTRL_STATUS_SYSBOOT1_25MHZ (2 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) -# define SCM_CTRL_STATUS_SYSBOOT1_26MHZ (3 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) - /**************************************************************************** * Public Functions ****************************************************************************/ diff --git a/arch/arm/src/am335x/hardware/am335x_dcan.h b/arch/arm/src/am335x/hardware/am335x_dcan.h index e8c6e803077..3fdee9ca83c 100644 --- a/arch/arm/src/am335x/hardware/am335x_dcan.h +++ b/arch/arm/src/am335x/hardware/am335x_dcan.h @@ -1,5 +1,5 @@ /******************************************************************************************** - * arch/arm/src/am335x/hardware/am335x_cm.h + * arch/arm/src/am335x/hardware/am335x_dcan.h * * Copyright (C) 2019 Petro Karashchenko. All rights reserved. * Author: Petro Karashchenko diff --git a/arch/arm/src/am335x/hardware/am335x_cm.h b/arch/arm/src/am335x/hardware/am335x_prcm.h similarity index 99% rename from arch/arm/src/am335x/hardware/am335x_cm.h rename to arch/arm/src/am335x/hardware/am335x_prcm.h index 1618daaf4ba..933f2b3b953 100644 --- a/arch/arm/src/am335x/hardware/am335x_cm.h +++ b/arch/arm/src/am335x/hardware/am335x_prcm.h @@ -1,5 +1,5 @@ /******************************************************************************************** - * arch/arm/src/am335x/hardware/am335x_cm.h + * arch/arm/src/am335x/hardware/am335x_prcm.h * * Copyright (C) 2019 Petro Karashchenko. All rights reserved. * Author: Petro Karashchenko @@ -33,8 +33,8 @@ * ********************************************************************************************/ -#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CM_H -#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CM_H +#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_PRCM_H +#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_PRCM_H /******************************************************************************************** * Included Files @@ -365,4 +365,4 @@ # define CM_DPLL_DMTIMER1_CLKSEL_CLK_RC32K (3 << CM_DPLL_DMTIMER1MS_CLKSEL_SHIFT) /* Select CLK_RC32K clock */ # define CM_DPLL_DMTIMER1_CLKSEL_CLK_32768 (4 << CM_DPLL_DMTIMER1MS_CLKSEL_SHIFT) /* Selects the CLK_32768 from 32KHz Crystal Osc */ -#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CM_H */ +#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_PRCM_H */ diff --git a/arch/arm/src/am335x/hardware/am335x_control.h b/arch/arm/src/am335x/hardware/am335x_scm.h similarity index 59% rename from arch/arm/src/am335x/hardware/am335x_control.h rename to arch/arm/src/am335x/hardware/am335x_scm.h index 44ae78be6f6..d5ffac612b2 100644 --- a/arch/arm/src/am335x/hardware/am335x_control.h +++ b/arch/arm/src/am335x/hardware/am335x_scm.h @@ -1,5 +1,5 @@ /******************************************************************************************** - * arch/arm/src/am335x/hardware/am335x_control.h + * arch/arm/src/am335x/hardware/am335x_scm.h * * Copyright (C) 2018 Petro Karashchenko. All rights reserved. * Author: Petro Karashchenko @@ -33,8 +33,8 @@ * ********************************************************************************************/ -#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CONTROL_H -#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CONTROL_H +#ifndef __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_SCM_H +#define __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_SCM_H /******************************************************************************************** * Included Files @@ -49,95 +49,95 @@ /* Control Module Register Offsets **********************************************************/ -#define AM335X_CONTROL_SYS_CONF_OFFSET 0x0010 -#define AM335X_CONTROL_STATUS_OFFSET 0x0040 -#define AM335X_CONTROL_EMIF_SDRAM_CONF_OFFSET 0x0110 -#define AM335X_CORE_SLDO_CTRL_OFFSET 0x0428 -#define AM335X_MPU_SLDO_CTRL_OFFSET 0x042C -#define AM335X_CLK32KDIVRATIO_CTRL_OFFSET 0x0444 -#define AM335X_BANDGAP_CTRL_OFFSET 0x0448 -#define AM335X_BANDGAP_TRIM_OFFSET 0x044C -#define AM335X_PLL_CLKINPULOW_CTRL_OFFSET 0x0458 -#define AM335X_MOSC_CTRL_OFFSET 0x0468 -#define AM335X_DEEPSLEEP_CTRL_OFFSET 0x0470 -#define AM335X_DPLL_PWR_SW_STATUS_OFFSET 0x050C -#define AM335X_DEVICE_ID_OFFSET 0x0600 -#define AM335X_DEV_FEATURE_OFFSET 0x0604 -#define AM335X_INIT_PRIORITY_0_OFFSET 0x0608 -#define AM335X_INIT_PRIORITY_1_OFFSET 0x060C -#define AM335X_TPTC_CFG_OFFSET 0x0614 -#define AM335X_USB_CTRL0_OFFSET 0x0620 -#define AM335X_USB_STS0_OFFSET 0x0624 -#define AM335X_USB_CTRL1_OFFSET 0x0628 -#define AM335X_USB_STS1_OFFSET 0x062C -#define AM335X_MAC_ID0_LO_OFFSET 0x0630 -#define AM335X_MAC_ID0_HI_OFFSET 0x0634 -#define AM335X_MAC_ID1_LO_OFFSET 0x0638 -#define AM335X_MAC_ID1_HI_OFFSET 0x063C -#define AM335X_DCAN_RAMINIT_OFFSET 0x0644 -#define AM335X_USB_WKUP_CTRL_OFFSET 0x0648 -#define AM335X_GMII_SEL_OFFSET 0x0650 -#define AM335X_PWMSS_CTRL_OFFSET 0x0664 -#define AM335X_MREGPRIO_0_OFFSET 0x0670 -#define AM335X_MREGPRIO_1_OFFSET 0x0674 -#define AM335X_HW_EVENT_SEL_GRP1_OFFSET 0x0690 -#define AM335X_HW_EVENT_SEL_GRP2_OFFSET 0x0694 -#define AM335X_HW_EVENT_SEL_GRP3_OFFSET 0x0698 -#define AM335X_HW_EVENT_SEL_GRP4_OFFSET 0x069C -#define AM335X_SMRT_CTRL_OFFSET 0x06A0 -#define AM335X_MPUSS_HW_DEBUG_SEL_OFFSET 0x06A4 -#define AM335X_MPUSS_HW_DBG_INFO_OFFSET 0x06A8 -#define AM335X_VDD_MPU_OPP_050_OFFSET 0x0770 -#define AM335X_VDD_MPU_OPP_100_OFFSET 0x0774 -#define AM335X_VDD_MPU_OPP_120_OFFSET 0x0778 -#define AM335X_VDD_MPU_OPP_TURBO_OFFSET 0x077C -#define AM335X_VDD_CORE_OPP_050_OFFSET 0x07B8 -#define AM335X_VDD_CORE_OPP_100_OFFSET 0x07BC -#define AM335X_BB_SCALE_OFFSET 0x07D0 -#define AM335X_USB_VID_PID_OFFSET 0x07F4 -#define AM335X_EFUSE_SMA_OFFSET 0x07FC +#define AM335X_SCM_CTRL_SYS_CONF_OFFSET 0x0010 +#define AM335X_SCM_CTRL_STATUS_OFFSET 0x0040 +#define AM335X_SCM_CTRL_EMIF_SDRAM_CONF_OFFSET 0x0110 +#define AM335X_SCM_CORE_SLDO_CTRL_OFFSET 0x0428 +#define AM335X_SCM_MPU_SLDO_CTRL_OFFSET 0x042c +#define AM335X_SCM_CLK32KDIVRATIO_CTRL_OFFSET 0x0444 +#define AM335X_SCM_BANDGAP_CTRL_OFFSET 0x0448 +#define AM335X_SCM_BANDGAP_TRIM_OFFSET 0x044c +#define AM335X_SCM_PLL_CLKINPULOW_CTRL_OFFSET 0x0458 +#define AM335X_SCM_MOSC_CTRL_OFFSET 0x0468 +#define AM335X_SCM_DEEPSLEEP_CTRL_OFFSET 0x0470 +#define AM335X_SCM_DPLL_PWR_SW_STATUS_OFFSET 0x050c +#define AM335X_SCM_DEVICE_ID_OFFSET 0x0600 +#define AM335X_SCM_DEV_FEATURE_OFFSET 0x0604 +#define AM335X_SCM_INIT_PRIORITY_0_OFFSET 0x0608 +#define AM335X_SCM_INIT_PRIORITY_1_OFFSET 0x060c +#define AM335X_SCM_TPTC_CFG_OFFSET 0x0614 +#define AM335X_SCM_USB_CTRL0_OFFSET 0x0620 +#define AM335X_SCM_USB_STS0_OFFSET 0x0624 +#define AM335X_SCM_USB_CTRL1_OFFSET 0x0628 +#define AM335X_SCM_USB_STS1_OFFSET 0x062c +#define AM335X_SCM_MAC_ID0_LO_OFFSET 0x0630 +#define AM335X_SCM_MAC_ID0_HI_OFFSET 0x0634 +#define AM335X_SCM_MAC_ID1_LO_OFFSET 0x0638 +#define AM335X_SCM_MAC_ID1_HI_OFFSET 0x063c +#define AM335X_SCM_DCAN_RAMINIT_OFFSET 0x0644 +#define AM335X_SCM_USB_WKUP_CTRL_OFFSET 0x0648 +#define AM335X_SCM_GMII_SEL_OFFSET 0x0650 +#define AM335X_SCM_PWMSS_CTRL_OFFSET 0x0664 +#define AM335X_SCM_MREGPRIO_0_OFFSET 0x0670 +#define AM335X_SCM_MREGPRIO_1_OFFSET 0x0674 +#define AM335X_SCM_HW_EVENT_SEL_GRP1_OFFSET 0x0690 +#define AM335X_SCM_HW_EVENT_SEL_GRP2_OFFSET 0x0694 +#define AM335X_SCM_HW_EVENT_SEL_GRP3_OFFSET 0x0698 +#define AM335X_SCM_HW_EVENT_SEL_GRP4_OFFSET 0x069c +#define AM335X_SCM_SMRT_CTRL_OFFSET 0x06a0 +#define AM335X_SCM_MPUSS_HW_DEBUG_SEL_OFFSET 0x06a4 +#define AM335X_SCM_MPUSS_HW_DBG_INFO_OFFSET 0x06a8 +#define AM335X_SCM_VDD_MPU_OPP_050_OFFSET 0x0770 +#define AM335X_SCM_VDD_MPU_OPP_100_OFFSET 0x0774 +#define AM335X_SCM_VDD_MPU_OPP_120_OFFSET 0x0778 +#define AM335X_SCM_VDD_MPU_OPP_TURBO_OFFSET 0x077c +#define AM335X_SCM_VDD_CORE_OPP_050_OFFSET 0x07b8 +#define AM335X_SCM_VDD_CORE_OPP_100_OFFSET 0x07bc +#define AM335X_SCM_BB_SCALE_OFFSET 0x07d0 +#define AM335X_SCM_USB_VID_PID_OFFSET 0x07f4 +#define AM335X_SCM_EFUSE_SMA_OFFSET 0x07fc -#define AM335X_CQDETECT_STATUS_OFFSET 0x0E00 -#define AM335X_DDR_IO_CTRL_OFFSET 0x0E04 -#define AM335X_VTP_CTRL_OFFSET 0x0E0C -#define AM335X_VREF_CTRL_OFFSET 0x0E14 -#define AM335X_TPCC_EVT_MUX_0_3_OFFSET 0x0F90 -#define AM335X_TPCC_EVT_MUX_4_7_OFFSET 0x0F94 -#define AM335X_TPCC_EVT_MUX_8_11_OFFSET 0x0F98 -#define AM335X_TPCC_EVT_MUX_12_15_OFFSET 0x0F9C -#define AM335X_TPCC_EVT_MUX_16_19_OFFSET 0x0FA0 -#define AM335X_TPCC_EVT_MUX_20_23_OFFSET 0x0FA4 -#define AM335X_TPCC_EVT_MUX_24_27_OFFSET 0x0FA8 -#define AM335X_TPCC_EVT_MUX_28_31_OFFSET 0x0FAC -#define AM335X_TPCC_EVT_MUX_32_35_OFFSET 0x0FB0 -#define AM335X_TPCC_EVT_MUX_36_39_OFFSET 0x0FB4 -#define AM335X_TPCC_EVT_MUX_40_43_OFFSET 0x0FB8 -#define AM335X_TPCC_EVT_MUX_44_47_OFFSET 0x0FBC -#define AM335X_TPCC_EVT_MUX_48_51_OFFSET 0x0FC0 -#define AM335X_TPCC_EVT_MUX_52_55_OFFSET 0x0FC4 -#define AM335X_TPCC_EVT_MUX_56_59_OFFSET 0x0FC8 -#define AM335X_TPCC_EVT_MUX_60_63_OFFSET 0x0FCC -#define AM335X_TIMER_EVT_CAPT_OFFSET 0x0FD0 -#define AM335X_ECAP_EVT_CAPT_OFFSET 0x0FD4 -#define AM335X_ADC_EVT_CAPT_OFFSET 0x0FD8 -#define AM335X_RESET_ISO_OFFSET 0x1000 -#define AM335X_DPLL_PWR_SW_CTRL_OFFSET 0x1318 -#define AM335X_DDR_CKE_CTRL_OFFSET 0x131C -#define AM335X_SMA2_OFFSET 0x1320 -#define AM335X_M3_TXEV_EOI_OFFSET 0x1324 -#define AM335X_IPC_MSG_REG0_OFFSET 0x1328 -#define AM335X_IPC_MSG_REG1_OFFSET 0x132C -#define AM335X_IPC_MSG_REG2_OFFSET 0x1330 -#define AM335X_IPC_MSG_REG3_OFFSET 0x1334 -#define AM335X_IPC_MSG_REG4_OFFSET 0x1338 -#define AM335X_IPC_MSG_REG5_OFFSET 0x133C -#define AM335X_IPC_MSG_REG6_OFFSET 0x1340 -#define AM335X_IPC_MSG_REG7_OFFSET 0x1344 -#define AM335X_DDR_CMD0_IOCTRL_OFFSET 0x1404 -#define AM335X_DDR_CMD1_IOCTRL_OFFSET 0x1408 -#define AM335X_DDR_CMD2_IOCTRL_OFFSET 0x140C -#define AM335X_DDR_DATA0_IOCTRL_OFFSET 0x1440 -#define AM335X_DDR_DATA1_IOCTRL_OFFSET 0x1444 +#define AM335X_SCM_CQDETECT_STATUS_OFFSET 0x0e00 +#define AM335X_SCM_DDR_IO_CTRL_OFFSET 0x0e04 +#define AM335X_SCM_VTP_CTRL_OFFSET 0x0e0c +#define AM335X_SCM_VREF_CTRL_OFFSET 0x0e14 +#define AM335X_SCM_TPCC_EVT_MUX_0_3_OFFSET 0x0f90 +#define AM335X_SCM_TPCC_EVT_MUX_4_7_OFFSET 0x0f94 +#define AM335X_SCM_TPCC_EVT_MUX_8_11_OFFSET 0x0f98 +#define AM335X_SCM_TPCC_EVT_MUX_12_15_OFFSET 0x0f9c +#define AM335X_SCM_TPCC_EVT_MUX_16_19_OFFSET 0x0fa0 +#define AM335X_SCM_TPCC_EVT_MUX_20_23_OFFSET 0x0fa4 +#define AM335X_SCM_TPCC_EVT_MUX_24_27_OFFSET 0x0fa8 +#define AM335X_SCM_TPCC_EVT_MUX_28_31_OFFSET 0x0fac +#define AM335X_SCM_TPCC_EVT_MUX_32_35_OFFSET 0x0fb0 +#define AM335X_SCM_TPCC_EVT_MUX_36_39_OFFSET 0x0fb4 +#define AM335X_SCM_TPCC_EVT_MUX_40_43_OFFSET 0x0fb8 +#define AM335X_SCM_TPCC_EVT_MUX_44_47_OFFSET 0x0fbc +#define AM335X_SCM_TPCC_EVT_MUX_48_51_OFFSET 0x0fc0 +#define AM335X_SCM_TPCC_EVT_MUX_52_55_OFFSET 0x0fc4 +#define AM335X_SCM_TPCC_EVT_MUX_56_59_OFFSET 0x0fc8 +#define AM335X_SCM_TPCC_EVT_MUX_60_63_OFFSET 0x0fcc +#define AM335X_SCM_TIMER_EVT_CAPT_OFFSET 0x0fd0 +#define AM335X_SCM_ECAP_EVT_CAPT_OFFSET 0x0fd4 +#define AM335X_SCM_ADC_EVT_CAPT_OFFSET 0x0fd8 +#define AM335X_SCM_RESET_ISO_OFFSET 0x1000 +#define AM335X_SCM_DPLL_PWR_SW_CTRL_OFFSET 0x1318 +#define AM335X_SCM_DDR_CKE_CTRL_OFFSET 0x131c +#define AM335X_SCM_SMA2_OFFSET 0x1320 +#define AM335X_SCM_M3_TXEV_EOI_OFFSET 0x1324 +#define AM335X_SCM_IPC_MSG_REG0_OFFSET 0x1328 +#define AM335X_SCM_IPC_MSG_REG1_OFFSET 0x132c +#define AM335X_SCM_IPC_MSG_REG2_OFFSET 0x1330 +#define AM335X_SCM_IPC_MSG_REG3_OFFSET 0x1334 +#define AM335X_SCM_IPC_MSG_REG4_OFFSET 0x1338 +#define AM335X_SCM_IPC_MSG_REG5_OFFSET 0x133c +#define AM335X_SCM_IPC_MSG_REG6_OFFSET 0x1340 +#define AM335X_SCM_IPC_MSG_REG7_OFFSET 0x1344 +#define AM335X_SCM_DDR_CMD0_IOCTRL_OFFSET 0x1404 +#define AM335X_SCM_DDR_CMD1_IOCTRL_OFFSET 0x1408 +#define AM335X_SCM_DDR_CMD2_IOCTRL_OFFSET 0x140c +#define AM335X_SCM_DDR_DATA0_IOCTRL_OFFSET 0x1440 +#define AM335X_SCM_DDR_DATA1_IOCTRL_OFFSET 0x1444 /* Pad Control Registers */ /* Pad Control Register Indices (used by software for table lookups) */ @@ -277,220 +277,220 @@ #define AM335X_PADCTL_GPMC_AD0_OFFSET 0x0800 #define AM335X_PADCTL_GPMC_AD1_OFFSET 0x0804 #define AM335X_PADCTL_GPMC_AD2_OFFSET 0x0808 -#define AM335X_PADCTL_GPMC_AD3_OFFSET 0x080C +#define AM335X_PADCTL_GPMC_AD3_OFFSET 0x080c #define AM335X_PADCTL_GPMC_AD4_OFFSET 0x0810 #define AM335X_PADCTL_GPMC_AD5_OFFSET 0x0814 #define AM335X_PADCTL_GPMC_AD6_OFFSET 0x0818 -#define AM335X_PADCTL_GPMC_AD7_OFFSET 0x081C +#define AM335X_PADCTL_GPMC_AD7_OFFSET 0x081c #define AM335X_PADCTL_GPMC_AD8_OFFSET 0x0820 #define AM335X_PADCTL_GPMC_AD9_OFFSET 0x0824 #define AM335X_PADCTL_GPMC_AD10_OFFSET 0x0828 -#define AM335X_PADCTL_GPMC_AD11_OFFSET 0x082C +#define AM335X_PADCTL_GPMC_AD11_OFFSET 0x082c #define AM335X_PADCTL_GPMC_AD12_OFFSET 0x0830 #define AM335X_PADCTL_GPMC_AD13_OFFSET 0x0834 #define AM335X_PADCTL_GPMC_AD14_OFFSET 0x0838 -#define AM335X_PADCTL_GPMC_AD15_OFFSET 0x083C +#define AM335X_PADCTL_GPMC_AD15_OFFSET 0x083c #define AM335X_PADCTL_GPMC_A0_OFFSET 0x0840 #define AM335X_PADCTL_GPMC_A1_OFFSET 0x0844 #define AM335X_PADCTL_GPMC_A2_OFFSET 0x0848 -#define AM335X_PADCTL_GPMC_A3_OFFSET 0x084C +#define AM335X_PADCTL_GPMC_A3_OFFSET 0x084c #define AM335X_PADCTL_GPMC_A4_OFFSET 0x0850 #define AM335X_PADCTL_GPMC_A5_OFFSET 0x0854 #define AM335X_PADCTL_GPMC_A6_OFFSET 0x0858 -#define AM335X_PADCTL_GPMC_A7_OFFSET 0x085C +#define AM335X_PADCTL_GPMC_A7_OFFSET 0x085c #define AM335X_PADCTL_GPMC_A8_OFFSET 0x0860 #define AM335X_PADCTL_GPMC_A9_OFFSET 0x0864 #define AM335X_PADCTL_GPMC_A10_OFFSET 0x0868 -#define AM335X_PADCTL_GPMC_A11_OFFSET 0x086C +#define AM335X_PADCTL_GPMC_A11_OFFSET 0x086c #define AM335X_PADCTL_GPMC_WAIT0_OFFSET 0x0870 #define AM335X_PADCTL_GPMC_WPN_OFFSET 0x0874 #define AM335X_PADCTL_GPMC_BEN1_OFFSET 0x0878 -#define AM335X_PADCTL_GPMC_CSN0_OFFSET 0x087C +#define AM335X_PADCTL_GPMC_CSN0_OFFSET 0x087c #define AM335X_PADCTL_GPMC_CSN1_OFFSET 0x0880 #define AM335X_PADCTL_GPMC_CSN2_OFFSET 0x0884 #define AM335X_PADCTL_GPMC_CSN3_OFFSET 0x0888 -#define AM335X_PADCTL_GPMC_CLK_OFFSET 0x088C +#define AM335X_PADCTL_GPMC_CLK_OFFSET 0x088c #define AM335X_PADCTL_GPMC_ADVN_ALE_OFFSET 0x0890 #define AM335X_PADCTL_GPMC_OEN_REN_OFFSET 0x0894 #define AM335X_PADCTL_GPMC_WEN_OFFSET 0x0898 -#define AM335X_PADCTL_GPMC_BEN0_CLE_OFFSET 0x089C -#define AM335X_PADCTL_LCD_DATA0_OFFSET 0x08A0 -#define AM335X_PADCTL_LCD_DATA1_OFFSET 0x08A4 -#define AM335X_PADCTL_LCD_DATA2_OFFSET 0x08A8 -#define AM335X_PADCTL_LCD_DATA3_OFFSET 0x08AC -#define AM335X_PADCTL_LCD_DATA4_OFFSET 0x08B0 -#define AM335X_PADCTL_LCD_DATA5_OFFSET 0x08B4 -#define AM335X_PADCTL_LCD_DATA6_OFFSET 0x08B8 -#define AM335X_PADCTL_LCD_DATA7_OFFSET 0x08BC -#define AM335X_PADCTL_LCD_DATA8_OFFSET 0x08C0 -#define AM335X_PADCTL_LCD_DATA9_OFFSET 0x08C4 -#define AM335X_PADCTL_LCD_DATA10_OFFSET 0x08C8 -#define AM335X_PADCTL_LCD_DATA11_OFFSET 0x08CC -#define AM335X_PADCTL_LCD_DATA12_OFFSET 0x08D0 -#define AM335X_PADCTL_LCD_DATA13_OFFSET 0x08D4 -#define AM335X_PADCTL_LCD_DATA14_OFFSET 0x08D8 -#define AM335X_PADCTL_LCD_DATA15_OFFSET 0x08DC -#define AM335X_PADCTL_LCD_VSYNC_OFFSET 0x08E0 -#define AM335X_PADCTL_LCD_HSYNC_OFFSET 0x08E4 -#define AM335X_PADCTL_LCD_PCLK_OFFSET 0x08E8 -#define AM335X_PADCTL_LCD_AC_BIAS_EN_OFFSET 0x08EC -#define AM335X_PADCTL_MMC0_DAT3_OFFSET 0x08F0 -#define AM335X_PADCTL_MMC0_DAT2_OFFSET 0x08F4 -#define AM335X_PADCTL_MMC0_DAT1_OFFSET 0x08F8 -#define AM335X_PADCTL_MMC0_DAT0_OFFSET 0x08FC +#define AM335X_PADCTL_GPMC_BEN0_CLE_OFFSET 0x089c +#define AM335X_PADCTL_LCD_DATA0_OFFSET 0x08a0 +#define AM335X_PADCTL_LCD_DATA1_OFFSET 0x08a4 +#define AM335X_PADCTL_LCD_DATA2_OFFSET 0x08a8 +#define AM335X_PADCTL_LCD_DATA3_OFFSET 0x08ac +#define AM335X_PADCTL_LCD_DATA4_OFFSET 0x08b0 +#define AM335X_PADCTL_LCD_DATA5_OFFSET 0x08b4 +#define AM335X_PADCTL_LCD_DATA6_OFFSET 0x08b8 +#define AM335X_PADCTL_LCD_DATA7_OFFSET 0x08bc +#define AM335X_PADCTL_LCD_DATA8_OFFSET 0x08c0 +#define AM335X_PADCTL_LCD_DATA9_OFFSET 0x08c4 +#define AM335X_PADCTL_LCD_DATA10_OFFSET 0x08c8 +#define AM335X_PADCTL_LCD_DATA11_OFFSET 0x08cc +#define AM335X_PADCTL_LCD_DATA12_OFFSET 0x08d0 +#define AM335X_PADCTL_LCD_DATA13_OFFSET 0x08d4 +#define AM335X_PADCTL_LCD_DATA14_OFFSET 0x08d8 +#define AM335X_PADCTL_LCD_DATA15_OFFSET 0x08dc +#define AM335X_PADCTL_LCD_VSYNC_OFFSET 0x08e0 +#define AM335X_PADCTL_LCD_HSYNC_OFFSET 0x08e4 +#define AM335X_PADCTL_LCD_PCLK_OFFSET 0x08e8 +#define AM335X_PADCTL_LCD_AC_BIAS_EN_OFFSET 0x08ec +#define AM335X_PADCTL_MMC0_DAT3_OFFSET 0x08f0 +#define AM335X_PADCTL_MMC0_DAT2_OFFSET 0x08f4 +#define AM335X_PADCTL_MMC0_DAT1_OFFSET 0x08f8 +#define AM335X_PADCTL_MMC0_DAT0_OFFSET 0x08fc #define AM335X_PADCTL_MMC0_CLK_OFFSET 0x0900 #define AM335X_PADCTL_MMC0_CMD_OFFSET 0x0904 #define AM335X_PADCTL_MII1_COL_OFFSET 0x0908 -#define AM335X_PADCTL_MII1_CRS_OFFSET 0x090C +#define AM335X_PADCTL_MII1_CRS_OFFSET 0x090c #define AM335X_PADCTL_MII1_RX_ER_OFFSET 0x0910 #define AM335X_PADCTL_MII1_TX_EN_OFFSET 0x0914 #define AM335X_PADCTL_MII1_RX_DV_OFFSET 0x0918 -#define AM335X_PADCTL_MII1_TXD3_OFFSET 0x091C +#define AM335X_PADCTL_MII1_TXD3_OFFSET 0x091c #define AM335X_PADCTL_MII1_TXD2_OFFSET 0x0920 #define AM335X_PADCTL_MII1_TXD1_OFFSET 0x0924 #define AM335X_PADCTL_MII1_TXD0_OFFSET 0x0928 -#define AM335X_PADCTL_MII1_TX_CLK_OFFSET 0x092C +#define AM335X_PADCTL_MII1_TX_CLK_OFFSET 0x092c #define AM335X_PADCTL_MII1_RX_CLK_OFFSET 0x0930 #define AM335X_PADCTL_MII1_RXD3_OFFSET 0x0934 #define AM335X_PADCTL_MII1_RXD2_OFFSET 0x0938 -#define AM335X_PADCTL_MII1_RXD1_OFFSET 0x093C +#define AM335X_PADCTL_MII1_RXD1_OFFSET 0x093c #define AM335X_PADCTL_MII1_RXD0_OFFSET 0x0940 #define AM335X_PADCTL_RMII1_REF_CLK_OFFSET 0x0944 #define AM335X_PADCTL_MDIO_OFFSET 0x0948 -#define AM335X_PADCTL_MDC_OFFSET 0x094C +#define AM335X_PADCTL_MDC_OFFSET 0x094c #define AM335X_PADCTL_SPI0_SCLK_OFFSET 0x0950 #define AM335X_PADCTL_SPI0_D0_OFFSET 0x0954 #define AM335X_PADCTL_SPI0_D1_OFFSET 0x0958 -#define AM335X_PADCTL_SPI0_CS0_OFFSET 0x095C +#define AM335X_PADCTL_SPI0_CS0_OFFSET 0x095c #define AM335X_PADCTL_SPI0_CS1_OFFSET 0x0960 #define AM335X_PADCTL_ECAP0_IN_PWM0_OUT_OFFSET 0x0964 #define AM335X_PADCTL_UART0_CTSN_OFFSET 0x0968 -#define AM335X_PADCTL_UART0_RTSN_OFFSET 0x096C +#define AM335X_PADCTL_UART0_RTSN_OFFSET 0x096c #define AM335X_PADCTL_UART0_RXD_OFFSET 0x0970 #define AM335X_PADCTL_UART0_TXD_OFFSET 0x0974 #define AM335X_PADCTL_UART1_CTSN_OFFSET 0x0978 -#define AM335X_PADCTL_UART1_RTSN_OFFSET 0x097C +#define AM335X_PADCTL_UART1_RTSN_OFFSET 0x097c #define AM335X_PADCTL_UART1_RXD_OFFSET 0x0980 #define AM335X_PADCTL_UART1_TXD_OFFSET 0x0984 #define AM335X_PADCTL_I2C0_SDA_OFFSET 0x0988 -#define AM335X_PADCTL_I2C0_SCL_OFFSET 0x098C +#define AM335X_PADCTL_I2C0_SCL_OFFSET 0x098c #define AM335X_PADCTL_MCASP0_ACLKX_OFFSET 0x0990 #define AM335X_PADCTL_MCASP0_FSX_OFFSET 0x0994 #define AM335X_PADCTL_MCASP0_AXR0_OFFSET 0x0998 -#define AM335X_PADCTL_MCASP0_AHCLKR_OFFSET 0x099C -#define AM335X_PADCTL_MCASP0_ACLKR_OFFSET 0x09A0 -#define AM335X_PADCTL_MCASP0_FSR_OFFSET 0x09A4 -#define AM335X_PADCTL_MCASP0_AXR1_OFFSET 0x09A8 -#define AM335X_PADCTL_MCASP0_AhCLKX_OFFSET 0x09AC -#define AM335X_PADCTL_XDMA_EVENT_INTR0_OFFSET 0x09B0 -#define AM335X_PADCTL_XDMA_EVENT_INTR1_OFFSET 0x09B4 -#define AM335X_PADCTL_WARMRSTN_OFFSET 0x09B8 -#define AM335X_PADCTL_NNMI_OFFSET 0x09C0 -#define AM335X_PADCTL_TMS_OFFSET 0x09D0 -#define AM335X_PADCTL_TDI_OFFSET 0x09D4 -#define AM335X_PADCTL_TDO_OFFSET 0x09D8 -#define AM335X_PADCTL_TCK_OFFSET 0x09DC -#define AM335X_PADCTL_TRSTN_OFFSET 0x09E0 -#define AM335X_PADCTL_EMU0_OFFSET 0x09E4 -#define AM335X_PADCTL_EMU1_OFFSET 0x09E8 -#define AM335X_PADCTL_RTC_PWRONRSTN_OFFSET 0x09F8 -#define AM335X_PADCTL_PMIC_POWER_EN_OFFSET 0x09FC -#define AM335X_PADCTL_EXT_WAKEUP_OFFSET 0x0A00 -#define AM335X_PADCTL_RTC_KALDO_ENN_OFFSET 0x0A04 -#define AM335X_PADCTL_USB0_DRVVBUS_OFFSET 0x0A1C -#define AM335X_PADCTL_USB1_DRVVBUS_OFFSET 0x0A34 +#define AM335X_PADCTL_MCASP0_AHCLKR_OFFSET 0x099c +#define AM335X_PADCTL_MCASP0_ACLKR_OFFSET 0x09a0 +#define AM335X_PADCTL_MCASP0_FSR_OFFSET 0x09a4 +#define AM335X_PADCTL_MCASP0_AXR1_OFFSET 0x09a8 +#define AM335X_PADCTL_MCASP0_AhCLKX_OFFSET 0x09ac +#define AM335X_PADCTL_XDMA_EVENT_INTR0_OFFSET 0x09b0 +#define AM335X_PADCTL_XDMA_EVENT_INTR1_OFFSET 0x09b4 +#define AM335X_PADCTL_WARMRSTN_OFFSET 0x09b8 +#define AM335X_PADCTL_NNMI_OFFSET 0x09c0 +#define AM335X_PADCTL_TMS_OFFSET 0x09d0 +#define AM335X_PADCTL_TDI_OFFSET 0x09d4 +#define AM335X_PADCTL_TDO_OFFSET 0x09d8 +#define AM335X_PADCTL_TCK_OFFSET 0x09dc +#define AM335X_PADCTL_TRSTN_OFFSET 0x09e0 +#define AM335X_PADCTL_EMU0_OFFSET 0x09e4 +#define AM335X_PADCTL_EMU1_OFFSET 0x09e8 +#define AM335X_PADCTL_RTC_PWRONRSTN_OFFSET 0x09f8 +#define AM335X_PADCTL_PMIC_POWER_EN_OFFSET 0x09fc +#define AM335X_PADCTL_EXT_WAKEUP_OFFSET 0x0a00 +#define AM335X_PADCTL_RTC_KALDO_ENN_OFFSET 0x0a04 +#define AM335X_PADCTL_USB0_DRVVBUS_OFFSET 0x0a1c +#define AM335X_PADCTL_USB1_DRVVBUS_OFFSET 0x0a34 /* Control Module Register Addresses ********************************************************/ -#define AM335X_CONTROL_SYS_CONF (AM335X_CONTROL_MODULE_VADDR + AM335X_CONTROL_SYS_CONF_OFFSET) -#define AM335X_CONTROL_STATUS (AM335X_CONTROL_MODULE_VADDR + AM335X_CONTROL_STATUS_OFFSET) -#define AM335X_CONTROL_EMIF_SDRAM_CONF (AM335X_CONTROL_MODULE_VADDR + AM335X_CONTROL_EMIF_SDRAM_CONF_OFFSET) -#define AM335X_CORE_SLDO_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_CORE_SLDO_CTRL_OFFSET) -#define AM335X_MPU_SLDO_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_MPU_SLDO_CTRL_OFFSET) -#define AM335X_CLK32KDIVRATIO_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_CLK32KDIVRATIO_CTRL_OFFSET) -#define AM335X_BANDGAP_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_BANDGAP_CTRL_OFFSET) -#define AM335X_BANDGAP_TRIM (AM335X_CONTROL_MODULE_VADDR + AM335X_BANDGAP_TRIM_OFFSET) -#define AM335X_PLL_CLKINPULOW_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_PLL_CLKINPULOW_CTRL_OFFSET) -#define AM335X_MOSC_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_MOSC_CTRL_OFFSET) -#define AM335X_DEEPSLEEP_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DEEPSLEEP_CTRL_OFFSET) -#define AM335X_DPLL_PWR_SW_STATUS (AM335X_CONTROL_MODULE_VADDR + AM335X_DPLL_PWR_SW_STATUS_OFFSET) -#define AM335X_DEVICE_ID (AM335X_CONTROL_MODULE_VADDR + AM335X_DEVICE_ID_OFFSET) -#define AM335X_DEV_FEATURE (AM335X_CONTROL_MODULE_VADDR + AM335X_DEV_FEATURE_OFFSET) -#define AM335X_INIT_PRIORITY_0 (AM335X_CONTROL_MODULE_VADDR + AM335X_INIT_PRIORITY_0_OFFSET) -#define AM335X_INIT_PRIORITY_1 (AM335X_CONTROL_MODULE_VADDR + AM335X_INIT_PRIORITY_1_OFFSET) -#define AM335X_TPTC_CFG (AM335X_CONTROL_MODULE_VADDR + AM335X_TPTC_CFG_OFFSET) -#define AM335X_USB_CTRL0 (AM335X_CONTROL_MODULE_VADDR + AM335X_USB_CTRL0_OFFSET) -#define AM335X_USB_STS0 (AM335X_CONTROL_MODULE_VADDR + AM335X_USB_STS0_OFFSET) -#define AM335X_USB_CTRL1 (AM335X_CONTROL_MODULE_VADDR + AM335X_USB_CTRL1_OFFSET) -#define AM335X_USB_STS1 (AM335X_CONTROL_MODULE_VADDR + AM335X_USB_STS1_OFFSET) -#define AM335X_MAC_ID0_LO (AM335X_CONTROL_MODULE_VADDR + AM335X_MAC_ID0_LO_OFFSET) -#define AM335X_MAC_ID0_HI (AM335X_CONTROL_MODULE_VADDR + AM335X_MAC_ID0_HI_OFFSET) -#define AM335X_MAC_ID1_LO (AM335X_CONTROL_MODULE_VADDR + AM335X_MAC_ID1_LO_OFFSET) -#define AM335X_MAC_ID1_HI (AM335X_CONTROL_MODULE_VADDR + AM335X_MAC_ID1_HI_OFFSET) -#define AM335X_DCAN_RAMINIT (AM335X_CONTROL_MODULE_VADDR + AM335X_DCAN_RAMINIT_OFFSET) -#define AM335X_USB_WKUP_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_USB_WKUP_CTRL_OFFSET) -#define AM335X_GMII_SEL (AM335X_CONTROL_MODULE_VADDR + AM335X_GMII_SEL_OFFSET) -#define AM335X_PWMSS_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_PWMSS_CTRL_OFFSET) -#define AM335X_MREGPRIO_0 (AM335X_CONTROL_MODULE_VADDR + AM335X_MREGPRIO_0_OFFSET) -#define AM335X_MREGPRIO_1 (AM335X_CONTROL_MODULE_VADDR + AM335X_MREGPRIO_1_OFFSET) -#define AM335X_HW_EVENT_SEL_GRP1 (AM335X_CONTROL_MODULE_VADDR + AM335X_HW_EVENT_SEL_GRP1_OFFSET) -#define AM335X_HW_EVENT_SEL_GRP2 (AM335X_CONTROL_MODULE_VADDR + AM335X_HW_EVENT_SEL_GRP2_OFFSET) -#define AM335X_HW_EVENT_SEL_GRP3 (AM335X_CONTROL_MODULE_VADDR + AM335X_HW_EVENT_SEL_GRP3_OFFSET) -#define AM335X_HW_EVENT_SEL_GRP4 (AM335X_CONTROL_MODULE_VADDR + AM335X_HW_EVENT_SEL_GRP4_OFFSET) -#define AM335X_SMRT_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SMRT_CTRL_OFFSET) -#define AM335X_MPUSS_HW_DEBUG_SEL (AM335X_CONTROL_MODULE_VADDR + AM335X_MPUSS_HW_DEBUG_SEL_OFFSET) -#define AM335X_MPUSS_HW_DBG_INFO (AM335X_CONTROL_MODULE_VADDR + AM335X_MPUSS_HW_DBG_INFO_OFFSET) -#define AM335X_VDD_MPU_OPP_050 (AM335X_CONTROL_MODULE_VADDR + AM335X_VDD_MPU_OPP_050_OFFSET) -#define AM335X_VDD_MPU_OPP_100 (AM335X_CONTROL_MODULE_VADDR + AM335X_VDD_MPU_OPP_100_OFFSET) -#define AM335X_VDD_MPU_OPP_120 (AM335X_CONTROL_MODULE_VADDR + AM335X_VDD_MPU_OPP_120_OFFSET) -#define AM335X_VDD_MPU_OPP_TURBO (AM335X_CONTROL_MODULE_VADDR + AM335X_VDD_MPU_OPP_TURBO_OFFSET) -#define AM335X_VDD_CORE_OPP_050 (AM335X_CONTROL_MODULE_VADDR + AM335X_VDD_CORE_OPP_050_OFFSET) -#define AM335X_VDD_CORE_OPP_100 (AM335X_CONTROL_MODULE_VADDR + AM335X_VDD_CORE_OPP_100_OFFSET) -#define AM335X_BB_SCALE (AM335X_CONTROL_MODULE_VADDR + AM335X_BB_SCALE_OFFSET) -#define AM335X_USB_VID_PID (AM335X_CONTROL_MODULE_VADDR + AM335X_USB_VID_PID_OFFSET) -#define AM335X_EFUSE_SMA (AM335X_CONTROL_MODULE_VADDR + AM335X_EFUSE_SMA_OFFSET) +#define AM335X_SCM_CTRL_SYS_CONF (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_CTRL_SYS_CONF_OFFSET) +#define AM335X_SCM_CTRL_STATUS (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_CTRL_STATUS_OFFSET) +#define AM335X_SCM_CTRL_EMIF_SDRAM_CONF (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_CTRL_EMIF_SDRAM_CONF_OFFSET) +#define AM335X_SCM_CORE_SLDO_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_CORE_SLDO_CTRL_OFFSET) +#define AM335X_SCM_MPU_SLDO_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MPU_SLDO_CTRL_OFFSET) +#define AM335X_SCM_CLK32KDIVRATIO_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_CLK32KDIVRATIO_CTRL_OFFSET) +#define AM335X_SCM_BANDGAP_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_BANDGAP_CTRL_OFFSET) +#define AM335X_SCM_BANDGAP_TRIM (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_BANDGAP_TRIM_OFFSET) +#define AM335X_SCM_PLL_CLKINPULOW_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_PLL_CLKINPULOW_CTRL_OFFSET) +#define AM335X_SCM_MOSC_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MOSC_CTRL_OFFSET) +#define AM335X_SCM_DEEPSLEEP_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DEEPSLEEP_CTRL_OFFSET) +#define AM335X_SCM_DPLL_PWR_SW_STATUS (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DPLL_PWR_SW_STATUS_OFFSET) +#define AM335X_SCM_DEVICE_ID (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DEVICE_ID_OFFSET) +#define AM335X_SCM_DEV_FEATURE (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DEV_FEATURE_OFFSET) +#define AM335X_SCM_INIT_PRIORITY_0 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_INIT_PRIORITY_0_OFFSET) +#define AM335X_SCM_INIT_PRIORITY_1 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_INIT_PRIORITY_1_OFFSET) +#define AM335X_SCM_TPTC_CFG (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPTC_CFG_OFFSET) +#define AM335X_SCM_USB_CTRL0 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_USB_CTRL0_OFFSET) +#define AM335X_SCM_USB_STS0 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_USB_STS0_OFFSET) +#define AM335X_SCM_USB_CTRL1 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_USB_CTRL1_OFFSET) +#define AM335X_SCM_USB_STS1 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_USB_STS1_OFFSET) +#define AM335X_SCM_MAC_ID0_LO (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MAC_ID0_LO_OFFSET) +#define AM335X_SCM_MAC_ID0_HI (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MAC_ID0_HI_OFFSET) +#define AM335X_SCM_MAC_ID1_LO (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MAC_ID1_LO_OFFSET) +#define AM335X_SCM_MAC_ID1_HI (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MAC_ID1_HI_OFFSET) +#define AM335X_SCM_DCAN_RAMINIT (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DCAN_RAMINIT_OFFSET) +#define AM335X_SCM_USB_WKUP_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_USB_WKUP_CTRL_OFFSET) +#define AM335X_SCM_GMII_SEL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_GMII_SEL_OFFSET) +#define AM335X_SCM_PWMSS_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_PWMSS_CTRL_OFFSET) +#define AM335X_SCM_MREGPRIO_0 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MREGPRIO_0_OFFSET) +#define AM335X_SCM_MREGPRIO_1 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MREGPRIO_1_OFFSET) +#define AM335X_SCM_HW_EVENT_SEL_GRP1 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_HW_EVENT_SEL_GRP1_OFFSET) +#define AM335X_SCM_HW_EVENT_SEL_GRP2 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_HW_EVENT_SEL_GRP2_OFFSET) +#define AM335X_SCM_HW_EVENT_SEL_GRP3 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_HW_EVENT_SEL_GRP3_OFFSET) +#define AM335X_SCM_HW_EVENT_SEL_GRP4 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_HW_EVENT_SEL_GRP4_OFFSET) +#define AM335X_SCM_SMRT_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_SMRT_CTRL_OFFSET) +#define AM335X_SCM_MPUSS_HW_DEBUG_SEL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MPUSS_HW_DEBUG_SEL_OFFSET) +#define AM335X_SCM_MPUSS_HW_DBG_INFO (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_MPUSS_HW_DBG_INFO_OFFSET) +#define AM335X_SCM_VDD_MPU_OPP_050 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_VDD_MPU_OPP_050_OFFSET) +#define AM335X_SCM_VDD_MPU_OPP_100 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_VDD_MPU_OPP_100_OFFSET) +#define AM335X_SCM_VDD_MPU_OPP_120 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_VDD_MPU_OPP_120_OFFSET) +#define AM335X_SCM_VDD_MPU_OPP_TURBO (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_VDD_MPU_OPP_TURBO_OFFSET) +#define AM335X_SCM_VDD_CORE_OPP_050 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_VDD_CORE_OPP_050_OFFSET) +#define AM335X_SCM_VDD_CORE_OPP_100 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_VDD_CORE_OPP_100_OFFSET) +#define AM335X_SCM_BB_SCALE (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_BB_SCALE_OFFSET) +#define AM335X_SCM_USB_VID_PID (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_USB_VID_PID_OFFSET) +#define AM335X_SCM_EFUSE_SMA (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_EFUSE_SMA_OFFSET) -#define AM335X_CQDETECT_STATUS (AM335X_CONTROL_MODULE_VADDR + AM335X_CQDETECT_STATUS_OFFSET) -#define AM335X_DDR_IO_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DDR_IO_CTRL_OFFSET) -#define AM335X_VTP_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_VTP_CTRL_OFFSET) -#define AM335X_VREF_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_VREF_CTRL_OFFSET) -#define AM335X_TPCC_EVT_MUX_0_3 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_0_3_OFFSET) -#define AM335X_TPCC_EVT_MUX_4_7 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_4_7_OFFSET) -#define AM335X_TPCC_EVT_MUX_8_11 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_8_11_OFFSET) -#define AM335X_TPCC_EVT_MUX_12_15 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_12_15_OFFSET) -#define AM335X_TPCC_EVT_MUX_16_19 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_16_19_OFFSET) -#define AM335X_TPCC_EVT_MUX_20_23 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_20_23_OFFSET) -#define AM335X_TPCC_EVT_MUX_24_27 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_24_27_OFFSET) -#define AM335X_TPCC_EVT_MUX_28_31 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_28_31_OFFSET) -#define AM335X_TPCC_EVT_MUX_32_35 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_32_35_OFFSET) -#define AM335X_TPCC_EVT_MUX_36_39 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_36_39_OFFSET) -#define AM335X_TPCC_EVT_MUX_40_43 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_40_43_OFFSET) -#define AM335X_TPCC_EVT_MUX_44_47 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_44_47_OFFSET) -#define AM335X_TPCC_EVT_MUX_48_51 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_48_51_OFFSET) -#define AM335X_TPCC_EVT_MUX_52_55 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_52_55_OFFSET) -#define AM335X_TPCC_EVT_MUX_56_59 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_56_59_OFFSET) -#define AM335X_TPCC_EVT_MUX_60_63 (AM335X_CONTROL_MODULE_VADDR + AM335X_TPCC_EVT_MUX_60_63_OFFSET) -#define AM335X_TIMER_EVT_CAPT (AM335X_CONTROL_MODULE_VADDR + AM335X_TIMER_EVT_CAPT_OFFSET) -#define AM335X_ECAP_EVT_CAPT (AM335X_CONTROL_MODULE_VADDR + AM335X_ECAP_EVT_CAPT_OFFSET) -#define AM335X_ADC_EVT_CAPT (AM335X_CONTROL_MODULE_VADDR + AM335X_ADC_EVT_CAPT_OFFSET) -#define AM335X_RESET_ISO (AM335X_CONTROL_MODULE_VADDR + AM335X_RESET_ISO_OFFSET) -#define AM335X_DPLL_PWR_SW_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DPLL_PWR_SW_CTRL_OFFSET) -#define AM335X_DDR_CKE_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DDR_CKE_CTRL_OFFSET) -#define AM335X_SMA2 (AM335X_CONTROL_MODULE_VADDR + AM335X_SMA2_OFFSET) -#define AM335X_M3_TXEV_EOI (AM335X_CONTROL_MODULE_VADDR + AM335X_M3_TXEV_EOI_OFFSET) -#define AM335X_IPC_MSG_REG0 (AM335X_CONTROL_MODULE_VADDR + AM335X_IPC_MSG_REG0_OFFSET) -#define AM335X_IPC_MSG_REG1 (AM335X_CONTROL_MODULE_VADDR + AM335X_IPC_MSG_REG1_OFFSET) -#define AM335X_IPC_MSG_REG2 (AM335X_CONTROL_MODULE_VADDR + AM335X_IPC_MSG_REG2_OFFSET) -#define AM335X_IPC_MSG_REG3 (AM335X_CONTROL_MODULE_VADDR + AM335X_IPC_MSG_REG3_OFFSET) -#define AM335X_IPC_MSG_REG4 (AM335X_CONTROL_MODULE_VADDR + AM335X_IPC_MSG_REG4_OFFSET) -#define AM335X_IPC_MSG_REG5 (AM335X_CONTROL_MODULE_VADDR + AM335X_IPC_MSG_REG5_OFFSET) -#define AM335X_IPC_MSG_REG6 (AM335X_CONTROL_MODULE_VADDR + AM335X_IPC_MSG_REG6_OFFSET) -#define AM335X_IPC_MSG_REG7 (AM335X_CONTROL_MODULE_VADDR + AM335X_IPC_MSG_REG7_OFFSET) -#define AM335X_DDR_CMD0_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DDR_CMD0_IOCTRL_OFFSET) -#define AM335X_DDR_CMD1_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DDR_CMD1_IOCTRL_OFFSET) -#define AM335X_DDR_CMD2_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DDR_CMD2_IOCTRL_OFFSET) -#define AM335X_DDR_DATA0_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DDR_DATA0_IOCTRL_OFFSET) -#define AM335X_DDR_DATA1_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_DDR_DATA1_IOCTRL_OFFSET) +#define AM335X_SCM_CQDETECT_STATUS (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_CQDETECT_STATUS_OFFSET) +#define AM335X_SCM_DDR_IO_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DDR_IO_CTRL_OFFSET) +#define AM335X_SCM_VTP_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_VTP_CTRL_OFFSET) +#define AM335X_SCM_VREF_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_VREF_CTRL_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_0_3 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_0_3_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_4_7 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_4_7_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_8_11 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_8_11_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_12_15 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_12_15_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_16_19 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_16_19_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_20_23 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_20_23_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_24_27 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_24_27_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_28_31 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_28_31_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_32_35 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_32_35_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_36_39 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_36_39_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_40_43 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_40_43_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_44_47 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_44_47_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_48_51 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_48_51_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_52_55 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_52_55_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_56_59 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_56_59_OFFSET) +#define AM335X_SCM_TPCC_EVT_MUX_60_63 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TPCC_EVT_MUX_60_63_OFFSET) +#define AM335X_SCM_TIMER_EVT_CAPT (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_TIMER_EVT_CAPT_OFFSET) +#define AM335X_SCM_ECAP_EVT_CAPT (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_ECAP_EVT_CAPT_OFFSET) +#define AM335X_SCM_ADC_EVT_CAPT (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_ADC_EVT_CAPT_OFFSET) +#define AM335X_SCM_RESET_ISO (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_RESET_ISO_OFFSET) +#define AM335X_SCM_DPLL_PWR_SW_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DPLL_PWR_SW_CTRL_OFFSET) +#define AM335X_SCM_DDR_CKE_CTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DDR_CKE_CTRL_OFFSET) +#define AM335X_SCM_SMA2 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_SMA2_OFFSET) +#define AM335X_SCM_M3_TXEV_EOI (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_M3_TXEV_EOI_OFFSET) +#define AM335X_SCM_IPC_MSG_REG0 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_IPC_MSG_REG0_OFFSET) +#define AM335X_SCM_IPC_MSG_REG1 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_IPC_MSG_REG1_OFFSET) +#define AM335X_SCM_IPC_MSG_REG2 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_IPC_MSG_REG2_OFFSET) +#define AM335X_SCM_IPC_MSG_REG3 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_IPC_MSG_REG3_OFFSET) +#define AM335X_SCM_IPC_MSG_REG4 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_IPC_MSG_REG4_OFFSET) +#define AM335X_SCM_IPC_MSG_REG5 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_IPC_MSG_REG5_OFFSET) +#define AM335X_SCM_IPC_MSG_REG6 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_IPC_MSG_REG6_OFFSET) +#define AM335X_SCM_IPC_MSG_REG7 (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_IPC_MSG_REG7_OFFSET) +#define AM335X_SCM_DDR_CMD0_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DDR_CMD0_IOCTRL_OFFSET) +#define AM335X_SCM_DDR_CMD1_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DDR_CMD1_IOCTRL_OFFSET) +#define AM335X_SCM_DDR_CMD2_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DDR_CMD2_IOCTRL_OFFSET) +#define AM335X_SCM_DDR_DATA0_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DDR_DATA0_IOCTRL_OFFSET) +#define AM335X_SCM_DDR_DATA1_IOCTRL (AM335X_CONTROL_MODULE_VADDR + AM335X_SCM_DDR_DATA1_IOCTRL_OFFSET) /* Pad Control Registers */ @@ -624,6 +624,15 @@ /* Control Module Register Bit Definitions **************************************************/ +/* Control Status Fields */ +#define SCM_CTRL_STATUS_SYSBOOT1_SHIFT (22) /* Bits 22-23: Crystal clock frequency selection */ +#define SCM_CTRL_STATUS_SYSBOOT1_MASK (3 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) +# define SCM_CTRL_STATUS_SYSBOOT1_19p2MHZ (0 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) +# define SCM_CTRL_STATUS_SYSBOOT1_24MHZ (1 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) +# define SCM_CTRL_STATUS_SYSBOOT1_25MHZ (2 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) +# define SCM_CTRL_STATUS_SYSBOOT1_26MHZ (3 << SCM_CTRL_STATUS_SYSBOOT1_SHIFT) + + /* PAD Control Fields */ #define PADCTL_MUXMODE_SHIFT (0) /* Bits 0-2: Functional signal mux select */ #define PADCTL_MUXMODE_MASK (7 << PADCTL_MUXMODE_SHIFT) @@ -643,4 +652,4 @@ #define PADCTL_RXACTIVE (1 << 5) /* Bit 5: Receiver enabled */ #define PADCTL_SLEWCTRL (1 << 6) /* Bit 6: Select between faster or slower slew rate */ -#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_CONTROL_H */ +#endif /* __ARCH_ARM_SRC_AM335X_HARDWARE_AM335X_SCM_H */ diff --git a/configs/beaglebone-black/Kconfig b/configs/beaglebone-black/Kconfig index 15b14ece171..c4e4b4eafb1 100644 --- a/configs/beaglebone-black/Kconfig +++ b/configs/beaglebone-black/Kconfig @@ -4,4 +4,14 @@ # if ARCH_BOARD_BEAGLEBONE_BLACK + +config BEAGLEBONE_VIDEOMODE + string "LCD Video Mode" + default "640x480x60" + depends on !CONFIG_LCD_TDA19988 || !CONFIG_AM335X_I2C2 + ---help--- + If we are not using HDMI (via the TDA19988) then we must select a + fixed LCD resolution. The default, "640x480x60" is standard VGA + which should be supported by all LCDs. + endif # ARCH_BOARD_BEAGLEBONE_BLACK diff --git a/configs/beaglebone-black/src/Makefile b/configs/beaglebone-black/src/Makefile index 20b1f72ab5e..a07bdad246e 100644 --- a/configs/beaglebone-black/src/Makefile +++ b/configs/beaglebone-black/src/Makefile @@ -51,7 +51,7 @@ CSRCS += am335x_buttons.c endif ifeq ($(CONFIG_AM335X_LCDC),y) -CSRCS += am335x_lcdc.c +CSRCS += am335x_lcd.c endif include $(TOPDIR)/configs/Board.mk diff --git a/configs/beaglebone-black/src/am335x_lcd.c b/configs/beaglebone-black/src/am335x_lcd.c index a18dbbf44e1..905aa1510ab 100644 --- a/configs/beaglebone-black/src/am335x_lcd.c +++ b/configs/beaglebone-black/src/am335x_lcd.c @@ -42,11 +42,14 @@ #include #include #include +#include +#include #include #include +#include -#include "am335x_lcd.h" +#include "am335x_lcdc.h" #include "beaglebone-black.h" #ifdef HAVE_LCD @@ -55,15 +58,19 @@ * Private Function Prototypes ****************************************************************************/ +#ifdef HAVE_TDA19988 static int am335x_attach(const struct tda19988_lower_s *lower, xcpt_t handler, void *arg); static int am335x_enable(const struct tda19988_lower_s *lower, bool enable); +#endif /**************************************************************************** * Private Data ****************************************************************************/ +#ifdef HAVE_TDA19988 static const strurct tda19988_lower_s g_lower; +#endif /**************************************************************************** * Private Functions @@ -77,10 +84,14 @@ static const strurct tda19988_lower_s g_lower; * ****************************************************************************/ +#ifdef HAVE_TDA19988 static int am335x_attach(const struct tda19988_lower_s *lower, xcpt_t handler, void *arg) { +#warning Missing logic + return -ENOSYS; } +#endif /**************************************************************************** * Name: am335x_enable @@ -90,9 +101,13 @@ static int am335x_attach(const struct tda19988_lower_s *lower, * ****************************************************************************/ +#ifdef HAVE_TDA19988 static int am335x_enable(const struct tda19988_lower_s *lower, bool enable) { +#warning Missing logic + return -ENOSYS; } +#endif /**************************************************************************** * Public Functions @@ -102,7 +117,8 @@ static int am335x_enable(const struct tda19988_lower_s *lower, bool enable) * Name: up_fbinitialize * * Description: - * Initialize the LCD. This involves: + * Initialize the LCD. If support for the TDA19988 HDMI controller is + * enabled, then this involves: * * 1. Initializing the TDA19988 HDMI controller driver * 2. Reading EDID data from the connected monitor @@ -110,10 +126,20 @@ static int am335x_enable(const struct tda19988_lower_s *lower, bool enable) * 4. Initializing the LCD controller using this video mode * 5. Initializing the HDMI controller using the video mode * + * Otherwise, a default video mode is used to initialize the LCD + * controller. + * ****************************************************************************/ -void up_fbinitialize(int display) +int up_fbinitialize(int display) { + FAR const struct videomode_s *videomode; + struct am335x_panel_info_s panel; + int ret; + +#ifdef HAVE_TDA19988 + TDA19988_HANDLE handle; + /* Initialize the TDA19988 GPIO interrupt input */ /* Initialize the TDA19988 lower half state instance */ /* Initialize the TDA19988 HDMI controller driver */ @@ -121,10 +147,45 @@ void up_fbinitialize(int display) /* Read raw EDID data from the connected monitor */ /* Select a compatible video mode from the EDID data */ /* Free the allocated EDID buffer */ - /* Convert the video mode to a AM335X LCD panel configuration */ - /* Initialize the LCD controller using this video mode */ - /* Convert the EDID video mode to a TDA19988 video mode */ - /* Initialize the HDMI controller using the TDA19988 video mode */ + +#warning Missing logic +#else + /* Lookup the video mode corresponding to the default video mode */ + + videomode = videomode_lookup_by_name(CONFIG_BEAGLEBONE_VIDEOMODE); + if (videomode == NULL) + { + lcderr("ERROR: Videomode \"%s\" is not supported.\n", + CONFIG_BEAGLEBONE_VIDEOMODE); + return -ENOTSUP; + } + +#endif + /* Convert the selected video mode to a AM335X LCD panel configuration */ + + am335x_lcd_videomode(videomode, &panel); + + /* Initialize the LCD controller using this panel configuration */ + + ret = am335x_lcd_initialize(&panel); + if (ret < 0) + { + lcderr("ERROR: am335x_lcd_initialize() failed: %d\n", ret); + return ret; + } + +#ifdef HAVE_TDA19988 + /* Initialize the HDMI controller using the selected video mode */ + + ret = tda19988_videomode(handle, videomode); + if (ret < 0) + { + lcderr("ERROR: tda19988_videomode() failed: %d\n", ret); + return ret; + } +#endif + + return OK; } #endif /* HAVE_LCD */ diff --git a/configs/beaglebone-black/src/beaglebone-black.h b/configs/beaglebone-black/src/beaglebone-black.h index 1b0f430aed0..9a997b21ebe 100644 --- a/configs/beaglebone-black/src/beaglebone-black.h +++ b/configs/beaglebone-black/src/beaglebone-black.h @@ -56,16 +56,25 @@ /* LCD ******************************************************************************/ -#define HAVE_LCD 1 -#if !defined(CONFIG_AM335X_LCDC) || !defined(CONFIG_VIDEO_EDID) || \ - !defined(CONFIG_LCD_TDA19988) || !defined(CONFIG_AM335X_I2C2) +#define HAVE_LCD 1 +#define HAVE_TDA19988 1 + +#if !defined(CONFIG_AM335X_LCDC) || !defined(CONFIG_VIDEO_EDID) # undef HAVE_LCD +# undef HAVE_TDA19988 +#elif !defined(CONFIG_LCD_TDA19988) || !defined(CONFIG_AM335X_I2C2) +# undef HAVE_TDA19988 +# if !defined(CONFIG_BEAGLEBONE_VIDEOMODE) +# define CONFIG_BEAGLEBONE_VIDEOMODE "640x480x60" +# endif #endif -#define TDA19988_I2CBUS 2 -#define TDA19988_HDMI_I2CADDR 0x70 -#define TDA19988_CEC_I2CADDR 0x34 -#define TDA19988_I2CFREQUENCY 400000 +#if defined(HAVE_LCD) +# define TDA19988_I2CBUS 2 +# define TDA19988_HDMI_I2CADDR 0x70 +# define TDA19988_CEC_I2CADDR 0x34 +# define TDA19988_I2CFREQUENCY 400000 +#endif /* LEDs *****************************************************************************/ diff --git a/configs/makerlisp/README.txt b/configs/makerlisp/README.txt index 0f43fab23bb..a80490c2139 100644 --- a/configs/makerlisp/README.txt +++ b/configs/makerlisp/README.txt @@ -384,10 +384,11 @@ Configuration Subdirectories You can debug the all RAM version using ZDS-II as follows: a. Connect to the debugger, - b. Load the nuttx.lod file + b. Reset, Go, and Break. This will initialize the external RAM + c. Break and Load the nuttx.lod file c. Set the PC to 0x040000 d. Single step a few times to make sure things look good, then - e. "GO" + e. Go 5. Optimizations: @@ -415,7 +416,7 @@ Configuration Subdirectories configuration. Not yet verified. 2019-07-09: The RAM version does not run! I can single step through - the initialization and all looks well, but when I "GO", the system + the initialization and all looks well, but when I "Go", the system crashes. The PC is sitting at a crazy address when I break in. I have not yet debugged this. diff --git a/configs/olimex-stm32-e407/README.txt b/configs/olimex-stm32-e407/README.txt index 0b6e02eee73..ccb3cbcf985 100644 --- a/configs/olimex-stm32-e407/README.txt +++ b/configs/olimex-stm32-e407/README.txt @@ -2,5 +2,75 @@ README ====== The Olimex STM32-E407 configuration is based on the configuration olimex-stm32-h407 and stm32f4discovery. -nsh - Basic shell run on USART2. -usbnsh - Basic shell run on the virtual serial port. +Configurations +============== + + Instantiating Configurations + ---------------------------- + Each Olimex-STM32-E407 configuration is maintained in a sub-directory and + can be selected as follow: + + tools/configure.sh olimex-stm32-e407/ + + Where is one of the following: + + Compile Firmware + ---------------- + Once you've set the proper configuration, you just need to execute the next + command: + + make + + If everything goes find, it should return the next two files: + + nuttx.hex + nuttx.bin + + You can return more kind of files by setting on menuconfig. + + + Flashing the Board + ----------------- + You can flash this board in different ways, but the easiest way is using + ARM-USB-TINY-H JTAG flasher device. + Connect this device to the JTAG connector and type the next command: + + openocd -f interface/ftdi/olimex-arm-usb-tiny-h.cfg -f target/stm32f4x.cfg -c init -c "reset halt" -c "flash write_image erase nuttx.bin 0x08000000" + + Configuration Directories + ------------------------- + nsh: + --- + Configures the NuttShell (nsh) located at apps/examples/nsh. This + configuration enables a console on UART2. Support for + builtin applications is enabled, but in the base configuration no + builtin applications are selected. + + usbnsh: + ------ + Configures the NuttShell (nsh) located at apps/examples/nsh. This + configuration enables a console on USB_OTG1. Support for + builtin applications is enabled, but in the base configuration no + builtin applications are selected. + + netnsh: + ------ + Configures the NuttShell (nsh) located at examples/nsh. This + configuration is focused on network testing. + + BMP180: + ------ + This a configuration example for the BMP180 barometer sensor. This + sensor works with I2C, you need to do the next connections: + + BMP180 VIN -> Board 3.3V + BMP180 GND -> Board GND + BMP180 SCL -> Board PB6 (Arduino header D1) + BMP180 SDA -> Board PB7 (Arduino header D0) + + This example is configured to work with the USBNSH instead of UART NSH, so + the console will be shown over the USB_OTG1 connector. + + On the console, type "ls /dev " and if the registration process goes fine, + you should see a device called "press0". Now execute the app + BMP180 to see the ambient pressure value. diff --git a/configs/olimex-stm32-e407/bmp180/defconfig b/configs/olimex-stm32-e407/bmp180/defconfig new file mode 100644 index 00000000000..f6b5557bb82 --- /dev/null +++ b/configs/olimex-stm32-e407/bmp180/defconfig @@ -0,0 +1,65 @@ +# +# This file is autogenerated: PLEASE DO NOT EDIT IT. +# +# You can use "make menuconfig" to make any modifications to the installed .config file. +# You can then do "make savedefconfig" to generate a new defconfig file that includes your +# modifications. +# +# CONFIG_ARCH_FPU is not set +# CONFIG_NSH_ARGCAT is not set +# CONFIG_NSH_CMDOPT_HEXDUMP is not set +# CONFIG_NSH_CMDPARMS is not set +CONFIG_ARCH="arm" +CONFIG_ARCH_BOARD="olimex-stm32-e407" +CONFIG_ARCH_BOARD_OLIMEX_STM32E407=y +CONFIG_ARCH_BUTTONS=y +CONFIG_ARCH_CHIP_STM32=y +CONFIG_ARCH_CHIP_STM32F407ZG=y +CONFIG_ARCH_STACKDUMP=y +CONFIG_BOARDCTL_USBDEVCTRL=y +CONFIG_BOARD_LATE_INITIALIZE=y +CONFIG_BOARD_LOOPSPERMSEC=16717 +CONFIG_BUILTIN=y +CONFIG_CDCACM=y +CONFIG_CDCACM_CONSOLE=y +CONFIG_EXAMPLES_BMP180=y +CONFIG_EXAMPLES_HELLO=y +CONFIG_FS_PROCFS=y +CONFIG_HAVE_CXX=y +CONFIG_HAVE_CXXINITIALIZE=y +CONFIG_INTELHEX_BINARY=y +CONFIG_LIB_BOARDCTL=y +CONFIG_MAX_TASKS=16 +CONFIG_MAX_WDOGPARMS=2 +CONFIG_MM_REGIONS=2 +CONFIG_NFILE_DESCRIPTORS=8 +CONFIG_NFILE_STREAMS=8 +CONFIG_NSH_BUILTIN_APPS=y +CONFIG_NSH_FILEIOSIZE=512 +CONFIG_NSH_LINELEN=64 +CONFIG_NSH_READLINE=y +CONFIG_PREALLOC_MQ_MSGS=4 +CONFIG_PREALLOC_TIMERS=4 +CONFIG_PREALLOC_WDOGS=16 +CONFIG_RAM_SIZE=114688 +CONFIG_RAM_START=0x20000000 +CONFIG_RAW_BINARY=y +CONFIG_RR_INTERVAL=200 +CONFIG_SCHED_WAITPID=y +CONFIG_SDCLONE_DISABLE=y +CONFIG_SENSORS=y +CONFIG_SENSORS_BMP180=y +CONFIG_START_DAY=6 +CONFIG_START_MONTH=12 +CONFIG_START_YEAR=2011 +CONFIG_STM32_I2C1=y +CONFIG_STM32_JTAG_SW_ENABLE=y +CONFIG_STM32_OTGFS=y +CONFIG_STM32_PWR=y +CONFIG_STM32_USART2=y +CONFIG_SYSTEM_NSH=y +CONFIG_SYSTEM_NSH_CXXINITIALIZE=y +CONFIG_USART2_RXBUFSIZE=128 +CONFIG_USART2_TXBUFSIZE=128 +CONFIG_USBDEV=y +CONFIG_USER_ENTRYPOINT="nsh_main" diff --git a/configs/olimex-stm32-e407/include/board.h b/configs/olimex-stm32-e407/include/board.h index e220e0fd06f..d4996f1a744 100644 --- a/configs/olimex-stm32-e407/include/board.h +++ b/configs/olimex-stm32-e407/include/board.h @@ -212,24 +212,35 @@ /* Alternate function pin selections ************************************************/ /* USART1 */ + #define GPIO_USART1_RX GPIO_USART1_RX_2 /* PB7 */ #define GPIO_USART1_TX GPIO_USART1_TX_2 /* PB6 */ /* USART2 */ + #define GPIO_USART2_RX GPIO_USART2_RX_2 /* PD6 */ #define GPIO_USART2_TX GPIO_USART2_TX_2 /* PD5 */ /* USART3 */ + #define GPIO_USART3_RX GPIO_USART3_RX_1 /* PB11 */ #define GPIO_USART3_TX GPIO_USART3_TX_1 /* PB10 */ /* CAN */ -#define GPIO_CAN1_RX GPIO_CAN1_RX_2 /* PB8 */ -#define GPIO_CAN1_TX GPIO_CAN1_TX_2 /* PB9 */ + +#define GPIO_CAN1_RX GPIO_CAN1_RX_2 /* PB8 */ +#define GPIO_CAN1_TX GPIO_CAN1_TX_2 /* PB9 */ /* I2C */ -#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 /* PB6 */ -#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 /* PB7 */ + +#define GPIO_I2C1_SCL GPIO_I2C1_SCL_1 /* PB6 */ +#define GPIO_I2C1_SDA GPIO_I2C1_SDA_1 /* PB7 */ + +/* SPI1 */ + +#define GPIO_SPI1_SCK GPIO_SPI1_SCK_1 /* PA5 */ +#define GPIO_SPI1_MOSI GPIO_SPI1_MOSI_2 /* PB5 */ +#define GPIO_SPI1_MISO GPIO_SPI1_MISO_1 /* PA6 */ /* Ethernet *************************************************************************/ diff --git a/configs/olimex-stm32-e407/src/Makefile b/configs/olimex-stm32-e407/src/Makefile index 4838e21009e..44defad9d74 100644 --- a/configs/olimex-stm32-e407/src/Makefile +++ b/configs/olimex-stm32-e407/src/Makefile @@ -36,7 +36,7 @@ -include $(TOPDIR)/Make.defs ASRCS = -CSRCS = stm32_boot.c stm32_bringup.c +CSRCS = stm32_boot.c stm32_bringup.c stm32_spi.c ifeq ($(CONFIG_ARCH_LEDS),y) CSRCS += stm32_autoleds.c @@ -80,5 +80,9 @@ ifeq ($(CONFIG_ARCH_FPU),y) CSRCS += stm32_ostest.c endif +ifeq ($(CONFIG_SENSORS_BMP180),y) +CSRCS += stm32_bmp180.c +endif + include $(TOPDIR)/configs/Board.mk diff --git a/configs/olimex-stm32-e407/src/olimex-stm32-e407.h b/configs/olimex-stm32-e407/src/olimex-stm32-e407.h index bbc73d71b3e..af7ef82633e 100644 --- a/configs/olimex-stm32-e407/src/olimex-stm32-e407.h +++ b/configs/olimex-stm32-e407/src/olimex-stm32-e407.h @@ -269,5 +269,23 @@ int stm32_sdio_initialize(void); int stm32_can_setup(void); #endif +/************************************************************************************ + * Name: stm32_bmp180initialize + * + * Description: + * Initialize and register the BMP180 Pressure Sensor driver. + * + * Input parameters: + * devpath - The full path to the driver to register. E.g., "/dev/press0" + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_BMP180) +int stm32_bmp180initialize(FAR const char *devpath); +#endif + #endif /* __ASSEMBLY__ */ #endif /* __CONFIGS_OLIMEX_STM32_E407_SRC_INTERNAL_H */ diff --git a/configs/olimex-stm32-e407/src/stm32_bmp180.c b/configs/olimex-stm32-e407/src/stm32_bmp180.c new file mode 100644 index 00000000000..e4bc6d55c49 --- /dev/null +++ b/configs/olimex-stm32-e407/src/stm32_bmp180.c @@ -0,0 +1,106 @@ +/************************************************************************************ + * configs/olimex-stm32-e407/src/stm32_bmp180.c + * + * Copyright (C) 2019 Acutronics Robotics. All rights reserved. + * Author: Acutronics Robotics (Juan Flores) + * Base on the implementation of: Alan Carvalho de Assis + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 OWNER 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. + * + ************************************************************************************/ + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include +#include + +#include "stm32.h" +#include "stm32_i2c.h" +#include "olimex-stm32-e407.h" + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_BMP180) + +/************************************************************************************ + * Pre-processor Definitions + ************************************************************************************/ + +#define BMP180_I2C_PORTNO 1 /* On I2C1 */ + +/************************************************************************************ + * Public Functions + ************************************************************************************/ + +/************************************************************************************ + * Name: stm32_bmp180initialize + * + * Description: + * Initialize and register the BMP180 Pressure Sensor driver. + * + * Input parameters: + * devpath - The full path to the driver to register. E.g., "/dev/press0" + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ************************************************************************************/ + +int stm32_bmp180initialize(FAR const char *devpath) +{ + FAR struct i2c_master_s *i2c; + int ret; + + sninfo("Initializing BMP180!\n"); + + /* Initialize I2C */ + + i2c = stm32_i2cbus_initialize(BMP180_I2C_PORTNO); + + if (!i2c) + { + return -ENODEV; + } + + /* Then register the barometer sensor */ + + ret = bmp180_register(devpath, i2c); + if (ret < 0) + { + snerr("ERROR: Error registering BMP180\n"); + } + + return ret; +} + +#endif /* CONFIG_I2C && CONFIG_SENSORS_BMP180 && CONFIG_STM32_I2C1 */ diff --git a/configs/olimex-stm32-e407/src/stm32_bringup.c b/configs/olimex-stm32-e407/src/stm32_bringup.c index 0cd2851d743..2f9becd43a9 100644 --- a/configs/olimex-stm32-e407/src/stm32_bringup.c +++ b/configs/olimex-stm32-e407/src/stm32_bringup.c @@ -218,6 +218,17 @@ int stm32_bringup(void) } #endif +#ifdef CONFIG_SENSORS_BMP180 + /* Initialize the BMP180 pressure sensor. */ + + ret = stm32_bmp180initialize("/dev/press0"); + if (ret < 0) + { + syslog(LOG_ERR, "Failed to initialize BMP180, error %d\n", ret); + return ret; + } +#endif + UNUSED(ret); return OK; } diff --git a/configs/olimex-stm32-e407/src/stm32_spi.c b/configs/olimex-stm32-e407/src/stm32_spi.c new file mode 100644 index 00000000000..ff18b1c51ef --- /dev/null +++ b/configs/olimex-stm32-e407/src/stm32_spi.c @@ -0,0 +1,318 @@ +/**************************************************************************** + * configs/olimex-stm32-e407/src/stm32_spi.c + * + * Copyright (C) 2016, 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Laurent Latil + * Modify by: Acutronics Robotics (Juan Flores) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include + +#include +#include + +#include "up_arch.h" +#include "chip.h" +#include "stm32.h" +#include "olimex-stm32-e407.h" + +#if defined(CONFIG_STM32_SPI1) || defined(CONFIG_STM32_SPI2) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_spidev_initialize + * + * Description: + * Called to configure SPI chip select GPIO pins for the Olimex-STM32-E407 + * board. + * + ****************************************************************************/ + +void stm32_spidev_initialize(void) +{ + /* NOTE: Clocking for SPI1 and/or SPI2 was already provided in stm32_rcc.c. + * Configurations of SPI pins is performed in stm32_spi.c. + * Here, we only initialize chip select pins unique to the board + * architecture. + */ + +#ifdef CONFIG_MTD_W25 + (void)stm32_configgpio(FLASH_SPI1_CS); /* FLASH chip select */ +#endif + +#ifdef CONFIG_CAN_MCP2515 + (void)stm32_configgpio(GPIO_MCP2515_CS); /* MCP2515 chip select */ +#endif + +#ifdef CONFIG_CL_MFRC522 + (void)stm32_configgpio(GPIO_CS_MFRC522); /* MFRC522 chip select */ +#endif + +#if defined(CONFIG_SENSORS_MAX6675) + (void)stm32_configgpio(GPIO_MAX6675_CS); /* MAX6675 chip select */ +#endif + +#ifdef CONFIG_LCD_MAX7219 + (void)stm32_configgpio(STM32_LCD_CS); /* MAX7219 chip select */ +#endif + +#ifdef CONFIG_LCD_ST7567 + (void)stm32_configgpio(STM32_LCD_CS); /* ST7567 chip select */ +#endif + +#ifdef CONFIG_LCD_PCD8544 + (void)stm32_configgpio(STM32_LCD_CS); /* ST7567 chip select */ +#endif + +#ifdef CONFIG_WL_NRF24L01 + stm32_configgpio(GPIO_NRF24L01_CS); /* nRF24L01 chip select */ +#endif + +#ifdef CONFIG_MMCSD_SPI + stm32_configgpio(GPIO_SDCARD_CS); /* SD/MMC Card chip select */ +#endif + +#ifdef CONFIG_IEEE802154_MRF24J40 + stm32_configgpio(GPIO_MRF24J40_CS); +#endif +} + +/**************************************************************************** + * Name: stm32_spi1/2select and stm32_spi1/2status + * + * Description: + * The external functions, stm32_spi1/2/3select and stm32_spi1/2/3status + * must be provided by board-specific logic. They are implementations of + * the select and status methods of the SPI interface defined by struct + * spi_ops_s (see include/nuttx/spi/spi.h). All other methods (including + * stm32_spibus_initialize()) are provided by common STM32 logic. To use + * this common SPI logic on your board: + * + * 1. Provide logic in stm32_boardinitialize() to configure SPI chip select + * pins. + * 2. Provide stm32_spi1/2/3select() and stm32_spi1/2/3status() functions + * in your board-specific logic. These functions will perform chip + * selection and status operations using GPIOs in the way your board is + * configured. + * 3. Add a calls to stm32_spibus_initialize() in your low level application + * initialization logic + * 4. The handle returned by stm32_spibus_initialize() may then be used to + * bind the SPI driver to higher level logic (e.g., calling + * mmcsd_spislotinitialize(), for example, will bind the SPI driver to + * the SPI MMC/SD driver). + * + ****************************************************************************/ + +#ifdef CONFIG_STM32_SPI1 +void stm32_spi1select(FAR struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ +#if defined(CONFIG_CAN_MCP2515) + if (devid == SPIDEV_CANBUS(0)) + { + stm32_gpiowrite(GPIO_MCP2515_CS, !selected); + } +#endif + +#if defined(CONFIG_CL_MFRC522) + if (devid == SPIDEV_CONTACTLESS(0)) + { + stm32_gpiowrite(GPIO_CS_MFRC522, !selected); + } +#endif + +#ifdef CONFIG_IEEE802154_MRF24J40 + if (devid == SPIDEV_IEEE802154(0)) + { + stm32_gpiowrite(GPIO_MRF24J40_CS, !selected); + } +#endif + +#if defined(CONFIG_IEEE802154_XBEE) + if (devid == SPIDEV_IEEE802154(0)) + { + stm32_gpiowrite(GPIO_XBEE_CS, !selected); + } +#endif + +#if defined(CONFIG_SENSORS_MAX6675) + if (devid == SPIDEV_TEMPERATURE(0)) + { + stm32_gpiowrite(GPIO_MAX6675_CS, !selected); + } +#endif + +#ifdef CONFIG_LCD_MAX7219 + if (devid == SPIDEV_DISPLAY(0)) + { + stm32_gpiowrite(STM32_LCD_CS, !selected); + } +#endif + +#ifdef CONFIG_LCD_PCD8544 + if (devid == SPIDEV_DISPLAY(0)) + { + stm32_gpiowrite(STM32_LCD_CS, !selected); + } +#endif + +#ifdef CONFIG_LCD_ST7567 + if (devid == SPIDEV_DISPLAY(0)) + { + stm32_gpiowrite(STM32_LCD_CS, !selected); + } +#endif + +#ifdef CONFIG_WL_NRF24L01 + if (devid == SPIDEV_WIRELESS(0)) + { + stm32_gpiowrite(GPIO_NRF24L01_CS, !selected); + } +#endif + +#ifdef CONFIG_MMCSD_SPI + if (devid == SPIDEV_MMCSD(0)) + { + stm32_gpiowrite(GPIO_SDCARD_CS, !selected); + } +#endif + +#ifdef CONFIG_MTD_W25 + stm32_gpiowrite(FLASH_SPI1_CS, !selected); +#endif +} + +uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + uint8_t status = 0; + +#ifdef CONFIG_WL_NRF24L01 + if (devid == SPIDEV_WIRELESS(0)) + { + status |= SPI_STATUS_PRESENT; + } +#endif + +#ifdef CONFIG_MMCSD_SPI + if (devid == SPIDEV_MMCSD(0)) + { + status |= SPI_STATUS_PRESENT; + } +#endif + + return status; +} +#endif + +#ifdef CONFIG_STM32_SPI2 +void stm32_spi2select(FAR struct spi_dev_s *dev, uint32_t devid, + bool selected) +{ +} + +uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, uint32_t devid) +{ + return 0; +} +#endif + +/**************************************************************************** + * Name: stm32_spi1cmddata + * + * Description: + * Set or clear the SH1101A A0 or SD1306 D/C n bit to select data (true) + * or command (false). This function must be provided by platform-specific + * logic. This is an implementation of the cmddata method of the SPI + * interface defined by struct spi_ops_s (see include/nuttx/spi/spi.h). + * + * Input Parameters: + * + * spi - SPI device that controls the bus the device that requires the CMD/ + * DATA selection. + * devid - If there are multiple devices on the bus, this selects which one + * to select cmd or data. NOTE: This design restricts, for example, + * one one SPI display per SPI bus. + * cmd - true: select command; false: select data + * + * Returned Value: + * None + * + ****************************************************************************/ + +#ifdef CONFIG_SPI_CMDDATA +#ifdef CONFIG_STM32_SPI1 +int stm32_spi1cmddata(FAR struct spi_dev_s *dev, uint32_t devid, + bool cmd) +{ +#ifdef CONFIG_LCD_ST7567 + if (devid == SPIDEV_DISPLAY(0)) + { + /* This is the Data/Command control pad which determines whether the + * data bits are data or a command. + */ + + (void)stm32_gpiowrite(STM32_LCD_RS, !cmd); + + return OK; + } +#endif + +#ifdef CONFIG_LCD_PCD8544 + if (devid == SPIDEV_DISPLAY(0)) + { + /* This is the Data/Command control pad which determines whether the + * data bits are data or a command. + */ + + (void)stm32_gpiowrite(STM32_LCD_CD, !cmd); + + return OK; + } +#endif + + return -ENODEV; +} +#endif +#endif + +#endif /* CONFIG_STM32_SPI1 || CONFIG_STM32_SPI2 */ diff --git a/configs/spresense/lcd/defconfig b/configs/spresense/lcd/defconfig index 085629160a7..098c329a5b1 100644 --- a/configs/spresense/lcd/defconfig +++ b/configs/spresense/lcd/defconfig @@ -8,6 +8,7 @@ # CONFIG_CXD56_I2C0_SCUSEQ is not set # CONFIG_MMCSD_HAVE_WRITEPROTECT is not set # CONFIG_MMCSD_SPI is not set +# CONFIG_MTD_SMART_WEAR_LEVEL is not set # CONFIG_STANDARD_SERIAL is not set CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="spresense" @@ -44,6 +45,7 @@ CONFIG_FAT_MAXFNAME=64 CONFIG_FS_FAT=y CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y @@ -54,6 +56,11 @@ CONFIG_MAX_TASKS=16 CONFIG_MAX_WDOGPARMS=2 CONFIG_MMCSD=y CONFIG_MMCSD_SDIO=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_SMART=y +CONFIG_MTD_SMART_ENABLE_CRC=y +CONFIG_MTD_SMART_SECTOR_SIZE=4096 CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NSH_ARCHINIT=y @@ -70,6 +77,9 @@ CONFIG_RTC=y CONFIG_RTC_DRIVER=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y +CONFIG_SMARTFS_ALIGNED_ACCESS=y +CONFIG_SMARTFS_MAXNAMLEN=30 +CONFIG_SMARTFS_MULTI_ROOT_DIRS=y CONFIG_SPI=y CONFIG_START_DAY=6 CONFIG_START_MONTH=12 @@ -88,4 +98,4 @@ CONFIG_USBDEV_DUALSPEED=y CONFIG_USBMSC=y CONFIG_USBMSC_COMPOSITE=y CONFIG_USBMSC_REMOVABLE=y -CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_USER_ENTRYPOINT="spresense_main" diff --git a/configs/spresense/mpy/defconfig b/configs/spresense/mpy/defconfig index 3b43d453568..907f138f173 100644 --- a/configs/spresense/mpy/defconfig +++ b/configs/spresense/mpy/defconfig @@ -8,6 +8,7 @@ # CONFIG_CXD56_I2C0_SCUSEQ is not set # CONFIG_MMCSD_HAVE_WRITEPROTECT is not set # CONFIG_MMCSD_SPI is not set +# CONFIG_MTD_SMART_WEAR_LEVEL is not set # CONFIG_STANDARD_SERIAL is not set CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="spresense" @@ -47,6 +48,7 @@ CONFIG_FAT_MAXFNAME=64 CONFIG_FS_FAT=y CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y @@ -54,6 +56,11 @@ CONFIG_MAX_TASKS=16 CONFIG_MAX_WDOGPARMS=2 CONFIG_MMCSD=y CONFIG_MMCSD_SDIO=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_SMART=y +CONFIG_MTD_SMART_ENABLE_CRC=y +CONFIG_MTD_SMART_SECTOR_SIZE=4096 CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NSH_ARCHINIT=y @@ -70,6 +77,9 @@ CONFIG_RTC=y CONFIG_RTC_DRIVER=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y +CONFIG_SMARTFS_ALIGNED_ACCESS=y +CONFIG_SMARTFS_MAXNAMLEN=30 +CONFIG_SMARTFS_MULTI_ROOT_DIRS=y CONFIG_SPI=y CONFIG_START_DAY=6 CONFIG_START_MONTH=12 @@ -85,4 +95,4 @@ CONFIG_USBDEV_DUALSPEED=y CONFIG_USBMSC=y CONFIG_USBMSC_EPBULKIN=1 CONFIG_USBMSC_REMOVABLE=y -CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_USER_ENTRYPOINT="spresense_main" diff --git a/configs/spresense/nsh/defconfig b/configs/spresense/nsh/defconfig index 00d1a5fa3da..817108b5cd6 100644 --- a/configs/spresense/nsh/defconfig +++ b/configs/spresense/nsh/defconfig @@ -56,4 +56,4 @@ CONFIG_SYSTEM_CLE=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_NSH_CXXINITIALIZE=y CONFIG_UART1_SERIAL_CONSOLE=y -CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_USER_ENTRYPOINT="spresense_main" diff --git a/configs/spresense/rndis/defconfig b/configs/spresense/rndis/defconfig index 0d30d533283..ae335dee991 100644 --- a/configs/spresense/rndis/defconfig +++ b/configs/spresense/rndis/defconfig @@ -7,6 +7,7 @@ # # CONFIG_MMCSD_HAVE_WRITEPROTECT is not set # CONFIG_MMCSD_SPI is not set +# CONFIG_MTD_SMART_WEAR_LEVEL is not set # CONFIG_STANDARD_SERIAL is not set CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="spresense" @@ -35,6 +36,7 @@ CONFIG_FS_FAT=y CONFIG_FS_FATTIME=y CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y @@ -68,6 +70,11 @@ CONFIG_NET_STATISTICS=y CONFIG_NET_TCP=y CONFIG_NET_UDP=y CONFIG_NET_UDP_BINDTODEVICE=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_SMART=y +CONFIG_MTD_SMART_ENABLE_CRC=y +CONFIG_MTD_SMART_SECTOR_SIZE=4096 CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NSH_ARCHINIT=y @@ -88,6 +95,9 @@ CONFIG_RTC=y CONFIG_SCHED_LPWORK=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y +CONFIG_SMARTFS_ALIGNED_ACCESS=y +CONFIG_SMARTFS_MAXNAMLEN=30 +CONFIG_SMARTFS_MULTI_ROOT_DIRS=y CONFIG_SPI=y CONFIG_STACK_COLORATION=y CONFIG_START_DAY=16 @@ -102,4 +112,4 @@ CONFIG_UART1_SERIAL_CONSOLE=y CONFIG_USBDEV=y CONFIG_USBDEV_DMA=y CONFIG_USBDEV_DUALSPEED=y -CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_USER_ENTRYPOINT="spresense_main" diff --git a/configs/spresense/usbmsc/defconfig b/configs/spresense/usbmsc/defconfig index 0d97b6c680c..4f71daeb5e1 100644 --- a/configs/spresense/usbmsc/defconfig +++ b/configs/spresense/usbmsc/defconfig @@ -8,6 +8,7 @@ # CONFIG_CXD56_I2C0_SCUSEQ is not set # CONFIG_MMCSD_HAVE_WRITEPROTECT is not set # CONFIG_MMCSD_SPI is not set +# CONFIG_MTD_SMART_WEAR_LEVEL is not set # CONFIG_STANDARD_SERIAL is not set CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="spresense" @@ -42,6 +43,7 @@ CONFIG_FAT_MAXFNAME=64 CONFIG_FS_FAT=y CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y @@ -49,6 +51,11 @@ CONFIG_MAX_TASKS=16 CONFIG_MAX_WDOGPARMS=2 CONFIG_MMCSD=y CONFIG_MMCSD_SDIO=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_SMART=y +CONFIG_MTD_SMART_ENABLE_CRC=y +CONFIG_MTD_SMART_SECTOR_SIZE=4096 CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NSH_ARCHINIT=y @@ -65,6 +72,9 @@ CONFIG_RTC=y CONFIG_RTC_DRIVER=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y +CONFIG_SMARTFS_ALIGNED_ACCESS=y +CONFIG_SMARTFS_MAXNAMLEN=30 +CONFIG_SMARTFS_MULTI_ROOT_DIRS=y CONFIG_SPI=y CONFIG_START_DAY=6 CONFIG_START_MONTH=12 @@ -83,4 +93,4 @@ CONFIG_USBDEV_DUALSPEED=y CONFIG_USBMSC=y CONFIG_USBMSC_COMPOSITE=y CONFIG_USBMSC_REMOVABLE=y -CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_USER_ENTRYPOINT="spresense_main" diff --git a/configs/spresense/usbnsh/defconfig b/configs/spresense/usbnsh/defconfig index ddb4b5ac214..f7df5d4034a 100644 --- a/configs/spresense/usbnsh/defconfig +++ b/configs/spresense/usbnsh/defconfig @@ -8,6 +8,7 @@ # CONFIG_CXD56_I2C0_SCUSEQ is not set # CONFIG_MMCSD_HAVE_WRITEPROTECT is not set # CONFIG_MMCSD_SPI is not set +# CONFIG_MTD_SMART_WEAR_LEVEL is not set # CONFIG_STANDARD_SERIAL is not set CONFIG_ARCH="arm" CONFIG_ARCH_BOARD="spresense" @@ -35,6 +36,7 @@ CONFIG_FAT_MAXFNAME=64 CONFIG_FS_FAT=y CONFIG_FS_PROCFS=y CONFIG_FS_PROCFS_REGISTER=y +CONFIG_FS_SMARTFS=y CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y CONFIG_I2C=y @@ -42,6 +44,11 @@ CONFIG_MAX_TASKS=16 CONFIG_MAX_WDOGPARMS=2 CONFIG_MMCSD=y CONFIG_MMCSD_SDIO=y +CONFIG_MTD_BYTE_WRITE=y +CONFIG_MTD_PARTITION=y +CONFIG_MTD_SMART=y +CONFIG_MTD_SMART_ENABLE_CRC=y +CONFIG_MTD_SMART_SECTOR_SIZE=4096 CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NSH_ARCHINIT=y @@ -58,6 +65,9 @@ CONFIG_RTC=y CONFIG_RTC_DRIVER=y CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y +CONFIG_SMARTFS_ALIGNED_ACCESS=y +CONFIG_SMARTFS_MAXNAMLEN=30 +CONFIG_SMARTFS_MULTI_ROOT_DIRS=y CONFIG_SPI=y CONFIG_START_DAY=6 CONFIG_START_MONTH=12 @@ -73,4 +83,4 @@ CONFIG_USBDEV_DUALSPEED=y CONFIG_USBMSC=y CONFIG_USBMSC_EPBULKIN=1 CONFIG_USBMSC_REMOVABLE=y -CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_USER_ENTRYPOINT="spresense_main" diff --git a/configs/spresense/wifi/defconfig b/configs/spresense/wifi/defconfig index b3bfef0baa6..9339db6af9c 100644 --- a/configs/spresense/wifi/defconfig +++ b/configs/spresense/wifi/defconfig @@ -85,6 +85,9 @@ CONFIG_SCHED_LPWORK=y CONFIG_SCHED_LPWORKPRIORITY=30 CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y +CONFIG_SMARTFS_ALIGNED_ACCESS=y +CONFIG_SMARTFS_MAXNAMLEN=30 +CONFIG_SMARTFS_MULTI_ROOT_DIRS=y CONFIG_STACK_COLORATION=y CONFIG_START_DAY=16 CONFIG_START_MONTH=7 @@ -100,7 +103,7 @@ CONFIG_USBDEV_DUALSPEED=y CONFIG_USBMSC=y CONFIG_USBMSC_EPBULKIN=1 CONFIG_USBMSC_REMOVABLE=y -CONFIG_USER_ENTRYPOINT="nsh_main" +CONFIG_USER_ENTRYPOINT="spresense_main" CONFIG_WIRELESS_GS2200M=y CONFIG_WL_GS2200M=y CONFIG_WL_GS2200M_SPI_FREQUENCY=10000000 diff --git a/drivers/lcd/tda19988.c b/drivers/lcd/tda19988.c index bdca8cb4220..19b905853a1 100644 --- a/drivers/lcd/tda19988.c +++ b/drivers/lcd/tda19988.c @@ -172,7 +172,7 @@ static int tda19988_unlink(FAR struct inode *inode); static int tda19988_hwinitialize(FAR struct tda1988_dev_s *priv); static int tda19988_videomode_internal(FAR struct tda1988_dev_s *priv, - FAR const struct tda19988_videomode_s *mode); + FAR const struct videomode_s *mode); #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS static void tda19988_shutdown(FAR struct tda1988_dev_s *priv); #endif @@ -229,7 +229,8 @@ static int tda19988_getregs(FAR const struct tda19988_i2c_s *dev, return -1; } - lcdinfo("Read: %02x:%02x->%02x\n", page, regaddr, *regval); + lcdinfo("Write: %02x<-%02x\n", regaddr, *regval); + lcderrdumpbuffer("Read:", regval, nregs); return OK; } @@ -263,7 +264,7 @@ static int tda19988_putreg(FAR const struct tda19988_i2c_s *dev, return ret; } - lcdinfo("Wrote: %02x:%02x<-%02x\n", page, regaddr, regval); + lcdinfo("Wrote: %02x<-%02x\n", regaddr, regval); return OK; } @@ -298,7 +299,7 @@ static int tda19988_putreg16(FAR const struct tda19988_i2c_s *dev, return ret; } - lcdinfo("Wrote: %02x:%02x<-%02x\n", page, regaddr, regval); + lcdinfo("Wrote: 02x<-%04x\n", regaddr, regval); return OK; } @@ -729,7 +730,7 @@ static int tda19988_fetch_edid(struct tda1988_dev_s *priv) goto done; } - blocks = priv->edid[EDID_TRAILER_NEXTENSIONS]; + blocks = priv->edid[EDID_TRAILER_NEXTENSIONS_OFFSET]; if (blocks > 0) { FAR uint8_t *edid; @@ -1125,15 +1126,15 @@ static int tda19988_ioctl(FAR struct file *filep, int cmd, unsigned long arg) * of the initialization of the driver. This is * equivalent to calling tda18899_videomode() within * the OS. - * Argument: A reference to a tda19988_videomode_s structure + * Argument: A reference to a videomode_s structure * instance. * Returns: None */ case TDA19988_IOC_VIDEOMODE: { - FAR const struct tda19988_videomode_s *mode = - (FAR const struct tda19988_videomode_s *)((uintptr_t)arg); + FAR const struct videomode_s *mode = + (FAR const struct videomode_s *)((uintptr_t)arg); if (mode == NULL) { @@ -1385,7 +1386,7 @@ done: static int tda19988_videomode_internal(FAR struct tda1988_dev_s *priv, - FAR const struct tda19988_videomode_s *mode) + FAR const struct videomode_s *mode) { uint16_t ref_pix; uint16_t ref_line; @@ -1462,7 +1463,7 @@ static int (mode->vsync_end - mode->vsync_start) / 2; } - div = 148500 / mode->dot_clock; + div = 148500 / mode->dotclock; if (div != 0) { if (--div > 3) @@ -1732,7 +1733,7 @@ TDA19988_HANDLE tda19988_register(FAR const char *devpath, ****************************************************************************/ int tda19988_videomode(TDA19988_HANDLE handle, - FAR const struct tda19988_videomode_s *mode) + FAR const struct videomode_s *mode) { FAR struct tda1988_dev_s *priv = (FAR struct tda1988_dev_s *)handle; int ret; diff --git a/drivers/sensors/Kconfig b/drivers/sensors/Kconfig index 394f9688938..0d6ed54a021 100644 --- a/drivers/sensors/Kconfig +++ b/drivers/sensors/Kconfig @@ -15,6 +15,13 @@ config APDS9960_I2C_FREQUENCY default 400000 depends on SENSORS_APDS9960 +config SENSORS_AK09912 + bool "Asahi AK09911/AK09912 Compass Sensor" + default n + select I2C + ---help--- + Enable driver for AK09911/AK09912 Compass sensor. + config SENSORS_AS5048B bool "AMS AS5048B Magnetic Rotary Encoder support" default n @@ -86,6 +93,13 @@ config SENSORS_BMP180 ---help--- Enable driver support for the Bosch BMP180 barometer sensor. +config SENSORS_BMP280 + bool "Bosch BMP280 Barometic Pressure Sensor" + default n + select I2C + ---help--- + Enable driver for the Bosch BMP280 barometic pressure sensor. + config SENSORS_DHTXX bool "DHTxx humidity/temperature Sensor support" default n @@ -724,6 +738,13 @@ config VEML6070_I2C_FREQUENCY default 100000 depends on SENSORS_VEML6070 +config SENSORS_VL53L1X + bool "ST VL53L1X TOF sensor" + default n + select I2C + ---help--- + Enable driver support for the VL53L1X Time Of Flight sensor. + config SENSORS_XEN1210 bool "Sensixs XEN1210 Magnetometer" default n diff --git a/drivers/sensors/Make.defs b/drivers/sensors/Make.defs index 360cbe18f21..3f4fde3fcdc 100644 --- a/drivers/sensors/Make.defs +++ b/drivers/sensors/Make.defs @@ -57,6 +57,10 @@ ifeq ($(CONFIG_SENSORS_APDS9960),y) CSRCS += apds9960.c endif +ifeq ($(CONFIG_SENSORS_AK09912),y) + CSRCS += ak09912.c +endif + ifeq ($(CONFIG_SENSORS_AS5048B),y) CSRCS += as5048b.c endif @@ -113,6 +117,11 @@ ifeq ($(CONFIG_SENSORS_BMP180),y) CSRCS += bmp180.c endif +ifeq ($(CONFIG_SENSORS_BMP280),y) + CSRCS += bmp280.c +endif + + ifeq ($(CONFIG_SENSORS_HTS221),y) CSRCS += hts221.c endif @@ -249,6 +258,12 @@ ifeq ($(CONFIG_SENSORS_VEML6070),y) CSRCS += veml6070.c endif +# ST VL53L1X + +ifeq ($(CONFIG_SENSORS_VL53L1X),y) + CSRCS += vl53l1x.c +endif + # Sensixs XEN1210 ifeq ($(CONFIG_SENSORS_XEN1210),y) diff --git a/drivers/sensors/ak09912.c b/drivers/sensors/ak09912.c new file mode 100644 index 00000000000..bd57a36227d --- /dev/null +++ b/drivers/sensors/ak09912.c @@ -0,0 +1,727 @@ +/**************************************************************************** + * drivers/sensors/ak09912.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_AK09912) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define AK09911_DEVID 0x05 +#define AK09912_DEVID 0x04 +#define AK09912_ADDR 0x0C +#define AK09912_FREQ 400000 + +/* REGISTER: WIA + * Who I am. + */ + +#define AK09912_WIA1 0x00 +#define AK09912_WIA2 0x01 + +/* REGISTER: CNTL2 + * Power mode + */ + +#define POWER_MODE_ADDR 0x31 + +/* REGISTER: ASAX + * Sensitivity values + */ + +#define AK09912_ASAX 0x60 + +/* REGISTER: CNTL1 + * Enable or disable temparator measure or enable or disable Noice suppression + * filter. + */ + +#define AK09912_CTRL1 0x30 + +/* REGISTER: HXL + * The start address of data registers. + */ + +#define AK09912_HXL 0x11 + +/* Polling timeout + * The unit is 10 millisecond. + */ + +#define AK09912_POLLING_TIMEOUT (1) // 10 ms + +/* The parameter for compensating. */ + +#define AK09912_SENSITIVITY (128) +#define AK09912_SENSITIVITY_DIV (256) + +/* Noice Suppression Filter */ + +#define AK09912_NSF_NONE 0b00 +#define AK09912_NSF_LOW 0b01 +#define AK09912_NSF_MIDDLE 0b10 +#define AK09912_NSF_HIGH 0b11 + +/* Power mode */ + +#define AKM_POWER_DOWN_MODE 0b0000 +#define AKM_SINGL_MEAS_MODE 0b00001 +#define AKM_CONT_MEAS_1 0b00010 +#define AKM_CONT_MEAS_2 0b00100 +#define AKM_CONT_MEAS_3 0b00110 +#define AKM_CONT_MEAS_4 0b01000 +#define AKM_EXT_TRIG_MODE 0b01010 +#define AKM_SELF_TEST_MODE 0b10000 +#define AKM_FUSE_ROM_MODE 0b11111 + +/* REGISTER: ST1 + * DRDY: Data ready bit. 0: not ready, 1: ready + * DOR: Data overrun. 0: Not overrun, 1: overrun + */ + +#define AK09912_ST1 0x10 + +#define SET_BITSLICE(s, v, offset, mask) \ +do { \ + s &= mask; \ + s |= (v << offset) & mask;} while(0) + +#define MERGE_BYTE(low, high) \ + ((low & 0xff) | ((high << 8) & ~0xff)) + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +/* Structure for compensating data. */ + +struct sensi_data_s +{ + uint8_t x; + uint8_t y; + uint8_t z; +}; + +/* Structure for ak09912 device */ + +struct ak09912_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* I2C address */ + int freq; /* Frequency <= 3.4MHz */ + int compensated; /* 0: uncompensated, 1:compensated */ + struct sensi_data_s asa_data; /* sensitivity data */ + uint8_t mode; /* power mode */ + uint8_t nsf; /* noice suppression filter setting */ + WDOG_ID wd; + sem_t wait; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Character driver methods */ + +static int ak09912_open(FAR struct file *filep); +static int ak09912_close(FAR struct file *filep); +static ssize_t ak09912_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t ak09912_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static int ak09912_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_ak09912fops = +{ + ak09912_open, /* open */ + ak09912_close, /* close */ + ak09912_read, /* read */ + ak09912_write, /* write */ + 0, /* seek */ + ak09912_ioctl, /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + 0, /* poll */ +#endif + 0 /* unlink */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ak09912_getreg8 + * + * Description: + * Read from an 8-bit BMP280 register + * + ****************************************************************************/ + +static uint8_t ak09912_getreg8(FAR struct ak09912_dev_s *priv, + uint8_t regaddr) +{ + struct i2c_msg_s msg[2]; + uint8_t regval = 0; + int ret; + + msg[0].frequency = priv->freq; + msg[0].addr = priv->addr; + msg[0].flags = 0; + msg[0].buffer = ®addr; + msg[0].length = 1; + + msg[1].frequency = priv->freq; + msg[1].addr = priv->addr; + msg[1].flags = I2C_M_READ; + msg[1].buffer = ®val; + msg[1].length = 1; + + ret = I2C_TRANSFER(priv->i2c, msg, 2); + if (ret < 0) + { + snerr("I2C_TRANSFER failed: %d\n", ret); + return 0; + } + + return regval; +} + +/**************************************************************************** + * Name: ak09912_putreg8 + * + * Description: + * Write to an 8-bit BMP280 register + * + ****************************************************************************/ + +static int ak09912_putreg8(FAR struct ak09912_dev_s *priv, + uint8_t regaddr, uint8_t regval) +{ + struct i2c_msg_s msg[2]; + int ret; + uint8_t txbuffer[2]; + + txbuffer[0] = regaddr; + txbuffer[1] = regval; + + msg[0].frequency = priv->freq; + msg[0].addr = priv->addr; + msg[0].flags = 0; + msg[0].buffer = txbuffer; + msg[0].length = 2; + + ret = I2C_TRANSFER(priv->i2c, msg, 1); + if (ret < 0) + { + snerr("I2C_TRANSFER failed: %d\n", ret); + } + return ret; +} + +/**************************************************************************** + * Name: ak09912_getreg + * + * Description: + * Read cnt bytes from a ak09912 register + * + ****************************************************************************/ + +static int32_t ak09912_getreg(FAR struct ak09912_dev_s *priv, + uint8_t regaddr, uint8_t* buffer, uint32_t cnt) +{ + struct i2c_msg_s msg[2]; + int ret; + + msg[0].frequency = priv->freq; + msg[0].addr = priv->addr; + msg[0].flags = 0; + msg[0].buffer = ®addr; + msg[0].length = 1; + + msg[1].frequency = priv->freq; + msg[1].addr = priv->addr; + msg[1].flags = I2C_M_READ; + msg[1].buffer = buffer; + msg[1].length = cnt; + + ret = I2C_TRANSFER(priv->i2c, msg, 2); + if (ret < 0) + { + snerr("I2C_TRANSFER failed: %d\n", ret); + return ret; + } + + return ret; +} + +/**************************************************************************** + * Name: ak09912_delay_msec + * + * Description: + * System level delay + * + ****************************************************************************/ + +void ak09912_delay_msek(uint16_t msek) +{ + /* This is used to short delay without schedule. */ + + up_udelay(msek * 1000); +} + +/**************************************************************************** + * Name: ak09912_set_power_mode + * + * Description: + * set POWER MODE for ak09912 + * + ****************************************************************************/ + +static int ak09912_set_power_mode(FAR struct ak09912_dev_s* priv, + uint32_t mode) +{ + int ret = 0; + ret = ak09912_putreg8(priv, POWER_MODE_ADDR, (uint8_t)mode); + ak09912_delay_msek(1); + return ret; +} + +/**************************************************************************** + * Name: ak09912_read_sensitivity_data + * + * Description: + * read sensitivity date in fuse mode. + * + ****************************************************************************/ + +static int ak09912_read_sensitivity_data(FAR struct ak09912_dev_s* priv, + FAR struct sensi_data_s* asa_data) +{ + int ret = 0; + uint8_t buffer[3]; + + ret = ak09912_getreg(priv, AK09912_ASAX, buffer, sizeof(buffer)); + if (ret == 0) + { + asa_data->x = buffer[0]; + asa_data->y = buffer[1]; + asa_data->z = buffer[2]; + } + return ret; +} + +/**************************************************************************** + * Name: ak09912_set_noice_suppr_flt + * + * Description: + * set noice suppression filter for ak09912 + * + ****************************************************************************/ + +static int ak09912_set_noice_suppr_flt(FAR struct ak09912_dev_s* priv, + uint32_t nsf) +{ + int ret = 0; + uint8_t ctrl1 = 0; + + ctrl1 = ak09912_getreg8(priv, AK09912_CTRL1); + SET_BITSLICE(ctrl1, nsf, 5, 0x60); + ret = ak09912_putreg8(priv, AK09912_CTRL1, ctrl1); + + return ret; +} + +/**************************************************************************** + * Name: ak09912_wd_timeout + * + * Description: + * a timer to check if data is ready. + * + ****************************************************************************/ + +static void ak09912_wd_timeout(int argc, uint32_t arg, ...) +{ + struct ak09912_dev_s *priv = (struct ak09912_dev_s *) arg; + irqstate_t flags = enter_critical_section(); + sem_post(&priv->wait); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: ak09912_read_mag_uncomp_data + * + * Description: + * read mag uncompensating data. + * + ****************************************************************************/ + +static int ak09912_read_mag_uncomp_data(FAR struct ak09912_dev_s* priv, + FAR struct mag_data_s* mag_data) +{ + int ret = 0; + uint8_t state = 0; + uint8_t buffer[8]; /* TMPS and ST2 is read, but the value is omitted. */ + + wd_start(priv->wd, AK09912_POLLING_TIMEOUT, ak09912_wd_timeout, + 1, (uint32_t)priv); + state = ak09912_getreg8(priv, AK09912_ST1); + while (! (state & 0x1)) + { + sem_wait(&priv->wait); + } + wd_cancel(priv->wd); + ret = ak09912_getreg(priv, AK09912_HXL, buffer, sizeof(buffer)); + + mag_data->x = MERGE_BYTE(buffer[0], buffer[1]); + mag_data->y = MERGE_BYTE(buffer[2], buffer[3]); + mag_data->z = MERGE_BYTE(buffer[4], buffer[5]); + + return ret; +} + +/**************************************************************************** + * Name: ak09912_read_mag_data + * + * Description: + * read mag data with compensation + * + ****************************************************************************/ + +static int ak09912_read_mag_data(FAR struct ak09912_dev_s* priv, + FAR struct mag_data_s* mag_data) +{ + int ret = 0; + + ret = ak09912_read_mag_uncomp_data(priv, mag_data); + if (ret < 0) + { + snerr("Failed to read mag data from device.\n"); + return ret; + } + + mag_data->x = (int16_t)(mag_data->x * + ((int32_t)priv->asa_data.x + AK09912_SENSITIVITY) / + AK09912_SENSITIVITY_DIV); + mag_data->y = (int16_t)(mag_data->y * + ((int32_t)priv->asa_data.y + AK09912_SENSITIVITY) / + AK09912_SENSITIVITY_DIV); + mag_data->z = (int16_t)(mag_data->z * + ((int32_t)priv->asa_data.z + AK09912_SENSITIVITY) / + AK09912_SENSITIVITY_DIV); + + return ret; +} + +/**************************************************************************** + * Name: ak09912_checkid + * + * Description: + * Read and verify the AK09912 chip ID + * + ****************************************************************************/ + +static int ak09912_checkid(FAR struct ak09912_dev_s *priv) +{ + uint16_t devid = 0; + + /* Read device ID */ + + devid = ak09912_getreg8(priv, AK09912_WIA1); + devid += ak09912_getreg8(priv, AK09912_WIA2) << 8; + sninfo("devid: 0x%02x\n", devid); + + if (devid != AK09911_DEVID && devid != AK09912_DEVID) + { + /* ID is not Correct */ + + snerr("Wrong Device ID! %02x\n", devid); + return -ENODEV; + } + + return OK; +} + +/**************************************************************************** + * Name: ak09912_updatecaldata + * + * Description: + * Update Calibration Coefficient Data + * + ****************************************************************************/ + +static int ak09912_initialize(FAR struct ak09912_dev_s *priv) +{ + int ret = 0; + + ret += ak09912_set_power_mode(priv, AKM_FUSE_ROM_MODE); + ret += ak09912_read_sensitivity_data(priv, &priv->asa_data); + ret += ak09912_set_power_mode(priv, AKM_POWER_DOWN_MODE); + ret += ak09912_set_noice_suppr_flt(priv, priv->nsf); + return ret; +} + +/**************************************************************************** + * Name: ak09912_open + * + * Description: + * This function is called whenever the AK09912 device is opened. + * + ****************************************************************************/ + +static int ak09912_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ak09912_dev_s *priv = inode->i_private; + int ret = 0; + + ret = ak09912_set_power_mode(priv, priv->mode); + if (ret < 0) + { + snerr("Failed to set power mode to %d.\n", priv->mode); + return ret; + } + return OK; +} + +/**************************************************************************** + * Name: ak09912_close + * + * Description: + * This routine is called when the AK09912 device is closed. + * + ****************************************************************************/ + +static int ak09912_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ak09912_dev_s *priv = inode->i_private; + int ret = 0; + + ret = ak09912_set_power_mode(priv, AKM_POWER_DOWN_MODE); + if (ret < 0) + { + snerr("Failed to set power mode to %d.\n", AKM_POWER_DOWN_MODE); + return ret; + } + return OK; +} + +/**************************************************************************** + * Name: ak09912_read + ****************************************************************************/ + +static ssize_t ak09912_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ak09912_dev_s *priv = inode->i_private; + int32_t ret = 0; + struct mag_data_s* mag_data = (struct mag_data_s*)buffer; + + if (! buffer) + { + snerr("Buffer is null\n"); + return -1; + } + + if (buflen != sizeof(struct mag_data_s)) + { + snerr("You can't read something other than 32 bits (4 bytes)\n"); + return -1; + } + + if (priv->compensated) + { + irqstate_t flags = enter_critical_section(); + ret = ak09912_read_mag_data(priv, mag_data); + leave_critical_section(flags); + } + else + { + irqstate_t flags = enter_critical_section(); + ret = ak09912_read_mag_uncomp_data(priv, mag_data); + leave_critical_section(flags); + } + + if (ret < 0) + { + snerr("Failed to read data from ak09912.\n"); + return ret; + } + + return sizeof(struct mag_data_s); +} + +/**************************************************************************** + * Name: ak09912_write + ****************************************************************************/ + +static ssize_t ak09912_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: ak09912_write + ****************************************************************************/ + +static int ak09912_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct ak09912_dev_s *priv = inode->i_private; + int ret = OK; + + switch (cmd) + { + case SNIOC_ENABLE_COMPENSATED: + priv->compensated = (int)arg; + break; + default: + snerr("Unrecognized cmd: %d\n", cmd); + ret = - ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: ak09912_register + * + * Description: + * Register the AK09912 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/compass0" + * i2c - An instance of the I2C interface to use to communicate with + * AK09912 + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int ak09912_register(FAR const char *devpath, FAR struct i2c_master_s *i2c) +{ + FAR struct ak09912_dev_s *priv; + char path[16]; + int ret; + + /* Initialize the AK09912 device structure */ + + priv = (FAR struct ak09912_dev_s *)kmm_malloc(sizeof(struct ak09912_dev_s)); + if (!priv) + { + snerr("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = AK09912_ADDR; + priv->freq = AK09912_FREQ; + priv->compensated = ENABLE_COMPENSATED; + priv->wd = wd_create(); + sem_init(&priv->wait, 0, 0); + + /* set default noice suppression filter. */ + + priv->nsf = AK09912_NSF_LOW; + + /* set default power mode */ + + priv->mode = AKM_CONT_MEAS_4; + + /* Check Device ID */ + + ret = ak09912_checkid(priv); + if (ret < 0) + { + snerr("Failed to register driver: %d\n", ret); + kmm_free(priv); + return ret; + } + + ret = ak09912_initialize(priv); + if (ret < 0) + { + snerr("Failed to initialize physical device ak09912:%d\n", ret); + kmm_free(priv); + return ret; + } + + /* Register the character driver */ + + (void) snprintf(path, sizeof(path), "%s%d", devpath, 0); + ret = register_driver(path, &g_ak09912fops, 0666, priv); + if (ret < 0) + { + snerr("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + sninfo("AK09912 driver loaded successfully!\n"); + return ret; +} + +#endif /* CONFIG_I2C && CONFIG_SENSORS_AK09912 */ diff --git a/drivers/sensors/bmp280.c b/drivers/sensors/bmp280.c new file mode 100644 index 00000000000..fca3d6331bf --- /dev/null +++ b/drivers/sensors/bmp280.c @@ -0,0 +1,723 @@ +/**************************************************************************** + * drivers/sensors/bmp280.c + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_BMP280) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define BMP280_ADDR 0x76 +#define BMP280_FREQ 400000 +#define DEVID 0x58 + +#define BMP280_DIG_T1_LSB 0x88 +#define BMP280_DIG_T1_MSB 0x89 +#define BMP280_DIG_T2_LSB 0x8a +#define BMP280_DIG_T2_MSB 0x8b +#define BMP280_DIG_T3_LSB 0x8c +#define BMP280_DIG_T3_MSB 0x8d +#define BMP280_DIG_P1_LSB 0x8e +#define BMP280_DIG_P1_MSB 0x8f +#define BMP280_DIG_P2_LSB 0x90 +#define BMP280_DIG_P2_MSB 0x91 +#define BMP280_DIG_P3_LSB 0x92 +#define BMP280_DIG_P3_MSB 0x93 +#define BMP280_DIG_P4_LSB 0x94 +#define BMP280_DIG_P4_MSB 0x95 +#define BMP280_DIG_P5_LSB 0x96 +#define BMP280_DIG_P5_MSB 0x97 +#define BMP280_DIG_P6_LSB 0x98 +#define BMP280_DIG_P6_MSB 0x99 +#define BMP280_DIG_P7_LSB 0x9a +#define BMP280_DIG_P7_MSB 0x9b +#define BMP280_DIG_P8_LSB 0x9c +#define BMP280_DIG_P8_MSB 0x9d +#define BMP280_DIG_P9_LSB 0x9e +#define BMP280_DIG_P9_MSB 0x9f + +#define BMP280_DEVID 0xd0 +#define BMP280_SOFT_RESET 0xe0 +#define BMP280_STAT 0xf3 +#define BMP280_CTRL_MEAS 0xf4 +#define BMP280_CONFIG 0xf5 +#define BMP280_PRESS_MSB 0xf7 +#define BMP280_PRESS_LSB 0xf8 +#define BMP280_PRESS_XLSB 0xf9 +#define BMP280_TEMP_MSB 0xfa +#define BMP280_TEMP_LSB 0xfb +#define BMP280_TEMP_XLSB 0xfc + +/* Power modes */ + +#define BMP280_SLEEP_MODE (0x00) +#define BMP280_FORCED_MODE (0x01) +#define BMP280_NORMAL_MODE (0x03) + +/* Oversampling for temperature. */ + +#define BMP280_OST_SKIPPED (0x00 << 5) +#define BMP280_OST_X1 (0x01 << 5) +#define BMP280_OST_X2 (0x02 << 5) +#define BMP280_OST_X4 (0x03 << 5) +#define BMP280_OST_X8 (0x04 << 5) +#define BMP280_OST_X16 (0x05 << 5) + +/* Oversampling for pressure. */ + +#define BMP280_OSP_SKIPPED (0x00 << 2) +#define BMP280_OSP_X1 (0x01 << 2) +#define BMP280_OSP_X2 (0x02 << 2) +#define BMP280_OSP_X4 (0x03 << 2) +#define BMP280_OSP_X8 (0x04 << 2) +#define BMP280_OSP_X16 (0x05 << 2) + +/* Predefined oversampling combinations. */ + +#define BMP280_OS_ULTRA_HIGH_RES (BMP280_OSP_X16 | BMP280_OST_X2) +#define BMP280_OS_STANDARD_RES (BMP280_OSP_X4 | BMP280_OST_X1) +#define BMP280_OS_ULTRA_LOW_POWER (BMP280_OSP_X1 | BMP280_OST_X1) + +/* Data combined from bytes to int */ + +#define COMBINE(d) (((int)(d)[0] << 12) | ((int)(d)[1] << 4) | ((int)(d)[2] >> 4)) + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +struct bmp280_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* BMP280 I2C address */ + int freq; /* BMP280 Frequency <= 3.4MHz */ + int compensated; /* 0: uncompensated, 1:compensated */ + struct bmp280_calib_s + { + uint16_t t1; + int16_t t2; + int16_t t3; + uint16_t p1; + int16_t p2; + int16_t p3; + int16_t p4; + int16_t p5; + int16_t p6; + int16_t p7; + int16_t p8; + int16_t p9; + } calib; + + int32_t tempfine; +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static uint8_t bmp280_getreg8(FAR struct bmp280_dev_s *priv, uint8_t regaddr); +static void bmp280_putreg8(FAR struct bmp280_dev_s *priv, uint8_t regaddr, + uint8_t regval); +static uint32_t bmp280_getpressure(FAR struct bmp280_dev_s *priv); + +/* Character driver methods */ + +static int bmp280_open(FAR struct file *filep); +static int bmp280_close(FAR struct file *filep); +static ssize_t bmp280_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static int bmp280_ioctl(FAR struct file *filep, int cmd, unsigned long arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_bmp280fops = +{ + bmp280_open, /* open */ + bmp280_close, /* close */ + bmp280_read, /* read */ + 0, /* write */ + 0, /* seek */ + bmp280_ioctl, /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + 0, /* poll */ +#endif + 0 /* unlink */ +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: bmp280_getreg8 + * + * Description: + * Read from an 8-bit BMP280 register + * + ****************************************************************************/ + +static uint8_t bmp280_getreg8(FAR struct bmp280_dev_s *priv, uint8_t regaddr) +{ + struct i2c_msg_s msg[2]; + uint8_t regval = 0; + int ret; + + msg[0].frequency = priv->freq; + msg[0].addr = priv->addr; + msg[0].flags = 0; + msg[0].buffer = ®addr; + msg[0].length = 1; + + msg[1].frequency = priv->freq; + msg[1].addr = priv->addr; + msg[1].flags = I2C_M_READ; + msg[1].buffer = ®val; + msg[1].length = 1; + + ret = I2C_TRANSFER(priv->i2c, msg, 2); + if (ret < 0) + { + snerr("I2C_TRANSFER failed: %d\n", ret); + return 0; + } + + return regval; +} + +/**************************************************************************** + * Name: bmp280_getregs + * + * Description: + * Read two 8-bit from a BMP280 register + * + ****************************************************************************/ + +static int bmp280_getregs(FAR struct bmp280_dev_s *priv, uint8_t regaddr, + uint8_t *rxbuffer, uint8_t length) +{ + struct i2c_msg_s msg[2]; + int ret; + + msg[0].frequency = priv->freq; + msg[0].addr = priv->addr; + msg[0].flags = 0; + msg[0].buffer = ®addr; + msg[0].length = 1; + + msg[1].frequency = priv->freq; + msg[1].addr = priv->addr; + msg[1].flags = I2C_M_READ; + msg[1].buffer = rxbuffer; + msg[1].length = length; + + ret = I2C_TRANSFER(priv->i2c, msg, 2); + if (ret < 0) + { + snerr("I2C_TRANSFER failed: %d\n", ret); + return -1; + } + + return OK; +} + +/**************************************************************************** + * Name: bmp280_putreg8 + * + * Description: + * Write to an 8-bit BMP280 register + * + ****************************************************************************/ + +static void bmp280_putreg8(FAR struct bmp280_dev_s *priv, uint8_t regaddr, + uint8_t regval) +{ + struct i2c_msg_s msg[2]; + uint8_t txbuffer[2]; + int ret; + + txbuffer[0] = regaddr; + txbuffer[1] = regval; + + msg[0].frequency = priv->freq; + msg[0].addr = priv->addr; + msg[0].flags = 0; + msg[0].buffer = txbuffer; + msg[0].length = 2; + + ret = I2C_TRANSFER(priv->i2c, msg, 1); + if (ret < 0) + { + snerr("I2C_TRANSFER failed: %d\n", ret); + } +} + +/**************************************************************************** + * Name: bmp280_checkid + * + * Description: + * Read and verify the BMP280 chip ID + * + ****************************************************************************/ + +static int bmp280_checkid(FAR struct bmp280_dev_s *priv) +{ + uint8_t devid = 0; + + /* Read device ID */ + + devid = bmp280_getreg8(priv, BMP280_DEVID); + up_mdelay(1); + sninfo("devid: 0x%02x\n", devid); + + if (devid != (uint16_t) DEVID) + { + /* ID is not Correct */ + + snerr("Wrong Device ID! %02x\n", devid); + return -ENODEV; + } + + return OK; +} + +/**************************************************************************** + * Name: bmp280_set_standby + * + * Description: + * set standby duration + * + ****************************************************************************/ + +static int bmp280_set_standby(FAR struct bmp280_dev_s *priv, uint8_t value) +{ + uint8_t v_data_u8; + uint8_t v_sb_u8; + + /* Set the standby duration value */ + + v_data_u8 = bmp280_getreg8(priv, BMP280_CONFIG); + v_data_u8 = (v_data_u8 & ~(0x07 << 5)) | (value << 5); + bmp280_putreg8(priv, BMP280_CONFIG, v_data_u8); + + /* Check the standby duration value */ + + v_data_u8 = bmp280_getreg8(priv, BMP280_CONFIG); + v_sb_u8 = (v_data_u8 >> 5) & 0x07; + + if (v_sb_u8 != value) + { + snerr("Failed to set value for standby time."); + return ERROR; + } + + return OK; +} + +/**************************************************************************** + * Name: bmp280_initialize + * + * Description: + * Initialize BMP280 device + * + ****************************************************************************/ + +static int bmp280_initialize(FAR struct bmp280_dev_s *priv) +{ + uint8_t buf[24]; + int ret; + + /* Get calibration data. */ + + ret = bmp280_getregs(priv, BMP280_DIG_T1_LSB, buf, 24); + if (ret < 0) + { + return ret; + } + + priv->calib.t1 = (uint16_t)buf[1] << 8 | buf[0]; + priv->calib.t2 = (int16_t) buf[3] << 8 | buf[2]; + priv->calib.t3 = (int16_t) buf[5] << 8 | buf[4]; + + priv->calib.p1 = (uint16_t)buf[ 7] << 8 | buf[ 6]; + priv->calib.p2 = (int16_t) buf[ 9] << 8 | buf[ 8]; + priv->calib.p3 = (int16_t) buf[11] << 8 | buf[10]; + priv->calib.p4 = (int16_t) buf[13] << 8 | buf[12]; + priv->calib.p5 = (int16_t) buf[15] << 8 | buf[14]; + priv->calib.p6 = (int16_t) buf[17] << 8 | buf[16]; + priv->calib.p7 = (int16_t) buf[19] << 8 | buf[18]; + priv->calib.p8 = (int16_t) buf[21] << 8 | buf[20]; + priv->calib.p9 = (int16_t) buf[23] << 8 | buf[22]; + + sninfo("T1 = %u\n", priv->calib.t1); + sninfo("T2 = %d\n", priv->calib.t2); + sninfo("T3 = %d\n", priv->calib.t3); + + sninfo("P1 = %u\n", priv->calib.p1); + sninfo("P2 = %d\n", priv->calib.p2); + sninfo("P3 = %d\n", priv->calib.p3); + sninfo("P4 = %d\n", priv->calib.p4); + sninfo("P5 = %d\n", priv->calib.p5); + sninfo("P6 = %d\n", priv->calib.p6); + sninfo("P7 = %d\n", priv->calib.p7); + sninfo("P8 = %d\n", priv->calib.p8); + sninfo("P9 = %d\n", priv->calib.p9); + + /* Set power mode to sleep */ + + bmp280_putreg8(priv, BMP280_CTRL_MEAS, BMP280_SLEEP_MODE); + + /* Set stand-by time to 1 ms, no IIR filter */ + + ret = bmp280_set_standby(priv, BMP280_STANDBY_1_MS); + if (ret != OK) + { + snerr("Failed to set value for standby time.\n"); + return -1; + } + + return ret; +} + +/**************************************************************************** + * Name: bmp280_compensate + * + * Description: + * calculate compensate tempreture + * + * Input Parameters: + * temp - uncompensate value of tempreture. + * + * Returned Value: + * calculate result of compensate tempreture. + * + ****************************************************************************/ + +static int32_t bmp280_compensate_temp(FAR struct bmp280_dev_s *priv, + int32_t temp) +{ + struct bmp280_calib_s *c = &priv->calib; + int32_t var1; + int32_t var2; + + var1 = ((((temp >> 3) - ((int32_t)c->t1 << 1))) * ((int32_t)c->t2)) >> 11; + var2 = (((((temp >> 4) - ((int32_t)c->t1)) * + ((temp >> 4) - ((int32_t)c->t1))) >> 12) * + ((int32_t)c->t3)) >> 14; + + priv->tempfine = var1 + var2; + + return (priv->tempfine * 5 + 128) >> 8; +} + +/**************************************************************************** + * Name: bmp280_compensate_press + * + * Description: + * calculate compensate pressure + * + * Input Parameters: + * press - uncompensate value of pressure. + * + * Returned Value: + * calculate result of compensate pressure. + * + ****************************************************************************/ + +static uint32_t bmp280_compensate_press(FAR struct bmp280_dev_s *priv, + uint32_t press, int32_t temp) +{ + struct bmp280_calib_s *c = &priv->calib; + int32_t var1; + int32_t var2; + uint32_t p; + + /* Update temperature fine value first. */ + + (void) bmp280_compensate_temp(priv, temp); + + var1 = (priv->tempfine >> 1) - 64000; + var2 = (((var1 >> 2) * (var1 >> 2)) >> 11 ) * ((int32_t)c->p6); + var2 = var2 + ((var1 * ((int32_t)c->p5)) << 1); + var2 = (var2 >> 2) + (((int32_t)c->p4) << 16); + var1 = (((c->p3 * (((var1 >> 2) * (var1 >> 2)) >> 13 )) >> 3) + + ((((int32_t)c->p2) * var1) >> 1)) >> 18; + var1 = (((32768 + var1) * ((int32_t)c->p1)) >> 15); + + /* avoid exception caused by division by zero */ + + if (var1 == 0) + { + return 0; + } + + p = (((uint32_t)((0x100000) - press) - (var2 >> 12))) * 3125; + + if (p < 0x80000000) + { + p = (p << 1) / ((uint32_t)var1); + } + else + { + p = (p / (uint32_t)var1) * 2; + } + + var1 = ((int32_t)c->p9 * ((int32_t)(((p >> 3) * (p >> 3)) >> 13))) >> 12; + var2 = ((int32_t)(p >> 2) * c->p8) >> 13; + p = (uint32_t)((int32_t)p + ((var1 + var2 + c->p7) >> 4)); + + return p; +} + +/**************************************************************************** + * Name: bmp280_getpressure + * + * Description: + * Calculate the Barometric Pressure using the temperature compensated + * See BMP280 data sheet for details + * + ****************************************************************************/ + +static uint32_t bmp280_getpressure(FAR struct bmp280_dev_s *priv) +{ + uint8_t buf[6]; + uint32_t press; + int32_t temp; + + bmp280_getregs(priv, BMP280_PRESS_MSB, buf, 6); + + press = (uint32_t)COMBINE(buf); + temp = COMBINE(&buf[3]); + + sninfo("press = %d, temp = %d\n", press, temp); + + if (priv->compensated == ENABLE_COMPENSATED) + { + press = bmp280_compensate_press(priv, press, temp); + } + + return press; +} + +/**************************************************************************** + * Name: bmp280_open + * + * Description: + * This function is called whenever the BMP280 device is opened. + * + ****************************************************************************/ + +static int bmp280_open(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct bmp280_dev_s *priv = inode->i_private; + + /* Set power mode to normal and standard sampling resolusion. */ + + bmp280_putreg8(priv, BMP280_CTRL_MEAS, BMP280_NORMAL_MODE | + BMP280_OS_STANDARD_RES); + + return OK; +} + +/**************************************************************************** + * Name: bmp280_close + * + * Description: + * This routine is called when the BMP280 device is closed. + * + ****************************************************************************/ + +static int bmp280_close(FAR struct file *filep) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct bmp280_dev_s *priv = inode->i_private; + + /* Set power mode to sleep */ + + bmp280_putreg8(priv, BMP280_CTRL_MEAS, BMP280_SLEEP_MODE); + + return OK; +} + +/**************************************************************************** + * Name: bmp280_read + ****************************************************************************/ + +static ssize_t bmp280_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct bmp280_dev_s *priv = inode->i_private; + FAR uint32_t *press = (FAR uint32_t *) buffer; + + if (!buffer) + { + snerr("Buffer is null\n"); + return -1; + } + + if (buflen < 4) + { + snerr("You can't read something other than 32 bits (4 bytes)\n"); + return -1; + } + + /* Get the pressure compensated */ + + *press = bmp280_getpressure(priv); + + /* Return size of uint32_t (4 bytes) */ + + return 4; +} + +/**************************************************************************** + * Name: bmp280_ioctl + ****************************************************************************/ + +static int bmp280_ioctl(FAR struct file *filep, int cmd, unsigned long arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct bmp280_dev_s *priv = inode->i_private; + int ret = OK; + + switch (cmd) + { + case SNIOC_ENABLE_COMPENSATED: + priv->compensated = (int)arg; + break; + + case SNIOC_SETSTB: + ret = bmp280_set_standby(priv, arg); + break; + + default: + snerr("Unrecognized cmd: %d\n", cmd); + ret = - ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: bmp280_register + * + * Description: + * Register the BMP280 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/press0" + * i2c - An instance of the I2C interface to use to communicate with + * BMP280 + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int bmp280_register(FAR const char *devpath, FAR struct i2c_master_s *i2c) +{ + FAR struct bmp280_dev_s *priv; + int ret; + + /* Initialize the BMP280 device structure */ + + priv = (FAR struct bmp280_dev_s *)kmm_malloc(sizeof(struct bmp280_dev_s)); + if (!priv) + { + snerr("Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = BMP280_ADDR; + priv->freq = BMP280_FREQ; + priv->compensated = ENABLE_COMPENSATED; + + /* Check Device ID */ + + ret = bmp280_checkid(priv); + if (ret < 0) + { + snerr("Failed to register driver: %d\n", ret); + kmm_free(priv); + return ret; + } + + ret = bmp280_initialize(priv); + if (ret < 0) + { + snerr("Failed to initialize physical device bmp280:%d\n", ret); + kmm_free(priv); + return ret; + } + + /* Register the character driver */ + + ret = register_driver(devpath, &g_bmp280fops, 0666, priv); + if (ret < 0) + { + snerr("Failed to register driver: %d\n", ret); + kmm_free(priv); + } + + sninfo("BMP280 driver loaded successfully!\n"); + return ret; +} + +#endif diff --git a/drivers/sensors/vl53l1x.c b/drivers/sensors/vl53l1x.c new file mode 100644 index 00000000000..580ef479aed --- /dev/null +++ b/drivers/sensors/vl53l1x.c @@ -0,0 +1,1195 @@ +/**************************************************************************** + * drivers/sensors/vl53l1x.c + * Character driver for the ST vl53l1x distance. + * + * Copyright (C) 2019 Acutronics Robotics + * Author: Acutronics Robotics (Juan Flores Muñoz) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 OWNER 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_VL53L1X) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define VL53L1X_FREQ 100000 +#define VL53L1X_ADDR 0x29 + +/**************************************************************************** + * Private Type Definitions + ****************************************************************************/ + +struct vl53l1x_dev_s +{ + FAR struct i2c_master_s *i2c; /* I2C interface */ + uint8_t addr; /* VL53L0X I2C address */ + int freq; /* VL53L0X Frequency */ +}; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint8_t g_vl51l1x_default_config[] = +{ + 0x00, + 0x00, + 0x00, + 0x01, + 0x02, + 0x00, + 0x02, + 0x08, + 0x00, + 0x08, + 0x10, + 0x01, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0xff, + 0x00, + 0x0f, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x20, + 0x0b, + 0x00, + 0x00, + 0x02, + 0x0a, + 0x21, + 0x00, + 0x00, + 0x05, + 0x00, + 0x00, + 0x00, + 0x00, + 0xc8, + 0x00, + 0x00, + 0x38, + 0xff, + 0x01, + 0x00, + 0x08, + 0x00, + 0x00, + 0x01, + 0xdb, + 0x0f, + 0x01, + 0xf1, + 0x0d, + 0x01, + 0x68, + 0x00, + 0x80, + 0x08, + 0xb8, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0f, + 0x89, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x01, + 0x0f, + 0x0d, + 0x0e, + 0x0e, + 0x00, + 0x00, + 0x02, + 0xc7, + 0xff, + 0x9b, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00 +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* I2C operations */ + +static uint8_t vl53l1x_getreg8(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr); +static uint16_t vl53l1x_getreg16(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr); +static uint32_t vl53l1x_getreg32(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr); +static void vl53l1x_putreg8(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr, uint8_t regval); +static void vl53l1x_putreg16(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr, uint16_t regval); +static void vl53l1x_putreg32(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr, uint32_t regval); + +/* Basic driver operations */ + +static void vl53l1x_startranging(FAR struct vl53l1x_dev_s *priv); +static void vl53l1x_stopranging(FAR struct vl53l1x_dev_s *priv); +static void vl53l1x_sensorinit(FAR struct vl53l1x_dev_s *priv); +static void vl53l1x_getdistance(FAR struct vl53l1x_dev_s *priv, + FAR uint16_t *distance); + +/* Set data operations */ + +static void vl53l1x_settimingbudget(FAR struct vl53l1x_dev_s *priv, + uint16_t ms_value); +static void vl53l1x_setdistancemode(FAR struct vl53l1x_dev_s *priv, + uint16_t mode); + +/* Get data operations */ + +static void vl53l1x_gettimingbudget(FAR struct vl53l1x_dev_s *priv, + FAR uint16_t *ms_value); +static void vl53l1x_getdistancemode(FAR struct vl53l1x_dev_s *priv, + FAR uint16_t *dm); +static void vl53l1x_getid(FAR struct vl53l1x_dev_s *priv, FAR uint16_t *id); +static void vl53l1x_getoffset(FAR struct vl53l1x_dev_s *priv, + FAR int16_t *offset); +static void vl53l1x_getintstate(FAR struct vl53l1x_dev_s *priv, + FAR uint8_t *state); + +/* Other operations */ + +static void vl53l1x_clearint(FAR struct vl53l1x_dev_s *priv); +static void vl53l1x_dataready(FAR struct vl53l1x_dev_s *priv, + FAR uint8_t *dataready); +static void vl53l1x_tempupdate(FAR struct vl53l1x_dev_s *priv); +static void vl53l1x_calibrateoffset(FAR struct vl53l1x_dev_s *priv, + uint16_t target_distance, + FAR int16_t *offset); + +/* Character driver methods */ + +static int vl53l1x_open(FAR struct file *filep); +static int vl53l1x_close(FAR struct file *filep); +static void vl53l1x_read(FAR struct file *filep, FAR char *buffer, + size_t buflen); +static ssize_t vl53l1x_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen); +static void vl53l1x_ioctl(FAR struct file *filep, int cmd, uint16_t arg); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct file_operations g_vl53l1xfops = +{ + vl53l1x_open, /* open */ + vl53l1x_close, /* close */ + vl53l1x_read, /* read */ + vl53l1x_write, /* write */ + NULL, /* seek */ + vl53l1x_ioctl, /* ioctl */ +#ifndef CONFIG_DISABLE_POLL + NULL, /* poll */ +#endif +#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS + NULL, /* unlink */ +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vl53l1x_SensorInit + * + * Description: + * This function loads the 135 bytes default values to initialize the sensor. + * + ****************************************************************************/ + +static void vl53l1x_sensorinit(FAR struct vl53l1x_dev_s *priv) +{ + uint8_t addr = 0x00; + uint8_t tmp = 0; + + for (addr = 0x2d; addr <= 0x87; addr++) + { + vl53l1x_putreg8(priv, addr, g_vl51l1x_default_config[addr - 0x2d]); + } + + vl53l1x_startranging(priv); + + while (tmp == 0) + { + vl53l1x_dataready(priv, &tmp); + } + + vl53l1x_clearint(priv); + vl53l1x_stopranging(priv); + vl53l1x_putreg8(priv, TIMEOUT_MACROP_LOOP_BOUND, 0x09); + vl53l1x_putreg8(priv, 0x0b, 0); +} + +/**************************************************************************** + * Name: vl53l1x_clearint + * + * Description: + * This function clears the interrupt, to be called after a ranging data + * reading to arm the interrupt for the next data ready event. + * + ****************************************************************************/ + +static void vl53l1x_clearint(FAR struct vl53l1x_dev_s *priv) +{ + vl53l1x_putreg8(priv, INTERRUPT_CLEAR, 0x01); +} + +/**************************************************************************** + * Name: vl53l1x_startranging + * + * Description: + * This function starts the ranging distance operation. The ranging ops + * is continuous. The clear interrupt has to be done after each get data to + * allow the interrupt to raise when the next data is ready. + * + ****************************************************************************/ + +static void vl53l1x_startranging(FAR struct vl53l1x_dev_s *priv) +{ + vl53l1x_putreg8(priv, SYSTEM_MODE, 0x40); +} + +/**************************************************************************** + * Name: vl53l1x_StopRanging + * + * Description: + * This function stops the ranging. + * + ****************************************************************************/ + +static void vl53l1x_stopranging(FAR struct vl53l1x_dev_s *priv) +{ + vl53l1x_putreg8(priv, SYSTEM_MODE, 0x00); +} + +/**************************************************************************** + * Name: vl53l1x_dataready + * + * Description: + * This function checks if the new ranging data is available by polling the + * dedicated register. + * + ****************************************************************************/ + +static void vl53l1x_dataready(FAR struct vl53l1x_dev_s *priv, + FAR uint8_t *dataready) +{ + uint8_t temp; + uint8_t intpol; + + temp = vl53l1x_getreg8(priv, GPIO_STATUS); + vl53l1x_getintstate(priv, &intpol); + + /* Read in the register to check if a new value is available */ + + if ((temp & 1) == intpol) + { + *dataready = 1; + } + else + { + *dataready = 0; + } +} + +/**************************************************************************** + * Name: vl53l1x_getinterruptstate + * + * Description: + * This function returns the current interrupt polarity. + * + ****************************************************************************/ + +static void vl53l1x_getintstate(FAR struct vl53l1x_dev_s *priv, + FAR uint8_t *state) +{ + uint8_t temp; + + temp = vl53l1x_getreg8(priv, GPIO_MUX_CTRL); + temp = temp & 0x10; + *state = !(temp >> 4); +} + +/**************************************************************************** + * Name: VL53L1X_GetTimingBudgetInMs + * + * Description: + * This function returns the timing budget in ms. + * + ****************************************************************************/ + +static void vl53l1x_gettimingbudget(FAR struct vl53l1x_dev_s *priv, + FAR uint16_t *ms_value) +{ + uint16_t temp; + + temp = vl53l1x_getreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI); + + switch (temp) + { + case 0x001d: + *ms_value = 15; + break; + + case 0x0051: + case 0x001e: + *ms_value = 20; + break; + + case 0x00d6: + case 0x0060: + *ms_value = 33; + break; + + case 0x1ae: + case 0x00ad: + *ms_value = 50; + break; + + case 0x02e1: + case 0x01cc: + *ms_value = 100; + break; + + case 0x03e1: + case 0x02d9: + *ms_value = 200; + break; + + case 0x0591: + case 0x048f: + *ms_value = 500; + break; + + default: + *ms_value = 0; + break; + } +} + +/**************************************************************************** + * Name: vl53l1x_settimingbudget + * + * Description: + * This function programs the timing budget in ms. + * + ****************************************************************************/ + +static void vl53l1x_settimingbudget(FAR struct vl53l1x_dev_s *priv, + uint16_t ms_value) +{ + uint16_t dm; + vl53l1x_getdistancemode(priv, &dm); + + /* Short Distance */ + + if (dm == 1) + { + switch (ms_value) + { + case 15: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x01d); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x0027); + } + break; + + case 20: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x0051); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x006e); + } + break; + + case 33: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x00d6); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x006e); + } + break; + + case 50: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x1ae); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x01e8); + } + break; + + case 100: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x02e1); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x0388); + } + break; + + case 200: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x03e1); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x0496); + } + break; + + case 500: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x0591); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x05c1); + } + break; + + default: + break; + } + } + else + { + switch (ms_value) + { + case 20: + { + vl53l1x_putreg16(priv, PHASECAL_TIMEOUT_MACRO, 0x001e); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x0022); + } + break; + + case 33: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x0060); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x006e); + } + break; + + case 50: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x00ad); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x00c6); + } + break; + + case 100: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x01cc); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x01ea); + } + break; + + case 200: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x02d9); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x02f8); + } + break; + + case 500: + { + vl53l1x_putreg16(priv, RANGE_CFG_TIMEOUT_MACRO_HI, 0x048f); + vl53l1x_putreg16(priv, RANGE_TIMEOUT_MACRO_HI, 0x04a4); + } + break; + + default: + break; + } + } +} + +/**************************************************************************** + * Name: vl53l1x_setdistancemode + * + * Description: + * This function programs the distance mode (1=short, 2=long(default)). + * Short mode max distance is limited to 1.3 m but better ambient immunity. + * Long mode can range up to 4 m in the dark with 200 ms timing budget. + * + ****************************************************************************/ + +static void vl53l1x_setdistancemode(FAR struct vl53l1x_dev_s *priv, + uint16_t dm) +{ + uint16_t tb; + + vl53l1x_gettimingbudget(priv, &tb); + switch (dm) + { + case 1: + { + vl53l1x_putreg8(priv, PHASECAL_TIMEOUT_MACRO, 0x14); + vl53l1x_putreg8(priv, RANGE_VCSEL_PERIOD_A, 0x07); + vl53l1x_putreg8(priv, RANGE_VCSEL_PERIOD_B, 0x05); + vl53l1x_putreg8(priv, RANGE_CFG_VALID_PHASE, 0x38); + vl53l1x_putreg16(priv, SD_CFG_WOI_SD0, 0x0705); + vl53l1x_putreg16(priv, SD_CFG_INIT_PHASE, 0x0606); + } + break; + + case 2: + { + vl53l1x_putreg8(priv, PHASECAL_TIMEOUT_MACRO, 0x0a); + vl53l1x_putreg8(priv, RANGE_VCSEL_PERIOD_A, 0x0f); + vl53l1x_putreg8(priv, RANGE_VCSEL_PERIOD_B, 0x0d); + vl53l1x_putreg8(priv, RANGE_CFG_VALID_PHASE, 0xb8); + vl53l1x_putreg16(priv, SD_CFG_WOI_SD0, 0x0f0d); + vl53l1x_putreg16(priv, SD_CFG_INIT_PHASE, 0x0e0e); + } + break; + + default: + break; + } + + vl53l1x_settimingbudget(priv, tb); +} + +/**************************************************************************** + * Name: vl53l1x_getdistancemode + * + * Description: + * This function returns the current distance mode (1=short, 2=long). + * + ****************************************************************************/ + +static void vl53l1x_getdistancemode(FAR struct vl53l1x_dev_s *priv, + FAR uint16_t *dm) +{ + uint8_t mode_read; + + mode_read = vl53l1x_getreg8(priv, PHASECAL_TIMEOUT_MACRO); + if (mode_read == 0x14) + { + *dm = 1; + } + + if (mode_read == 0x0a) + { + *dm = 2; + } +} + +/**************************************************************************** + * Name: vl53l1x_getid + * + * Description: + * This function returns the sensor id, sensor Id must be 0xeeac. + * + ****************************************************************************/ + +static void vl53l1x_getid(FAR struct vl53l1x_dev_s *priv, FAR uint16_t *id) +{ + uint16_t tmp = 0; + + tmp = vl53l1x_getreg16(priv, VL53L1_GET_ID); + *id = tmp; +} + +/**************************************************************************** + * Name: vl53l1x_GetDistance + * + * Description: + * This function returns the distance measured by the sensor in mm. + * + ****************************************************************************/ + +static void vl53l1x_getdistance(FAR struct vl53l1x_dev_s *priv, + FAR uint16_t *distance) +{ + uint16_t tmp; + + tmp = vl53l1x_getreg16(priv, VL53L1_GET_DISTANCE); + *distance = tmp; +} + +/**************************************************************************** + * Name: vl53l1x_getoffset + * + * Description: + * This function returns the programmed offset correction value in mm. + * + ****************************************************************************/ + +static void vl53l1x_getoffset(FAR struct vl53l1x_dev_s *priv, + FAR int16_t *offset) +{ + uint16_t temp; + + temp = vl53l1x_getreg16(priv, RANGE_OFFSET_MM); + + temp = temp << 3; + temp = temp >> 5; + + *offset = (int16_t) (temp); +} + +/**************************************************************************** + * Name: vl53l1x_tempupdate + * + * Description: + * This function performs the temperature calibration. It is recommended to + * call this function any time the temperature might have changed by more + * tahn 8 deg C without sensor ranging activity for an extended period. + * + ****************************************************************************/ + +static void vl53l1x_tempupdate(FAR struct vl53l1x_dev_s *priv) +{ + uint8_t tmp = 0; + + vl53l1x_putreg8(priv, TIMEOUT_MACROP_LOOP_BOUND, 0x81); + vl53l1x_putreg8(priv, 0x0b, 0x92); + + vl53l1x_startranging(priv); + + while (tmp == 0) + { + vl53l1x_dataready(priv, &tmp); + } + + vl53l1x_clearint(priv); + vl53l1x_stopranging(priv); + + vl53l1x_putreg8(priv, TIMEOUT_MACROP_LOOP_BOUND, 0x09); + vl53l1x_putreg8(priv, 0x0b, 0); +} + +/**************************************************************************** + * Name: vl53l1x_calibrateoffset + * + * Description: + * The function returns the offset value found and programs the offset + * compensation into the device. + * + ****************************************************************************/ + +static void vl53l1x_calibrateoffset(FAR struct vl53l1x_dev_s *priv, + uint16_t target_distance, + FAR int16_t *offset) +{ + uint8_t i = 0; + uint8_t tmp; + int16_t average_distance = 0; + uint16_t distance; + + vl53l1x_putreg16(priv, RANGE_OFFSET_MM, 0x0); + vl53l1x_putreg16(priv, INNER_OFFSET_MM, 0x0); + vl53l1x_putreg16(priv, OUTER_OFFSET_MM, 0x0); + + vl53l1x_startranging(priv); + + for (i = 0; i < 50; i++) + { + while (tmp == 0) + { + vl53l1x_dataready(priv, &tmp); + } + + vl53l1x_getdistance(priv, &distance); + vl53l1x_clearint(priv); + + average_distance = average_distance + distance; + } + vl53l1x_stopranging(priv); + + average_distance = average_distance / 50; + *offset = target_distance - average_distance; + + vl53l1x_putreg16(priv, RANGE_OFFSET_MM, *offset *4); +} + +/**************************************************************************** + * Name: vl53l1x_getreg8 + * + * Description: + * Read from an 8-bit vl53l1x register + * + ****************************************************************************/ + +static uint8_t vl53l1x_getreg8(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr) +{ + struct i2c_config_s config; + + uint8_t regval = 0; + uint16_t ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; + + /* Write the register address */ + + ret = i2c_write(priv->i2c, &config, (uint8_t *)®addr, 2); + if (ret < 0) + { + snerr("ERROR: i2c_write failed: %d\n", ret); + return ret; + } + + /* Read the register value */ + + ret = i2c_read(priv->i2c, &config, ®val, 1); + if (ret < 0) + { + snerr("ERROR: i2c_read failed: %d\n", ret); + return ret; + } + + return regval; +} + +/**************************************************************************** + * Name: bmp180_getreg16 + * + * Description: + * Read two 8-bit from a BMP180 register + * + ****************************************************************************/ + +static uint16_t vl53l1x_getreg16(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr) +{ + struct i2c_config_s config; + + uint16_t msb; + uint16_t lsb; + uint16_t regval = 0; + uint8_t reg_addr_aux[2]; + uint8_t ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; + + /* Split the I2C direction */ + + reg_addr_aux[0] = (regaddr >> 8) & 0xff; + reg_addr_aux[1] = regaddr; + + /* Register to read */ + + sninfo("Reg %02x % \r\n", reg_addr_aux[0], reg_addr_aux[1]); + ret = i2c_write(priv->i2c, &config, (uint8_t *)®_addr_aux, 2); + if (ret < 0) + { + snerr("ERROR: i2c_write failed: %d\n", ret); + return ret; + } + + /* Read register */ + + ret = i2c_read(priv->i2c, &config, (uint8_t *) & regval, 2); + if (ret < 0) + { + snerr("ERROR: i2c_read failed: %d\n", ret); + return ret; + } + + /* MSB and LSB are inverted */ + + msb = (regval & 0xff); + lsb = (regval & 0xff00) >> 8; + + regval = (msb << 8) | lsb; + + return regval; +} + +/**************************************************************************** + * Name: vl53l1x_getreg32 + * + * Description: + * Read 4 8-bit from a vl53l1x register + * + ****************************************************************************/ + +static uint32_t vl53l1x_getreg32(FAR struct vl53l1x_dev_s *priv, + uint16_t regaddr) +{ + struct i2c_config_s config; + + uint16_t byte[4]; + uint32_t regval = 0; + uint8_t ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; + + /* Register to read */ + + ret = i2c_write(priv->i2c, &config, (FAR uint8_t *)®addr, 2); + if (ret < 0) + { + snerr("ERROR: i2c_write failed: %d\n", ret); + return ret; + } + + /* Read register */ + + ret = i2c_read(priv->i2c, &config, (FAR uint8_t *) & regval, 4); + if (ret < 0) + { + snerr("ERROR: i2c_read failed: %d\n", ret); + return ret; + } + + /* The bytes are in the opposite order of importance */ + + byte[0] = (regval & 0xff); + byte[1] = (regval & 0xff00) >> 8; + byte[2] = (regval & 0xffff00) >> 16; + byte[3] = (regval & 0xffffff00) >> 24; + + regval = (byte[0] << 24) | (byte[1] << 16) | (byte[2] << 8) | byte[3]; + + return regval; +} + +/**************************************************************************** + * Name: vl53l1x_putreg8 + * + * Description: + * Write to an 8-bit vl53l1x register + * + ****************************************************************************/ + +static void vl53l1x_putreg8(FAR struct vl53l1x_dev_s *priv, uint16_t regaddr, + uint8_t regval) +{ + struct i2c_config_s config; + uint8_t data[3]; + int ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; + + data[0] = (regaddr >> 8) & 0xff; + data[1] = regaddr; + data[2] = regval & 0xff; + + /* Write the register address and value */ + + ret = i2c_write(priv->i2c, &config, (uint8_t *) & data, 3); + if (ret < 0) + { + snerr("ERROR: i2c_write failed: %d\n", ret); + return; + } + + return; +} + +/**************************************************************************** + * Name: vl53l1x_putreg16 + * + * Description: + * Write to an 16-bit vl53l1x register + * + ****************************************************************************/ + +static void vl53l1x_putreg16(FAR struct vl53l1x_dev_s *priv, uint16_t regaddr, + uint16_t regval) +{ + struct i2c_config_s config; + uint8_t data[4]; + int ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; + + data[0] = (regaddr >> 8) & 0xff; + data[1] = regaddr; + data[2] = (regval >> 8) & 0xff; + data[3] = regval & 0xff; + + /* Write the register address and value */ + + ret = i2c_write(priv->i2c, &config, (uint8_t *) & data, 4); + if (ret < 0) + { + snerr("ERROR: i2c_write failed: %d\n", ret); + return; + } + + return; +} + +/**************************************************************************** + * Name: vl53l1x_putreg32 + * + * Description: + * Write to an 32-bit vl53l1x register + * + ****************************************************************************/ + +static void vl53l1x_putreg32(FAR struct vl53l1x_dev_s *priv, uint16_t regaddr, + uint32_t regval) +{ + struct i2c_config_s config; + uint8_t data[7]; + int ret; + + /* Set up the I2C configuration */ + + config.frequency = priv->freq; + config.address = priv->addr; + config.addrlen = 7; + + data[0] = (regaddr >> 8) & 0xff; + data[1] = regaddr; + data[2] = (regval >> 24) & 0xff; + data[4] = (regval >> 16) & 0xff; + data[5] = (regval >> 8) & 0xff; + data[6] = regval & 0xff; + + /* Write the register address and value */ + + ret = i2c_write(priv->i2c, &config, (uint8_t *) & data, 7); + if (ret < 0) + { + snerr("ERROR: i2c_write failed: %d\n", ret); + return; + } + + return; +} + +/**************************************************************************** + * Name: vl53l1x_open + * + * Description: + * This function is called whenever the vl53l1x device is opened. + * + ****************************************************************************/ + +static int vl53l1x_open(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: vl53l1x_close + * + * Description: + * This routine is called when the vl53l1x device is closed. + * + ****************************************************************************/ + +static int vl53l1x_close(FAR struct file *filep) +{ + return OK; +} + +/**************************************************************************** + * Name: vl53l1x_read + ****************************************************************************/ + +static void vl53l1x_read(FAR struct file *filep, FAR char *buffer, + size_t buflen) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct vl53l1x_dev_s *priv = inode->i_private; + FAR uint16_t *aux = (FAR uint16_t *) buffer; + + vl53l1x_startranging(priv); + vl53l1x_getdistance(priv, aux); + vl53l1x_stopranging(priv); +} + +/**************************************************************************** + * Name: vl53l1x_write + ****************************************************************************/ + +static ssize_t vl53l1x_write(FAR struct file *filep, FAR const char *buffer, + size_t buflen) +{ + return -ENOSYS; +} + +/**************************************************************************** + * Name: vl53l1x_ioctl + ****************************************************************************/ + +static void vl53l1x_ioctl(FAR struct file *filep, int cmd, uint16_t arg) +{ + FAR struct inode *inode = filep->f_inode; + FAR struct vl53l1x_dev_s *priv = inode->i_private; + + switch (cmd) + { + case SNIOC_DISTANCESHORT: + { + sninfo("Set distance up to 1.3M\n"); + vl53l1x_setdistancemode(priv, 1); + } + break; + + case SNIOC_DISTANCELONG: + { + sninfo("Set distance up to 4M\n"); + vl53l1x_setdistancemode(priv, 2); + } + break; + + case SNIOC_CALIBRATE: + { + sninfo("Calibrating distance\n"); + int16_t offset; + vl53l1x_getoffset(priv, (int16_t *)&offset); + vl53l1x_calibrateoffset(priv, arg, (int16_t *)&offset); + } + break; + + case SNIOC_TEMPUPDATE: + { + sninfo("Recalculating due to temperature change\n"); + vl53l1x_tempupdate(priv); + } + break; + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vl53l1x_register + * + * Description: + * Register the vl53l1x character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/tof" + * i2c - An instance of the I2C interface to use to communicate with + * vl53l1x TOF + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int vl53l1x_register(FAR const char *devpath, FAR struct i2c_master_s *i2c) +{ + FAR struct vl53l1x_dev_s *priv; + int ret = 0; + uint16_t id; + + /* Initialize the vl53l1x device structure */ + + priv = (FAR struct vl53l1x_dev_s *)kmm_malloc(sizeof(struct vl53l1x_dev_s)); + if (!priv) + { + snerr("ERROR: Failed to allocate instance\n"); + return -ENOMEM; + } + + priv->i2c = i2c; + priv->addr = VL53L1X_ADDR; + priv->freq = VL53L1X_FREQ; + + vl53l1x_sensorinit(priv); + + vl53l1x_getid(priv, &id); + if (id != 0xeacc) + { + snerr("ERROR: Failed sensor ID %04x\n", id); + kmm_free(priv); + return 0; + } + + register_driver(devpath, &g_vl53l1xfops, 0666, priv); + if (ret < 0) + { + snerr("ERROR: Failed to register driver: %d\n", ret); + kmm_free(priv); + return 0; + } + + sninfo("vl53l1x driver loaded successfully!\n"); + return 1; +} + +#endif /* CONFIG_I2C && CONFIG_SENSORS_VL53L1X */ diff --git a/drivers/wireless/gs2200m.c b/drivers/wireless/gs2200m.c index 542371623ae..e25a8d588fc 100644 --- a/drivers/wireless/gs2200m.c +++ b/drivers/wireless/gs2200m.c @@ -173,6 +173,7 @@ struct gs2200m_dev_s uint16_t aip_cid_bits; uint8_t tx_buff[MAX_PKT_LEN]; struct net_driver_s net_dev; + uint8_t op_mode; FAR const struct gs2200m_lower_s *lower; }; @@ -1369,10 +1370,18 @@ errout: static enum pkt_type_e gs2200m_set_opmode(FAR struct gs2200m_dev_s *dev, uint8_t mode) { + enum pkt_type_e t; char cmd[20]; snprintf(cmd, sizeof(cmd), "AT+WM=%d\r\n", mode); - return gs2200m_send_cmd(dev, cmd, NULL); + t = gs2200m_send_cmd(dev, cmd, NULL); + + if (TYPE_OK == t) + { + dev->op_mode = mode; + } + + return t; } /**************************************************************************** @@ -1471,7 +1480,7 @@ static enum pkt_type_e gs2200m_set_security(FAR struct gs2200m_dev_s *dev, ****************************************************************************/ static enum pkt_type_e gs2200m_join_network(FAR struct gs2200m_dev_s *dev, - FAR char *ssid) + FAR char *ssid, uint8_t ch) { struct pkt_dat_s pkt_dat; enum pkt_type_e r; @@ -1482,7 +1491,18 @@ static enum pkt_type_e gs2200m_join_network(FAR struct gs2200m_dev_s *dev, /* Initialize pkt_dat and send command */ memset(&pkt_dat, 0, sizeof(pkt_dat)); - snprintf(cmd, sizeof(cmd), "AT+WA=%s\r\n", ssid); + + if (0 == dev->op_mode) + { + snprintf(cmd, sizeof(cmd), "AT+WA=%s\r\n", ssid); + } + else + { + /* In AP mode, we can specify chennel to use */ + + snprintf(cmd, sizeof(cmd), "AT+WA=%s,,%d\r\n", ssid, ch); + } + r = gs2200m_send_cmd(dev, cmd, &pkt_dat); if (r != TYPE_OK) @@ -2155,7 +2175,7 @@ static int gs2200m_ioctl_assoc_sta(FAR struct gs2200m_dev_s *dev, /* Associate with AP */ - if (TYPE_OK != gs2200m_join_network(dev, msg->ssid)) + if (TYPE_OK != gs2200m_join_network(dev, msg->ssid, 0)) { wlerr("*** error: failed to join (ssid:%s) \n", msg->ssid); return -1; @@ -2222,9 +2242,10 @@ static int gs2200m_ioctl_assoc_ap(FAR struct gs2200m_dev_s *dev, /* Enable the AP */ - if (TYPE_OK != gs2200m_join_network(dev, msg->ssid)) + if (TYPE_OK != gs2200m_join_network(dev, msg->ssid, msg->ch)) { - wlerr("*** error: failed to join (ssid:%s) \n", msg->ssid); + wlerr("*** error: failed to join (ssid:%s, ch:%d) \n", + msg->ssid, msg->ch); return -1; } diff --git a/include/cxx/cstddef b/include/cxx/cstddef index 74811d830b1..5c2ca53ed1c 100644 --- a/include/cxx/cstddef +++ b/include/cxx/cstddef @@ -76,6 +76,9 @@ namespace std using ::socklen_t; using ::sa_family_t; +#if __cplusplus >= 201103L + using nullptr_t = decltype(nullptr); +#endif } #endif // __INCLUDE_CXX_CSTDDEF diff --git a/include/nuttx/lcd/tda19988.h b/include/nuttx/lcd/tda19988.h index 8b77c00a621..b958261b0e8 100644 --- a/include/nuttx/lcd/tda19988.h +++ b/include/nuttx/lcd/tda19988.h @@ -46,6 +46,7 @@ #include #include #include +#include #ifdef CONFIG_LCD_TDA19988 @@ -59,30 +60,13 @@ * Description: Select the video mode. This must be done as part of the * initialization of the driver. This is equivalent to * calling tda18899_videomode() within the OS. - * Argument: A reference to a tda19988_videomode_s structure instance. - * See struct tda19988_videomode_s below. + * Argument: A reference to a videomode_s structure instance. + * See struct videomode_s below. * Returns: None */ #define TDA19988_IOC_VIDEOMODE _LCDIOC(TDA19988_NIOCTL_BASE + 0) -/* Values for video mode flags */ - -#define VID_PHSYNC 0x0001 -#define VID_NHSYNC 0x0002 -#define VID_PVSYNC 0x0004 -#define VID_NVSYNC 0x0008 -#define VID_INTERLACE 0x0010 -#define VID_DBLSCAN 0x0020 -#define VID_CSYNC 0x0040 -#define VID_PCSYNC 0x0080 -#define VID_NCSYNC 0x0100 -#define VID_HSKEW 0x0200 -#define VID_BCAST 0x0400 -#define VID_PIXMUX 0x1000 -#define VID_DBLCLK 0x2000 -#define VID_CLKDIV2 0x4000 - /**************************************************************************** * Public Types ****************************************************************************/ @@ -91,26 +75,6 @@ typedef FAR void *TDA19988_HANDLE; -/* Structure that provides the TDA19988 video mode */ - -struct tda19988_videomode_s -{ - int dot_clock; /* Dot clock frequency in kHz. */ - - int hdisplay; - int hsync_start; - int hsync_end; - int htotal; - - int vdisplay; - int vsync_start; - int vsync_end; - int vtotal; - - int flags; /* Video mode flags; see above. */ - int hskew; -}; - /* This structure defines the I2C interface. * REVISIT: This could be simplified because the CEC and HDMI reside on * the same I2C bus (pins CSCL and CSCA). @@ -210,7 +174,7 @@ TDA19988_HANDLE tda19988_register(FAR const char *devpath, ****************************************************************************/ int tda19988_videomode(TDA19988_HANDLE handle, - FAR const struct tda19988_videomode_s *mode); + FAR const struct videomode_s *mode); /**************************************************************************** * Name: tda19988_read_edid diff --git a/include/nuttx/sensors/ak09912.h b/include/nuttx/sensors/ak09912.h new file mode 100644 index 00000000000..a8c3e23791f --- /dev/null +++ b/include/nuttx/sensors/ak09912.h @@ -0,0 +1,122 @@ +/**************************************************************************** + * include/nuttx/sensors/ak09912.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 OWNER 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SENSORS_AK09912_H +#define __INCLUDE_NUTTX_SENSORS_AK09912_H + +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_AK09912) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Prerequisites: + * + * CONFIG_AK09912 + * Enables support for the AK09912 driver + */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct i2c_master_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* IOCTL Commands ***********************************************************/ + +/* Arg: 0: Disable compensated + * 1: Enable compensated + */ + +#define ENABLE_COMPENSATED (1) +#define DISABLE_COMPENSATED (0) +#define SNIOC_ENABLE_COMPENSATED _SNIOC(0x0001) + +#define SNIOC_GETADJ _SNIOC(0x0002) + +struct mag_data_s +{ + int16_t x; /* X raw data */ + int16_t y; /* Y raw data */ + int16_t z; /* Z raw data */ +}; + +struct ak09912_sensadj_s +{ + uint8_t x; + uint8_t y; + uint8_t z; +}; + +/**************************************************************************** + * Name: ak09912_register + * + * Description: + * Register the AK09912 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/mag0" + * i2c - An instance of the I2C interface to use to communicate with + * AK09912 + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ +int ak09912_register(FAR const char *devpath, FAR struct i2c_master_s *i2c); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_AK09912 */ +#endif /* __DRIVERS_AK09912_H */ diff --git a/include/nuttx/sensors/bmp280.h b/include/nuttx/sensors/bmp280.h new file mode 100644 index 00000000000..45467ce7073 --- /dev/null +++ b/include/nuttx/sensors/bmp280.h @@ -0,0 +1,165 @@ +/**************************************************************************** + * include/nuttx/sensors/bmp280.h + * + * Copyright 2018 Sony Semiconductor Solutions Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name of Sony Semiconductor Solutions Corporation nor + * the names of its contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * 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 OWNER 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SENSORS_BMP280_H +#define __INCLUDE_NUTTX_SENSORS_BMP280_H + +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_BMP280) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* Prerequisites: + * + * CONFIG_BMP280 + * Enables support for the BMP280 driver + */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct i2c_master_s; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/* IOCTL Commands ***********************************************************/ + +/* Arg: 0: Disable compensated + * 1: Enable compensated + */ + +#define ENABLE_COMPENSATED (1) +#define DISABLE_COMPENSATED (0) + +/* Standby duration */ + +#define BMP280_STANDBY_1_MS (0x00) /* 0.5 ms */ +#define BMP280_STANDBY_63_MS (0x01) /* 62.5 ms */ +#define BMP280_STANDBY_125_MS (0x02) /* 125 ms */ +#define BMP280_STANDBY_250_MS (0x03) /* 250 ms */ +#define BMP280_STANDBY_500_MS (0x04) /* 500 ms */ +#define BMP280_STANDBY_1000_MS (0x05) /* 1000 ms */ +#define BMP280_STANDBY_2000_MS (0x06) /* 2000 ms */ +#define BMP280_STANDBY_4000_MS (0x07) /* 4000 ms */ + +/* Enable compensate of sensing values (no SCU bus only) + * + * Arg: ENABLE_COMPENSATED or DISABLE_COMPENSATED + */ + +#define SNIOC_ENABLE_COMPENSATED _SNIOC(0x0001) + +/* Get sensor predefined adjustment values (SCU bus only) + * + * Arg: Pointer of struct bmp280_press_adj_s (pressure) + * Pointer of struct bmp280_temp_adj_s (temperature) + */ + +#define SNIOC_GETADJ _SNIOC(0x0002) + +/* Set sensor standby duration + * + * Arg: BMP280_STANDBY_*_MS + */ + +#define SNIOC_SETSTB _SNIOC(0x0003) + +struct bmp280_press_adj_s +{ + uint16_t dig_p1; /** calibration P1 data */ + int16_t dig_p2; /** calibration P2 data */ + int16_t dig_p3; /** calibration P3 data */ + int16_t dig_p4; /** calibration P4 data */ + int16_t dig_p5; /** calibration P5 data */ + int16_t dig_p6; /** calibration P6 data */ + int16_t dig_p7; /** calibration P7 data */ + int16_t dig_p8; /** calibration P8 data */ + int16_t dig_p9; /** calibration P9 data */ +}; + +struct bmp280_temp_adj_s +{ + uint16_t dig_t1; /** calibration T1 data */ + int16_t dig_t2; /** calibration T2 data */ + int16_t dig_t3; /** calibration T3 data */ +}; + +struct bmp280_meas_s +{ + uint8_t msb; /** meas value MSB */ + uint8_t lsb; /** meas value LSB */ + uint8_t xlsb; /** meas value XLSB */ +}; + +/**************************************************************************** + * Name: bmp280_register + * + * Description: + * Register the BMP280 character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/press" + * i2c - An instance of the I2C interface to use to communicate with + * BMP280 + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ +int bmp280_register(FAR const char *devpath, FAR struct i2c_master_s *i2c); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_SENSORS_BMP280 */ +#endif /* __INCLUDE_NUTTX_BMP280_H */ diff --git a/include/nuttx/sensors/ioctl.h b/include/nuttx/sensors/ioctl.h index 3c0a2d6d595..508be61c577 100644 --- a/include/nuttx/sensors/ioctl.h +++ b/include/nuttx/sensors/ioctl.h @@ -210,4 +210,11 @@ #define SNIOC_SET_CLEAN_INTERVAL _SNIOC(0x005d) /* Arg: uint32_t value (seconds) */ #define SNIOC_START_FAN_CLEANING _SNIOC(0x005e) /* Arg: None */ +/* IOCTL commands unique to the VL53L1X */ + +#define SNIOC_DISTANCESHORT _SNIOC(0x0100) /* Arg: None */ +#define SNIOC_DISTANCELONG _SNIOC(0x0101) /* Arg: None */ +#define SNIOC_CALIBRATE _SNIOC(0x0102) /* Arg: b16_t value */ +#define SNIOC_TEMPUPDATE _SNIOC(0x0103) /* Arg: b16_t value */ + #endif /* __INCLUDE_NUTTX_SENSORS_IOCTL_H */ diff --git a/include/nuttx/sensors/vl53l1x.h b/include/nuttx/sensors/vl53l1x.h new file mode 100644 index 00000000000..d160b18edb7 --- /dev/null +++ b/include/nuttx/sensors/vl53l1x.h @@ -0,0 +1,114 @@ +/**************************************************************************** + * drivers/sensors/vl53l1x.h + * + * Copyright (C) 2019 Acutronics Robotics. All rights reserved. + * Author: Acutronics Robotics (Juan Flores Muñoz) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 OWNER 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SENSORS_VL53L1X_H +#define __INCLUDE_NUTTX_SENSORS_VL53L1X_H + +#include + +#if defined(CONFIG_I2C) && defined(CONFIG_SENSORS_VL53L1X) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define VL53L1X_I2C_PORTNO 1 + +#define SOFT_RESET 0x0000 +#define TIMEOUT_MACROP_LOOP_BOUND 0x0008 +#define RANGE_OFFSET_MM 0x001e +#define INNER_OFFSET_MM 0x0020 +#define OUTER_OFFSET_MM 0x0022 +#define GPIO_MUX_CTRL 0x0030 +#define GPIO_STATUS 0x0031 +#define PHASECAL_TIMEOUT_MACRO 0x004b +#define RANGE_CFG_TIMEOUT_MACRO_HI 0x005e +#define RANGE_VCSEL_PERIOD_A 0x0060 +#define RANGE_VCSEL_PERIOD_B 0x0063 +#define RANGE_TIMEOUT_MACRO_HI 0x0061 +#define RANGE_CFG_VALID_PHASE 0x0069 +#define SYSTEM__THRESH_HIGH 0x0072 +#define SYSTEM__THRESH_LOW 0x0074 +#define SD_CFG_WOI_SD0 0x0078 +#define SD_CFG_INIT_PHASE 0x007a +#define INTERRUPT_CLEAR 0x0086 +#define SYSTEM_MODE 0x0087 +#define EFFECTIVE_SPADS 0x008c +#define VL53L1_GET_DISTANCE 0x0096 +#define SIGNAL_COUNT_RATE 0x0098 +#define VL53L1_SYSTEM_STATUS 0x00e5 +#define VL53L1_GET_ID 0x010f + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef __cplusplus +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/**************************************************************************** + * Name: vl53l1x_register + * + * Description: + * Register the VL53L1X character device as 'devpath' + * + * Input Parameters: + * devpath - The full path to the driver to register. E.g., "/dev/tof0" + * i2c - An instance of the I2C interface to use to communicate with + * VL53L1X + * + * Returned Value: + * Zero (OK) on success; a negated errno value on failure. + * + ****************************************************************************/ + +int vl53l1x_register(FAR const char *devpath, FAR struct i2c_master_s *i2c); + +#undef EXTERN +#ifdef __cplusplus +} +#endif + +#endif /* CONFIG_I2C && CONFIG_SENSORS_VL53L1X */ +#endif /* __INCLUDE_NUTTX_SENSORS_VL53L1X_H */ diff --git a/include/nuttx/video/edid.h b/include/nuttx/video/edid.h index fec2add6c3d..29eb8688d0a 100644 --- a/include/nuttx/video/edid.h +++ b/include/nuttx/video/edid.h @@ -5,10 +5,10 @@ * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * - * Reference: Wikipedia + * Reference: Wikipedia (initial version) * - * Some of structures in this file derive from FreeBSD which has a - * compatible 2-clause BSD license: + * Updated and extended with definitions from FreeBSD which has a compatible 2-clause BSD + * license: * * Copyright (c) 2006 Itronix Inc. All rights reserved. * Written by Garrett D'Amore for Itronix Inc. @@ -50,6 +50,7 @@ ********************************************************************************************/ #include +#include /******************************************************************************************** * Pre-processor Definitions @@ -168,6 +169,8 @@ /* For digital input: */ #define EDID_DISPLAY_INPUT_VIDIF_SHIFT (0) /* Bits 0-3: Video interface */ +#define EDID_DISPLAY_INPUT_VIDIF_MASK (15 << EDID_DISPLAY_INPUT_VIDIF_SHIFT) +# define EDID_DISPLAY_INPUT_DFP1_COMPAT (1 << EDID_DISPLAY_INPUT_VIDIF_SHIFT) #define EDID_DISPLAY_INPUT_BITDEPTH_SHIFT (4) /* Bits 4-6: Bit depth */ #define EDID_DISPLAY_INPUT_BITDEPTH_MASK (7 << EDID_DISPLAY_INPUT_BITDEPTH_SHIFT) @@ -180,9 +183,13 @@ * supported */ #define EDID_DISPLAY_INPUT_SYNC (1 << 3) /* Bit 3: Separate sync supported */ #define EDID_DISPLAY_INPUT_BLANK2BLACK (1 << 4) /* Bit 4: Blank to black setup */ -#define EDID_DISPLAY_INPUT_LEVELS_SHIFT (0) /* Bits 5-6: Video white and sync levels, +#define EDID_DISPLAY_INPUT_LEVELS_SHIFT (5) /* Bits 5-6: Video white and sync levels, * relative to blank */ #define EDID_DISPLAY_INPUT_LEVELS_MASK (3 << EDID_DISPLAY_INPUT_LEVELS_SHIFT) +# define EDID_DISPLAY_INPUT_LEVEL_1 (0 << EDID_DISPLAY_INPUT_LEVELS_SHIFT) /* -0.7, 0.3V */ +# define EDID_DISPLAY_INPUT_LEVEL_2 (1 << EDID_DISPLAY_INPUT_LEVELS_SHIFT) /* -0.714, 0.286V */ +# define EDID_DISPLAY_INPUT_LEVEL_3 (2 << EDID_DISPLAY_INPUT_LEVELS_SHIFT) /* -1.0, 0.4V */ +# define EDID_DISPLAY_INPUT_LEVEL_4 (3 << EDID_DISPLAY_INPUT_LEVELS_SHIFT) /* -0.7, 0.0V */ /* Display Section: Supported Features */ @@ -204,6 +211,10 @@ #define EDID_DISPLAY_FEATURE_ATYPE_MASK (3 << EDID_DISPLAY_FEATURE_ATYPE_SHIFT) #define EDID_DISPLAY_FEATURE_DTYPE_SHIFT (3) /* Bits 3-4: Display type (digital) */ #define EDID_DISPLAY_FEATURE_DTYPE_MASK (3 << EDID_DISPLAY_FEATURE_DTYPE_SHIFT) +# define EDID_ISPLAY_FEATURES_DTYPE_MONO (0 << EDID_DISPLAY_FEATURE_DTYPE_SHIFT) +# define EDID_ISPLAY_FEATURES_DTYPE_RGB (1 << EDID_DISPLAY_FEATURE_DTYPE_SHIFT) +# define EDID_ISPLAY_FEATURES_DTYPE_NON_RGB (2 << EDID_DISPLAY_FEATURE_DTYPE_SHIFT) +# define EDID_ISPLAY_FEATURES_DTYPE_UNDEFINED (3 << EDID_DISPLAY_FEATURE_DTYPE_SHIFT) #define EDID_DISPLAY_FEATURE_DPMSOFF (1 << 5) /* Bit 5: DPMS active-off supported */ #define EDID_DISPLAY_FEATURE_DPMSSUSP (1 << 6) /* Bit 6: DPMS suspend supported */ #define EDID_DISPLAY_FEATURE_DPMSSTDBY (1 << 7) /* Bit 7: DPMS standby supported */ @@ -479,46 +490,10 @@ * from manufacturer. However, the value is * later used by DDDB. */ -/* Video mode flags used in struct hdmi_videomode_s */ - -#define VID_PHSYNC (1 << 0) -#define VID_NHSYNC (1 << 1) -#define VID_PVSYNC (1 << 2) -#define VID_NVSYNC (1 << 3) -#define VID_INTERLACE (1 << 4) -#define VID_DBLSCAN (1 << 5) -#define VID_CSYNC (1 << 6) -#define VID_PCSYNC (1 << 7) -#define VID_NCSYNC (1 << 8) -#define VID_HSKEW (1 << 9) -#define VID_BCAST (1 << 10) -#define VID_PIXMUX (1 << 11) -#define VID_DBLCLK (1 << 12) -#define VID_CLKDIV2 (1 << 13) - /******************************************************************************************** * Pre-processor Definitions ********************************************************************************************/ -/* This structure represents one video mode extracted from the EDID. CAREFUL: Fields - * may not change without also modification to initializer in edid_videomode.c. - */ - -struct edid_videomode_s -{ - uint32_t dotclock; /* Dot clock frequency in kHz. */ - uint16_t hdisplay; - uint16_t hsync_start; - uint16_t hsync_end; - uint16_t htotal; - uint16_t vdisplay; - uint16_t vsync_start; - uint16_t vsync_end; - uint16_t vtotal; - uint16_t flags; /* Video mode flags; see above. */ - FAR const char *name; -}; - /* These structures is a user-friendly digest of the EDID data. */ struct edid_chroma_s @@ -540,8 +515,9 @@ struct edid_range_s uint16_t er_min_hfreq; /* kHz */ uint16_t er_max_hfreq; /* kHz */ uint16_t er_max_clock; /* MHz */ - int er_have_gtf2; uint16_t er_gtf2_hfreq; + + bool er_have_gtf2; uint16_t er_gtf2_c; uint16_t er_gtf2_m; uint16_t er_gtf2_k; @@ -561,18 +537,18 @@ struct edid_info_s uint8_t edid_ext_block_count; uint16_t edid_product; uint32_t edid_serial; - int edid_year; - int edid_week; - int edid_have_range; + uint16_t edid_year; + uint8_t edid_week; + bool edid_have_range; struct edid_range_s edid_range; struct edid_chroma_s edid_chroma; /* Parsed modes */ - FAR struct edid_videomode_s *edid_preferred_mode; + FAR struct videomode_s *edid_preferred_mode; int edid_nmodes; - struct edid_videomode_s edid_modes[64]; + struct videomode_s edid_modes[64]; }; /******************************************************************************************** @@ -599,37 +575,19 @@ struct edid_info_s int edid_parse(FAR const uint8_t *data, FAR struct edid_info_s *edid); /******************************************************************************************** - * Name: edid_sort_modes + * Name: edid_dump * * Description: - * Sort video modes by refresh rate, aspect ratio, then resolution. - * Preferred mode or largest mode is first in the list and other modes - * are sorted on closest match to that mode. - * - * Note that the aspect ratio calculation treats "close" aspect ratios - * (within 12.5%) as the same for this purpose. + * Dump the full content of the EDID * * Input Parameters: - * modes - A reference to the first entry in a list of video modes - * preferred - A pointer to the pointer to the preferred mode in the list - * nmodes - The number of modes in the list + * edid - The edid to be dumped * * Returned Value: * None * ********************************************************************************************/ -void edid_sort_modes(FAR struct edid_videomode_s *modes, - FAR struct edid_videomode_s **preferred, unsigned int nmodes); - -/******************************************************************************************** - * Name: edid_mode_lookup - * - * Description: - * Find the video mode in a look-up table - * - ********************************************************************************************/ - -FAR const struct edid_videomode_s *edid_mode_lookup(FAR const char *name); +void edid_dump(FAR const struct edid_info_s *edid); #endif /* __INCLUDE_NUTTX_VIDEO_EDID_H */ diff --git a/include/nuttx/video/vesagtf.h b/include/nuttx/video/vesagtf.h new file mode 100644 index 00000000000..6c34485ba6c --- /dev/null +++ b/include/nuttx/video/vesagtf.h @@ -0,0 +1,121 @@ +/**************************************************************************7 + * include/nuttx/video/vesagtf.h + * EDID (Extended Display Identification Data) Format + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from logic in FreeBSD which has an equivalent 3-clause BSD + * license: + * + * Copyright (c) 2006 Itronix Inc. All rights reserved. + * Written by Garrett D'Amore for Itronix Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 OWNER 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. + * + ********************************************************************************************/ + +#ifndef __INCLUDE_NUTTX_VIDEO_VESAGTF +#define __INCLUDE_NUTTX_VIDEO_VESAGTF + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Default values to use for params. */ + +#define VESAGTF_MARGIN_PPT 18 /* 1.8% */ +#define VESAGTF_MIN_PORCH 1 /* minimum front porch */ +#define VESAGTF_VSYNC_RQD 3 /* vsync width in lines */ +#define VESAGTF_HSYNC_PCT 8 /* width of hsync % of total line */ +#define VESAGTF_MIN_VSBP 550 /* min vsync + back porch (usec) */ +#define VESAGTF_M 600 /* blanking formula gradient */ +#define VESAGTF_C 40 /* blanking formula offset */ +#define VESAGTF_K 128 /* blanking formula scaling factor */ +#define VESAGTF_J 20 /* blanking formula scaling factor */ + +#define VESAGTF_FLAG_ILACE 0x0001/* use interlace */ +#define VESAGTF_FLAG_MARGINS 0x0002/* use margins */ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Use VESA GTF formula to generate a monitor mode, given resolution and + * refresh rates. + */ + +struct vesagtf_params +{ + unsigned int margin_ppt; /* Bertical margin size, percent * 10 think + * parts-per-thousand */ + unsigned int min_porch; /* Minimum front porch */ + unsigned int vsync_rqd; /* Width of vsync in lines */ + unsigned int hsync_pct; /* Hsync as % of total width */ + unsigned int min_vsbp; /* Minimum vsync + back porch (usec) */ + unsigned int m; /* Blanking formula gradient */ + unsigned int c; /* Blanking formula offset */ + unsigned int k; /* Blanking formula scaling factor */ + unsigned int j; /* Blanking formula scaling factor */ +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +struct videomode_s; /* Forward reference */ + +/**************************************************************************** + * Name: vesagtf_mode + * + * Description: + * Use VESA GTF formula to generate monitor timings. Assumes default + * GTF parameters, non-interlaced, and no margins. + * + ****************************************************************************/ + +void vesagtf_mode(unsigned int x, unsigned int y, unsigned int refresh, + FAR struct videomode_s *videomode); + +/**************************************************************************** + * Name: vesagtf_mode_params + * + * Description: + * vesagtf_mode_params() - as defined by the GTF Timing Standard, compute + * the Stage 1 Parameters using the vertical refresh frequency. In other + * words: input a desired resolution and desired refresh rate, and + * output the GTF mode timings. + * + ****************************************************************************/ + +void vesagtf_mode_params(unsigned int x, unsigned int y, unsigned int refresh, + FAR struct vesagtf_params *params, + unsigned int flags, + FAR struct videomode_s *videomode); + +#endif /* __INCLUDE_NUTTX_VIDEO_VESAGTF */ diff --git a/include/nuttx/video/videomode.h b/include/nuttx/video/videomode.h new file mode 100644 index 00000000000..04dd1818c8c --- /dev/null +++ b/include/nuttx/video/videomode.h @@ -0,0 +1,191 @@ +/**************************************************************************** + * include/nuttx/video/videomode.h + * EDID (Extended Display Identification Data) Format + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Some of structures in this file derive from FreeBSD which has a + * compatible 2-clause BSD license: + * + * Copyright (c) 2006 Itronix Inc. All rights reserved. + * Written by Garrett D'Amore for Itronix Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * 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 OWNER 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_VIDEO_VIDEOMODE_H +#define __INCLUDE_NUTTX_VIDEO_VIDEOMODE_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Video mode flags used in struct hdmi_videomode_s */ + +#define VID_PHSYNC (1 << 0) +#define VID_NHSYNC (1 << 1) +#define VID_PVSYNC (1 << 2) +#define VID_NVSYNC (1 << 3) +#define VID_INTERLACE (1 << 4) +#define VID_DBLSCAN (1 << 5) +#define VID_CSYNC (1 << 6) +#define VID_PCSYNC (1 << 7) +#define VID_NCSYNC (1 << 8) +#define VID_HSKEW (1 << 9) +#define VID_BCAST (1 << 10) +#define VID_PIXMUX (1 << 12) +#define VID_DBLCLK (1 << 13) +#define VID_CLKDIV2 (1 << 14) + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* This structure represents one video mode extracted from the EDID. + * CAREFUL: Fields may not change without also modification to initializer + * in videomode_lookup.c. + */ + +struct videomode_s +{ + uint32_t dotclock; /* Dot clock frequency in kHz. */ + uint16_t hdisplay; + uint16_t hsync_start; + uint16_t hsync_end; + uint16_t htotal; + uint16_t vdisplay; + uint16_t vsync_start; + uint16_t vsync_end; + uint16_t vtotal; + uint16_t hskew; + uint16_t flags; /* Video mode flags; see above. */ + FAR const char *name; +}; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: sort_videomodes + * + * Description: + * Sort video modes by refresh rate, aspect ratio, then resolution. + * Preferred mode or largest mode is first in the list and other modes + * are sorted on closest match to that mode. + * + * Note that the aspect ratio calculation treats "close" aspect ratios + * (within 12.5%) as the same for this purpose. + * + * Input Parameters: + * modes - A reference to the first entry in a list of video modes + * preferred - A pointer to the pointer to the preferred mode in the list + * nmodes - The number of modes in the list + * + * Returned Value: + * None + * + ****************************************************************************/ + +void sort_videomodes(FAR struct videomode_s *modes, + FAR struct videomode_s **preferred, + unsigned int nmodes); + +/**************************************************************************** + * Name: videomode_lookup + * + * Description: + * Find the video mode in a look-up table + * + ****************************************************************************/ + +FAR const struct videomode_s *videomode_lookup_by_name(FAR const char *name); + +/**************************************************************************** + * Name: videomode_lookup_by_dotclock + * + * Description: + * Find the video mode in a look-up table with the matching width and + * height and the closest dot clock that does not exceed the requested + * dot clock. + * + ****************************************************************************/ + +#if 0 /* Not used */ +FAR const struct videomode_s * + videomode_lookup_by_dotclock(uint16_t width, uint16_t height, + uint32_t dotclock); +#endif + +/**************************************************************************** + * Name: videomode_lookup_by_refresh + * + * Description: + * Find the video mode in a look-up table with the matching width and + * height and the closest refresh rate that does not exceed the requested + * rate. + * + ****************************************************************************/ + +#if 0 /* Not used */ +FAR const struct videomode_s * + videomode_lookup_by_refresh(uint16_t width, uint16_t height, + uint16_t refresh); +#endif + +/**************************************************************************** + * Name: videomode_dump + * + * Description: + * Dump the content of a video mode one one line to the SYSLOG. + * + * Input Parameters: + * prefix - A string to print at the beginning of the line. May be + * NULL + * videomode - The videomode to be dumped + * terse - True: Print only a minimal amount of data, sufficient to + * identify the video mode. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void videomode_dump(FAR const char *prefix, + FAR const struct videomode_s *videomode, bool terse); + +#endif /* __INCLUDE_NUTTX_VIDEO_VIDEOMODE_H */ diff --git a/include/nuttx/wireless/gs2200m.h b/include/nuttx/wireless/gs2200m.h index 3f1576ed73e..6f6887fa5e8 100644 --- a/include/nuttx/wireless/gs2200m.h +++ b/include/nuttx/wireless/gs2200m.h @@ -118,6 +118,7 @@ struct gs2200m_assoc_msg FAR char *ssid; FAR char *key; uint8_t mode; + uint8_t ch; }; struct gs2200m_lower_s diff --git a/include/sys/syscall.h b/include/sys/syscall.h index 823d88b4ebb..bea4a25b43e 100644 --- a/include/sys/syscall.h +++ b/include/sys/syscall.h @@ -141,7 +141,7 @@ /* The following can be individually enabled */ -#ifdef CONFIG_ARCH_HAVE_VFORK +#if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_ARCH_HAVE_VFORK) # define SYS_vfork __SYS_vfork # define __SYS_atexit (__SYS_vfork + 1) #else diff --git a/syscall/syscall.csv b/syscall/syscall.csv index 60017472095..8e817e1fe75 100644 --- a/syscall/syscall.csv +++ b/syscall/syscall.csv @@ -177,7 +177,7 @@ "unsetenv","stdlib.h","!defined(CONFIG_DISABLE_ENVIRON)","int","const char*" "up_assert","assert.h","","void","FAR const uint8_t*","int" #"up_assert","assert.h","","void" -"vfork","unistd.h","defined(CONFIG_ARCH_HAVE_VFORK)","pid_t" +"vfork","unistd.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_ARCH_HAVE_VFORK)","pid_t" "wait","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","pid_t","int*" "waitid","sys/wait.h","defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_SCHED_HAVE_PARENT)","int","idtype_t","id_t"," FAR siginfo_t *","int" "waitpid","sys/wait.h","defined(CONFIG_SCHED_WAITPID)","pid_t","pid_t","int*","int" diff --git a/syscall/syscall_lookup.h b/syscall/syscall_lookup.h index 99fdfb6aebf..cb748f778b4 100644 --- a/syscall/syscall_lookup.h +++ b/syscall/syscall_lookup.h @@ -96,7 +96,7 @@ SYSCALL_LOOKUP(up_assert, 2, STUB_up_assert) /* The following can be individually enabled */ -#ifdef CONFIG_ARCH_HAVE_VFORK +#if defined(CONFIG_SCHED_WAITPID) && defined(CONFIG_ARCH_HAVE_VFORK) SYSCALL_LOOKUP(vfork, 0, STUB_vfork) #endif diff --git a/video/Kconfig b/video/Kconfig index f4ec346d722..9f7ffe0df01 100644 --- a/video/Kconfig +++ b/video/Kconfig @@ -13,6 +13,6 @@ config VIDEO if VIDEO -source video/edid/Kconfig +source video/videomode/Kconfig endif # VIDEO diff --git a/video/Makefile b/video/Makefile index 9561962de1e..7ef94641f59 100644 --- a/video/Makefile +++ b/video/Makefile @@ -41,7 +41,7 @@ CSRCS = DEPPATH = --dep-path . VPATH = . -include edid/Make.defs +include videomode/Make.defs AOBJS = $(ASRCS:.S=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT)) diff --git a/video/edid/Kconfig b/video/videomode/Kconfig similarity index 88% rename from video/edid/Kconfig rename to video/videomode/Kconfig index 57e4811cadb..37707ee44e9 100644 --- a/video/edid/Kconfig +++ b/video/videomode/Kconfig @@ -4,7 +4,7 @@ # config VIDEO_EDID - bool "EDID Support" + bool "EDID / Videomode Support" default n ---help--- Enable support for managing EDID data EDID (Extended Display diff --git a/video/edid/Make.defs b/video/videomode/Make.defs similarity index 90% rename from video/edid/Make.defs rename to video/videomode/Make.defs index 3c8b4a52e9b..aaca5a417ff 100644 --- a/video/edid/Make.defs +++ b/video/videomode/Make.defs @@ -1,5 +1,5 @@ ############################################################################ -# video/edid/Make.defs +# video/videomode/Make.defs # # Copyright (C) 2019 Gregory Nutt. All rights reserved. # Author: Gregory Nutt @@ -38,11 +38,13 @@ ifeq ($(CONFIG_VIDEO_EDID),y) # Files required for EDID support ASRCS += -CSRCS += edid_parse.c edid_videomode.c edid_sort.c +CSRCS += edid_parse.c edid_dump.c +CSRCS += videomode_lookup.c videomode_sort.c videomode_dump.c +CSRCS += vesagtf.c # Include EDID build support -DEPPATH += --dep-path edid -VPATH += :edid +DEPPATH += --dep-path videomode +VPATH += :videomode endif diff --git a/video/videomode/edid_dump.c b/video/videomode/edid_dump.c new file mode 100644 index 00000000000..13e1211b5c1 --- /dev/null +++ b/video/videomode/edid_dump.c @@ -0,0 +1,261 @@ +/**************************************************************************** + * video/videomode/edid_dump.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from logic in FreeBSD which has an compatible 2-clause BSD + * license: + * + * Copyright (c) 2006 Itronix Inc. All rights reserved. + * Written by Garrett D'Amore for Itronix Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED ``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 NETBSD FOUNDATION 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include +#include + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: edid_dump + * + * Description: + * Dump the full content of the EDID + * + * Input Parameters: + * edid - The edid to be dumped + * + * Returned Value: + * None + * + ****************************************************************************/ + +void edid_dump(FAR const struct edid_info_s *edid) +{ + FAR const char *prefix; + int i; + + if (edid == NULL) + { + return; + } + + syslog(LOG_INFO, "%-16s[%s]\n", + "Manufacturer:", edid->edid_manufacturer); + syslog(LOG_INFO, "%-16s%u.%u\n", + "EDID Version:", edid->edid_version, edid->edid_revision); + + syslog(LOG_INFO, "%-16s%02x\n", + "Video Input:", edid->edid_video_input); + if ((edid->edid_video_input & EDID_DISPLAY_INPUT_DIGITAL) != 0) + { + if ((edid->edid_video_input & EDID_DISPLAY_INPUT_DFP1_COMPAT) != 0) + { + syslog(LOG_INFO, "%-16s%s\n", + "", "Digital (DFP 1.x compatible)\n"); + } + else + { + syslog(LOG_INFO, "%-16s%s\n", + "", "Digital"); + } + } + else + { + switch (edid->edid_video_input & EDID_DISPLAY_INPUT_LEVELS_MASK) + { + case EDID_DISPLAY_INPUT_LEVEL_1: + syslog(LOG_INFO, "%-16s-0.7, 0.3V\n", "", "Analog:"); + break; + + case EDID_DISPLAY_INPUT_LEVEL_2: + syslog(LOG_INFO, "%-16s-0.714, 0.286V\n", "", "Analog:"); + break; + + case EDID_DISPLAY_INPUT_LEVEL_3: + syslog(LOG_INFO, "%-16s-1.0, 0.4V\n", "", "Analog:"); + break; + + case EDID_DISPLAY_INPUT_LEVEL_4: + syslog(LOG_INFO, "%-16s-0.7, 0.0V\n", "", "Analog:"); + break; + } + + if ((edid->edid_video_input & EDID_DISPLAY_INPUT_BLANK2BLACK) != 0) + { + syslog(LOG_INFO, "%-16sBlank-to-black setup\n", ""); + } + + if ((edid->edid_video_input & EDID_DISPLAY_INPUT_SYNC) != 0) + { + syslog(LOG_INFO, " %-16sSeperate syncs\n", ""); + } + + if ((edid->edid_video_input & EDID_DISPLAY_INPUT_COMPOSITE) != 0) + { + syslog(LOG_INFO, "%-16sComposite sync\n", ""); + } + + if ((edid->edid_video_input & EDID_DISPLAY_INPUT_GREEN) != 0) + { + syslog(LOG_INFO, "%-16sSync on green\n", ""); + } + + if ((edid->edid_video_input & EDID_DISPLAY_INPUT_VSERRATED) != 0) + { + syslog(LOG_INFO, "%-16sSerrated vsync\n", ""); + } + } + + syslog(LOG_INFO, "Max Size: %d cm x %d cm\n", + edid->edid_max_hsize, edid->edid_max_vsize); + syslog(LOG_INFO, "Gamma: %u.%02\n", + edid->edid_gamma / 100, edid->edid_gamma % 100); + + syslog(LOG_INFO, "%-16s%02x\n", + "Features:", edid->edid_features); + if (edid->edid_features & EDID_DISPLAY_FEATURE_DPMSSTDBY) + { + syslog(LOG_INFO, "%-16sDPMS standby\n", ""); + } + + if (edid->edid_features & EDID_DISPLAY_FEATURE_DPMSSUSP) + { + syslog(LOG_INFO, "%-16sDPMS suspend\n", ""); + } + + if (edid->edid_features & EDID_DISPLAY_FEATURE_DPMSOFF) + { + syslog(LOG_INFO, "%-16sDPMS active-off\n", ""); + } + + switch (edid->edid_features & EDID_DISPLAY_FEATURE_DTYPE_MASK) + { + case EDID_ISPLAY_FEATURES_DTYPE_MONO: + syslog(LOG_INFO, "%-16sMonochrome\n", ""); + break; + + case EDID_ISPLAY_FEATURES_DTYPE_RGB: + syslog(LOG_INFO, "%-16sRGB\n", ""); + break; + + case EDID_ISPLAY_FEATURES_DTYPE_NON_RGB: + syslog(LOG_INFO, "%-16sMulticolor\n", ""); + break; + + case EDID_ISPLAY_FEATURES_DTYPE_UNDEFINED: + syslog(LOG_INFO, "%-16sUndefined monitor type\n", ""); + break; + } + + if (edid->edid_features & EDID_DISPLAY_FEATURE_STDRGB) + { + syslog(LOG_INFO, "%-16sStandard color space\n", ""); + } + + if (edid->edid_features & EDID_DISPLAY_FEATURE_MODE) + { + syslog(LOG_INFO, "%-16sPreferred timing\n", ""); + } + + if (edid->edid_features & EDID_DISPLAY_FEATURE_CONTINUOUS) + { + syslog(LOG_INFO, "%-16sDefault GTF supported\n", ""); + } + + syslog(LOG_INFO, "%-16s%d\n", + "Ext Blocks:", edid->edid_ext_block_count); + syslog(LOG_INFO, "%-16s%u\n", + "Product:", edid->edid_product); + syslog(LOG_INFO, "%-16s%lu\n", + "Serial No:", (unsigned long)edid->edid_serial); + syslog(LOG_INFO, "%-16sYear %d, Week %d\n", + "Manufactured:", edid->edid_year, edid->edid_week); + + if (edid->edid_have_range) + { + syslog(LOG_INFO, "%-16sHorizontal: %d - %d kHz\n", + "Range:", edid->edid_range.er_min_hfreq, edid->edid_range.er_max_hfreq); + syslog(LOG_INFO, "%-16sVertical: %d - %d Hz\n", + "", edid->edid_range.er_min_vfreq, edid->edid_range.er_max_vfreq); + syslog(LOG_INFO, "%-16sMax Dot Clock: %d MHz\n", + "", edid->edid_range.er_max_clock); + if (edid->edid_range.er_have_gtf2) + { + syslog(LOG_INFO, "%-16sGTF2 hfreq: %d\n", + "", edid->edid_range.er_gtf2_hfreq); + syslog(LOG_INFO, "%-16sGTF2 C: %d\n", + "", edid->edid_range.er_gtf2_c); + syslog(LOG_INFO, "%-16sGTF2 M: %d\n", + "", edid->edid_range.er_gtf2_m); + syslog(LOG_INFO, "%-16sGTF2 J: %d\n", + "", edid->edid_range.er_gtf2_j); + syslog(LOG_INFO, "%-16sGTF2 K: %d\n", + "", edid->edid_range.er_gtf2_k); + } + } + + syslog(LOG_INFO, "%-16sRed X: 0.%03d\n", + "Chroma Info:", edid->edid_chroma.ec_redx); + syslog(LOG_INFO, "%-16sRed Y: 0.%03d\n", + "", edid->edid_chroma.ec_redy); + syslog(LOG_INFO, "%-16sGrn X: 0.%03d\n", + "", edid->edid_chroma.ec_greenx); + syslog(LOG_INFO, "%-16sGrn Y: 0.%03d\n", + "", edid->edid_chroma.ec_greeny); + syslog(LOG_INFO, "%-16sBlu X: 0.%03d\n", + "", edid->edid_chroma.ec_bluex); + syslog(LOG_INFO, "%-16sBlu Y: 0.%03d\n", + "", edid->edid_chroma.ec_bluey); + syslog(LOG_INFO, "%-16sWht X: 0.%03d\n", + "", edid->edid_chroma.ec_whitex); + syslog(LOG_INFO, "%-16sWht Y: 0.%03d\n", + "", edid->edid_chroma.ec_whitey); + + prefix = "Video modes: "; + for (i = 0; i < edid->edid_nmodes; i++) + { + videomode_dump(prefix, &edid->edid_modes[i], false); + prefix = " "; + } + + if (edid->edid_preferred_mode) + { + prefix = "Preferred Mode: "; + videomode_dump(prefix, edid->edid_preferred_mode, true); + } +} diff --git a/video/edid/edid_parse.c b/video/videomode/edid_parse.c similarity index 94% rename from video/edid/edid_parse.c rename to video/videomode/edid_parse.c index 74e24cc8fb8..7bc21467b85 100644 --- a/video/edid/edid_parse.c +++ b/video/videomode/edid_parse.c @@ -1,5 +1,5 @@ /**************************************************************************** - * video/edid/edid_parse.c + * video/videomode/edid_parse.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -7,9 +7,7 @@ * Derives from logic in FreeBSD which has an equivalent 3-clause BSD * license: * - * Copyright (c) 2006 Itronix Inc. - * All rights reserved. - * + * Copyright (c) 2006 Itronix Inc. All rights reserved. * Written by Garrett D'Amore for Itronix Inc. * * Redistribution and use in source and binary forms, with or without @@ -51,6 +49,8 @@ #include #include +#include +#include #include /**************************************************************************** @@ -134,9 +134,9 @@ static bool edid_valid(FAR const uint8_t *data) ****************************************************************************/ static bool edid_std_timing(FAR const uint8_t *stdtim, - FAR struct edid_videomode_s *mode) + FAR struct videomode_s *mode) { - FAR const struct edid_videomode_s *lookup; + FAR const struct videomode_s *lookup; char name[80]; unsigned x; unsigned y; @@ -175,23 +175,19 @@ static bool edid_std_timing(FAR const uint8_t *stdtim, /* First try to lookup the mode as a DMT timing */ snprintf(name, sizeof(name), "%dx%dx%d", x, y, f); - if ((lookup = edid_mode_lookup(name)) != NULL) + if ((lookup = videomode_lookup_by_name(name)) != NULL) { *mode = *lookup; } else { -#if 0 /* Not implemented. See FreeBSD sys/dev/videomode/vesagtf.c */ /* Failing that, calculate it using gtf - * + * * Hmm. I'm not using alternate GTF timings, which * could, in theory, be present. */ vesagtf_mode(x, y, f, mode); -#endif -# warning REVISIT: Missing logic - return false; } return true; @@ -205,9 +201,9 @@ static bool edid_std_timing(FAR const uint8_t *stdtim, * ****************************************************************************/ -static struct edid_videomode_s * +static struct videomode_s * edid_search_mode(FAR struct edid_info_s *edid, - FAR const struct edid_videomode_s *mode) + FAR const struct videomode_s *mode) { int refresh; int i; @@ -238,7 +234,7 @@ static struct edid_videomode_s * ****************************************************************************/ static bool edid_desc_timing(FAR const uint8_t *desc, - FAR struct edid_videomode_s *mode) + FAR struct videomode_s *mode) { uint16_t hactive; unsigned int hblank; @@ -255,9 +251,9 @@ static bool edid_desc_timing(FAR const uint8_t *desc, /* We don't support stereo modes (for now) */ if (flags & (EDID_DESC_STEREO_MASK | EDID_DESC_STEREO_INTERLEAVE)) - { + { return false; - } + } mode->dotclock = (uint16_t)desc[EDID_DESC_PIXCLOCK_OFFSET] | ((uint16_t)desc[EDID_DESC_PIXCLOCK_OFFSET + 1] << 8); @@ -284,7 +280,9 @@ static bool edid_desc_timing(FAR const uint8_t *desc, mode->vsync_start = vactive + vsyncoff; mode->vsync_end = mode->vsync_start + vsyncwid; + mode->hskew = 0; mode->flags = 0; + mode->name = NULL; if ((flags & EDID_DESC_INTERLACED) != 0) { @@ -322,8 +320,8 @@ static bool edid_desc_timing(FAR const uint8_t *desc, static void edid_block(FAR struct edid_info_s *edid, FAR const uint8_t *desc) { - struct edid_videomode_s mode; - FAR struct edid_videomode_s *exist_mode; + struct videomode_s mode; + FAR struct videomode_s *exist_mode; uint16_t pixclk; int i; @@ -355,7 +353,8 @@ static void edid_block(FAR struct edid_info_s *edid, FAR const uint8_t *desc) edid->edid_modes[edid->edid_nmodes] = mode; if (edid->edid_preferred_mode == NULL) { - edid->edid_preferred_mode = &edid->edid_modes[edid->edid_nmodes];} + edid->edid_preferred_mode = &edid->edid_modes[edid->edid_nmodes]; + } edid->edid_nmodes++; } @@ -384,7 +383,7 @@ static void edid_block(FAR struct edid_info_s *edid, FAR const uint8_t *desc) break; case EDID_DESCTYPE_LIMITS: - edid->edid_have_range = 1; + edid->edid_have_range = true; edid->edid_range.er_min_vfreq = EDID_DESC_RANGE_MIN_VFREQ(desc); edid->edid_range.er_max_vfreq = EDID_DESC_RANGE_MAX_VFREQ(desc); edid->edid_range.er_min_hfreq = EDID_DESC_RANGE_MIN_HFREQ(desc); @@ -396,7 +395,7 @@ static void edid_block(FAR struct edid_info_s *edid, FAR const uint8_t *desc) break; } - edid->edid_range.er_have_gtf2 = 1; + edid->edid_range.er_have_gtf2 = true; edid->edid_range.er_gtf2_hfreq = EDID_DESC_RANGE_GTF2_HFREQ(desc); edid->edid_range.er_gtf2_c = EDID_DESC_RANGE_GTF2_C(desc); edid->edid_range.er_gtf2_m = EDID_DESC_RANGE_GTF2_M(desc); @@ -420,6 +419,7 @@ static void edid_block(FAR struct edid_info_s *edid, FAR const uint8_t *desc) if (edid_std_timing(desc, &mode)) { /* Does this mode already exist? */ + exist_mode = edid_search_mode(edid, &mode); if (exist_mode == NULL) { @@ -433,7 +433,8 @@ static void edid_block(FAR struct edid_info_s *edid, FAR const uint8_t *desc) break; case EDID_DESCTYPE_WHITEPOINT: - /* XXX: not implemented yet */ + /* Not implemented yet */ + break; } } @@ -454,14 +455,14 @@ static void edid_block(FAR struct edid_info_s *edid, FAR const uint8_t *desc) * edid - The location to return the digested EDID data. * * Returned Value: - * Zero (OK) is returned on success; otherwise a negated errno value is returned to - * indicate the nature of the failure. + * Zero (OK) is returned on success; otherwise a negated errno value is + * returned to indicate the nature of the failure. * ****************************************************************************/ int edid_parse(FAR const uint8_t *data, FAR struct edid_info_s *edid) { - FAR const struct edid_videomode_s *mode; + FAR const struct videomode_s *mode; uint16_t manufacturer; uint16_t estmodes; uint8_t gamma; @@ -532,7 +533,7 @@ int edid_parse(FAR const uint8_t *data, FAR struct edid_info_s *edid) { if (estmodes & (1 << i)) { - mode = edid_mode_lookup(g_edid_modes[i]); + mode = videomode_lookup_by_name(g_edid_modes[i]); if (mode != NULL) { edid->edid_modes[edid->edid_nmodes] = *mode; @@ -550,8 +551,8 @@ int edid_parse(FAR const uint8_t *data, FAR struct edid_info_s *edid) for (i = 0; i < EDID_STDTIMING_NUMBER; i++) { - struct edid_videomode_s stdmode; - FAR struct edid_videomode_s *exist_mode; + struct videomode_s stdmode; + FAR struct videomode_s *exist_mode; if (edid_std_timing(data + EDID_STDTIMING_OFFSET + i * 2, &stdmode)) { diff --git a/video/videomode/vesagtf.c b/video/videomode/vesagtf.c new file mode 100644 index 00000000000..b60d83ac170 --- /dev/null +++ b/video/videomode/vesagtf.c @@ -0,0 +1,505 @@ +/**************************************************************************** + * video/videomode/vesagtf.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from logic in FreeBSD which has an equivalent 3-clause BSD + * license: + * + * Copyright (c) 2006 Itronix Inc. All rights reserved. + * Written by Garrett D'Amore for Itronix Inc. + * + * That version, in turn, derived from a userland GTF program supplied by + * Nvidia which was also released under a compatible 3-clause BSD license: + * + * Copyright (c) 2001, Andy Ritger + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * 3. The name of Itronix Inc. may not be used to endorse + * or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``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 ITRONIX INC. 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. + * + ****************************************************************************/ + +/* The logic in this file program was based on the Generalized Timing + * Formula(GTF TM) Standard Version: 1.0, Revision: 1.0 + * + * NOTES: + * + * The GTF allows for computation of "margins" (the visible border + * surrounding the addressable video); on most non-overscan type + * systems, the margin period is zero. I've implemented the margin + * computations but not enabled it because 1) I don't really have + * any experience with this, and 2) neither XFree86 modelines nor + * fbset fb.modes provide an obvious way for margin timings to be + * included in their mode descriptions (needs more investigation). + * + * The GTF provides for computation of interlaced mode timings; + * I've implemented the computations but not enabled them, yet. + * I should probably enable and test this at some point. + * + * TODO: + * + * o Add support for interlaced modes. + * + * o Implement the other portions of the GTF: compute mode timings + * given either the desired pixel clock or the desired horizontal + * frequency. + * + * o It would be nice if this were more general purpose to do things + * outside the scope of the GTF: like generate double scan mode + * timings, for example. + * + * o Printing digits to the right of the decimal point when the + * digits are 0 annoys me. + * + * o Error checking. + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define CELL_GRAN 8 /* Assumed character cell granularity */ + +/* c' and m' are part of the Blanking Duty Cycle computation + * + * #define C_PRIME (((c - j) * k/256.0) + j) + * #define M_PRIME (k/256.0 * m) + */ + +/* c' and m' multiplied by 256 to give integer math. Make sure to + * scale results using these back down, appropriately. + */ + +#define C_PRIME256(p) (((p->c - p->j) * p->k) + (p->j * 256)) +#define M_PRIME256(p) (p->k * p->m) + +#define DIVIDE(x,y) (((x) + ((y) / 2)) / (y)) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: vesagtf_mode_params + * + * Description: + * vesagtf_mode_params() - as defined by the GTF Timing Standard, compute + * the Stage 1 Parameters using the vertical refresh frequency. In other + * words: input a desired resolution and desired refresh rate, and + * output the GTF mode timings. + * + ****************************************************************************/ + +void vesagtf_mode_params(unsigned int x, unsigned int y, + unsigned int refresh, + FAR struct vesagtf_params *params, + unsigned int flags, + FAR struct videomode_s *videomode) +{ + uint64_t h_period_est; + uint64_t v_field_est; + uint64_t h_period; + uint64_t ideal_duty_cycle; + + unsigned int v_field_rqd; + unsigned int top_margin; + unsigned int bottom_margin; + unsigned int interlace; + unsigned int vsync_plus_bp; + unsigned total_v_lines; + unsigned int left_margin; + unsigned int right_margin; + unsigned int total_active_pixels; + unsigned int h_blank; + unsigned int h_pixels; + unsigned int v_lines; + unsigned int total_pixels; + unsigned int pixel_freq; + unsigned int h_sync; + unsigned int h_front_porch; + unsigned int v_odd_front_porch_lines; + +#if 0 /* Unused, not needed */ + unsigned int v_field_rate; + unsigned int v_back_porch; + unsigned int v_frame_rate; + unsigned int h_freq; +#endif + + /* 1. In order to give correct results, the number of horizontal + * pixels requested is first processed to ensure that it is divisible + * by the character size, by rounding it to the nearest character + * cell boundary: + * + * [H PIXELS RND] = ((ROUND([H PIXELS]/[CELL GRAN RND],0))*[CELLGRAN RND]) + */ + + h_pixels = DIVIDE(x, CELL_GRAN) * CELL_GRAN; + + /* 2. If interlace is requested, the number of vertical lines assumed + * by the calculation must be halved, as the computation calculates + * the number of vertical lines per field. In either case, the + * number of lines is rounded to the nearest integer. + * + * [V LINES RND] = IF([INT RQD?]="y", ROUND([V LINES]/2,0), + * ROUND([V LINES],0)) + */ + + v_lines = (flags & VESAGTF_FLAG_ILACE) ? DIVIDE(y, 2) : y; + + /* 3. Find the frame rate required: + * + * [V FIELD RATE RQD] = IF([INT RQD?]="y", [I/P FREQ RQD]*2, + * [I/P FREQ RQD]) + */ + + v_field_rqd = (flags & VESAGTF_FLAG_ILACE) ? (refresh * 2) : (refresh); + + /* 4. Find number of lines in Top margin: + * 5. Find number of lines in Bottom margin: + * + * [TOP MARGIN (LINES)] = IF([MARGINS RQD?]="Y", + * ROUND(([MARGIN%]/100*[V LINES RND]),0), + * 0) + * + * Ditto for bottom margin. Note that instead of %, we use PPT, which + * is parts per thousand. This helps us with integer math. + */ + + top_margin = (flags & VESAGTF_FLAG_MARGINS) ? + DIVIDE(v_lines * params->margin_ppt, 1000) : 0; + bottom_margin = top_margin; + + /* 6. If interlace is required, then set variable [INTERLACE]=0.5: + * + * [INTERLACE]=(IF([INT RQD?]="y",0.5,0)) + * + * To make this integer friendly, we use some special hacks in step + * 7 below. Please read those comments to understand why I am using + * a whole number of 1.0 instead of 0.5 here. + */ + + interlace = (flags & VESAGTF_FLAG_ILACE) ? 1 : 0; + + /* 7. Estimate the Horizontal period + * + * [H PERIOD EST] = ((1/[V FIELD RATE RQD]) - [MIN VSYNC+BP]/1000000) / + * ([V LINES RND] + (2*[TOP MARGIN (LINES)]) + + * [MIN PORCH RND]+[INTERLACE]) * 1000000 + * + * To make it integer friendly, we pre-multiply the 1000000 to get to + * usec. This gives us: + * + * [H PERIOD EST] = ((1000000/[V FIELD RATE RQD]) - [MIN VSYNC+BP]) / + * ([V LINES RND] + (2 * [TOP MARGIN (LINES)]) + + * [MIN PORCH RND]+[INTERLACE]) + * + * The other problem is that the interlace value is wrong. To get + * the interlace to a whole number, we multiply both the numerator and + * divisor by 2, so we can use a value of either 1 or 0 for the interlace + * factor. + * + * This gives us: + * + * [H PERIOD EST] = ((2*((1000000/[V FIELD RATE RQD]) - [MIN VSYNC+BP])) / + * (2*([V LINES RND] + (2*[TOP MARGIN (LINES)]) + + * [MIN PORCH RND]) + [2*INTERLACE])) + * + * Finally we multiply by another 1000, to get value in picosec. + * Why picosec? To minimize rounding errors. Gotta love integer + * math and error propagation. + */ + + h_period_est = DIVIDE(((DIVIDE(2000000000000ULL, v_field_rqd)) - + (2000000 * params->min_vsbp)), + ((2 * (v_lines + + (2 * top_margin) + params->min_porch)) + + interlace)); + + /* 8. Find the number of lines in V sync + back porch: + * + * [V SYNC+BP] = ROUND(([MIN VSYNC+BP]/[H PERIOD EST]),0) + * + * But recall that h_period_est is in psec. So multiply by 1000000. + */ + + vsync_plus_bp = DIVIDE(params->min_vsbp * 1000000, h_period_est); + +#if 0 /* Not needed */ + /* 9. Find the number of lines in V back porch alone: + * + * [V BACK PORCH] = [V SYNC+BP] - [V SYNC RND] + * + * XXX is "[V SYNC RND]" a typo? should be [V SYNC RQD]? + */ + + v_back_porch = vsync_plus_bp - params->vsync_rqd; +#endif + + /* 10. Find the total number of lines in Vertical field period: + * + * [TOTAL V LINES] = [V LINES RND] + [TOP MARGIN (LINES)] + + * [BOT MARGIN (LINES)] + [V SYNC+BP] + [INTERLACE] + + * [MIN PORCH RND] + */ + + total_v_lines = v_lines + top_margin + bottom_margin + vsync_plus_bp + + interlace + params->min_porch; + + /* 11. Estimate the Vertical field frequency: + * + * [V FIELD RATE EST] = 1 / [H PERIOD EST] / [TOTAL V LINES] * 1000000 + * + * Again, we want to pre multiply by 10^9 to convert for nsec, thereby + * making it usable in integer math. + * + * So we get: + * + * [V FIELD RATE EST] = 1000000000 / [H PERIOD EST] / [TOTAL V LINES] + * + * This is all scaled to get the result in uHz. Again, we're trying to + * minimize error propagation. + */ + + v_field_est = DIVIDE(DIVIDE(1000000000000000ULL, h_period_est), + total_v_lines); + + /* 12. Find the actual horizontal period: + * + * [H PERIOD] = [H PERIOD EST] / ([V FIELD RATE RQD] / [V FIELD RATE EST]) + */ + + h_period = DIVIDE(h_period_est * v_field_est, v_field_rqd * 1000); + +#if 0 /* Not needed */ + /* 13. Find the actual Vertical field frequency: + * + * [V FIELD RATE] = 1 / [H PERIOD] / [TOTAL V LINES] * 1000000 + * + * And again, we convert to nsec ahead of time, giving us: + * + * [V FIELD RATE] = 1000000 / [H PERIOD] / [TOTAL V LINES] + * + * And another rescaling back to mHz. Gotta love it. + */ + + v_field_rate = DIVIDE(1000000000000ULL, h_period * total_v_lines); + + /* 14. Find the Vertical frame frequency: + * + * [V FRAME RATE] = (IF([INT RQD?]="y", [V FIELD RATE]/2, [V FIELD RATE])) + * + * N.B. that the result here is in mHz. + */ + + v_frame_rate = (flags & VESAGTF_FLAG_ILACE) ? + v_field_rate / 2 : v_field_rate; +#endif + + /* 15. Find number of pixels in left margin: + * 16. Find number of pixels in right margin: + * + * [LEFT MARGIN (PIXELS)] = (IF( [MARGINS RQD?]="Y", + * (ROUND( ([H PIXELS RND] * [MARGIN%] / 100 / + * [CELL GRAN RND]),0)) * [CELL GRAN RND], + * 0)) + * + * Again, we deal with margin percentages as PPT (parts per thousand). + * And the calculations for left and right are the same. + */ + + left_margin = right_margin = (flags & VESAGTF_FLAG_MARGINS) ? + DIVIDE(DIVIDE(h_pixels * params->margin_ppt, 1000), + CELL_GRAN) * CELL_GRAN : 0; + + /* 17. Find total number of active pixels in image and left and right + * margins: + * + * [TOTAL ACTIVE PIXELS] = [H PIXELS RND] + [LEFT MARGIN (PIXELS)] + + * [RIGHT MARGIN (PIXELS)] + */ + + total_active_pixels = h_pixels + left_margin + right_margin; + + /* 18. Find the ideal blanking duty cycle from the blanking duty cycle + * equation: + * + * [IDEAL DUTY CYCLE] = [c'] - ([m']*[H PERIOD]/1000) + * + * However, we have modified values for [c'] as [256*c'] and + * [m'] as [256*m']. Again the idea here is to get good scaling. + * We use 256 as the factor to make the math fast. + * + * Note that this means that we have to scale it appropriately in + * later calculations. + * + * The ending result is that our ideal_duty_cycle is 256000x larger + * than the duty cycle used by VESA. But again, this reduces error + * propagation. + */ + + ideal_duty_cycle = + ((C_PRIME256(params) * 1000) - + (M_PRIME256(params) * h_period / 1000000)); + + /* 19. Find the number of pixels in the blanking time to the nearest + * double character cell: + * + * [H BLANK (PIXELS)] = (ROUND(([TOTAL ACTIVE PIXELS] * + * [IDEAL DUTY CYCLE] / + * (100-[IDEAL DUTY CYCLE]) / + * (2*[CELL GRAN RND])), 0)) + * * (2*[CELL GRAN RND]) + * + * Of course, we adjust to make this rounding work in integer math. + */ + + h_blank = DIVIDE(DIVIDE(total_active_pixels * ideal_duty_cycle, + (256000 * 100ULL) - ideal_duty_cycle), + 2 * CELL_GRAN) * (2 * CELL_GRAN); + + /* 20. Find total number of pixels: + * + * [TOTAL PIXELS] = [TOTAL ACTIVE PIXELS] + [H BLANK (PIXELS)] + */ + + total_pixels = total_active_pixels + h_blank; + + /* 21. Find pixel clock frequency: + * + * [PIXEL FREQ] = [TOTAL PIXELS] / [H PERIOD] + * + * We calculate this in Hz rather than MHz, to get a value that + * is usable with integer math. Recall that the [H PERIOD] is in + * nsec. + */ + + pixel_freq = DIVIDE(total_pixels * 1000000, DIVIDE(h_period, 1000)); + +#if 0 /* Not needed */ + /* 22. Find horizontal frequency: + * + * [H FREQ] = 1000 / [H PERIOD] + * + * We calculate this in Hz rather than kHz, to avoid rounding + * errors. Recall that the [H PERIOD] is in usec. + */ + + h_freq = 1000000000 / h_period; +#endif + + /* Stage 1 computations are now complete; I should really pass + * the results to another function and do the Stage 2 + * computations, but I only need a few more values so I'll just + * append the computations here for now. + */ + + /* 17. Find the number of pixels in the horizontal sync period: + * + * [H SYNC (PIXELS)] =(ROUND(([H SYNC%] / 100 * [TOTAL PIXELS] / + * [CELL GRAN RND]),0))*[CELL GRAN RND] + * + * Rewriting for integer math: + * + * [H SYNC (PIXELS)]=(ROUND((H SYNC%] * [TOTAL PIXELS] / 100 / + * [CELL GRAN RND),0))*[CELL GRAN RND] + */ + + h_sync = DIVIDE(((params->hsync_pct * total_pixels) / 100), CELL_GRAN) * + CELL_GRAN; + + /* 18. Find the number of pixels in the horizontal front porch period: + * + * [H FRONT PORCH (PIXELS)] = ([H BLANK (PIXELS)]/2)-[H SYNC (PIXELS)] + * + * Note that h_blank is always an even number of characters (i.e. + * h_blank % (CELL_GRAN * 2) == 0) + */ + + h_front_porch = (h_blank / 2) - h_sync; + + /* 36. Find the number of lines in the odd front porch period: + * + * [V ODD FRONT PORCH(LINES)]=([MIN PORCH RND]+[INTERLACE]) + * + * Adjusting for the fact that the interlace is scaled: + * + * [V ODD FRONT PORCH(LINES)]=(([MIN PORCH RND] * 2) + [2*INTERLACE]) / 2 + */ + + v_odd_front_porch_lines = ((2 * params->min_porch) + interlace) / 2; + + /* finally, pack the results in the mode struct */ + + videomode->hsync_start = h_pixels + h_front_porch; + videomode->hsync_end = videomode->hsync_start + h_sync; + videomode->htotal = total_pixels; + videomode->hdisplay = h_pixels; + + videomode->vsync_start = v_lines + v_odd_front_porch_lines; + videomode->vsync_end = videomode->vsync_start + params->vsync_rqd; + videomode->vtotal = total_v_lines; + videomode->vdisplay = v_lines; + + videomode->dotclock = pixel_freq; +} + +/**************************************************************************** + * Name: vesagtf_mode + * + * Description: + * Use VESA GTF formula to generate monitor timings. Assumes default + * GTF parameters, non-interlaced, and no margins. + * + ****************************************************************************/ + +void vesagtf_mode(unsigned int x, unsigned int y, unsigned int refresh, + FAR struct videomode_s *videomode) +{ + struct vesagtf_params params; + + params.margin_ppt = VESAGTF_MARGIN_PPT; + params.min_porch = VESAGTF_MIN_PORCH; + params.vsync_rqd = VESAGTF_VSYNC_RQD; + params.hsync_pct = VESAGTF_HSYNC_PCT; + params.min_vsbp = VESAGTF_MIN_VSBP; + params.m = VESAGTF_M; + params.c = VESAGTF_C; + params.k = VESAGTF_K; + params.j = VESAGTF_J; + + vesagtf_mode_params(x, y, refresh, ¶ms, 0, videomode); +} diff --git a/video/videomode/videomode_dump.c b/video/videomode/videomode_dump.c new file mode 100644 index 00000000000..c35ca844723 --- /dev/null +++ b/video/videomode/videomode_dump.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * video/videomode/videomode_dump.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Derives from logic in FreeBSD which has an compatible 2-clause BSD + * license: + * + * Copyright (c) 2006 Itronix Inc. All rights reserved. + * Written by Garrett D'Amore for Itronix Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED ``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 NETBSD FOUNDATION 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define DIVIDE(x,y) (((x) + ((y) / 2)) / (y)) + +/**************************************************************************** + * Name: videomode_refresh + * + * Description: + * Calculate the refresh rate. + * + * Input Parameters: + * videomode - The videomode to be dumped + * + * Returned Value: + * None + * + ****************************************************************************/ + +static uint32_t videomode_refresh(FAR const struct videomode_s *videomode) +{ + return DIVIDE(DIVIDE(videomode->dotclock * 1000, videomode->htotal), + videomode->vtotal); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: videomode_dump + * + * Description: + * Dump the content of a video mode one one line to the SYSLOG. + * + * Input Parameters: + * prefix - A string to print at the beginning of the line. May be + * NULL + * videomode - The videomode to be dumped + * terse - True: Print only a minimal amount of data, sufficient to + * identify the video mode. + * + * Returned Value: + * None + * + ****************************************************************************/ + +void videomode_dump(FAR const char *prefix, + FAR const struct videomode_s *videomode, bool terse) +{ + if (videomode != NULL) + { + if (prefix != NULL) + { + syslog(LOG_INFO, "%s", prefix); + } + + syslog(LOG_INFO, "%ux%u @ %luHz", + videomode->hdisplay, videomode->vdisplay, + (unsigned long)videomode_refresh(videomode)); + + if (!terse) + { + syslog(LOG_INFO, " (%lu %u %u %u %u %u %u", + (unsigned long)videomode->dotclock, + videomode->hsync_start, videomode->hsync_end, videomode->htotal, + videomode->vsync_start, videomode->vsync_end, videomode->vtotal); + syslog(LOG_INFO, " %s%sH %s%sV)\n", + videomode->flags & VID_PHSYNC ? "+" : "", + videomode->flags & VID_NHSYNC ? "-" : "", + videomode->flags & VID_PVSYNC ? "+" : "", + videomode->flags & VID_NVSYNC ? "-" : ""); + } + } +} diff --git a/video/edid/edid_videomode.c b/video/videomode/videomode_lookup.c similarity index 76% rename from video/edid/edid_videomode.c rename to video/videomode/videomode_lookup.c index dc944e659ed..441ff394035 100644 --- a/video/edid/edid_videomode.c +++ b/video/videomode/videomode_lookup.c @@ -1,5 +1,5 @@ /**************************************************************************** - * video/edid/edid_parse.c + * video/videomode/videomode_lookup.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -7,9 +7,7 @@ * Derives from logic in FreeBSD which has an equivalent 3-clause BSD * license: * - * Copyright (c) 2006 Itronix Inc. - * All rights reserved. - * + * Copyright (c) 2006 Itronix Inc. All rights reserved. * Written by Garrett D'Amore for Itronix Inc. * * Redistribution and use in source and binary forms, with or without @@ -47,8 +45,9 @@ #include #include +#include -#include +#include /**************************************************************************** * Pre-processor Definitions @@ -65,14 +64,14 @@ #define M(nm,hr,vr,clk,hs,he,ht,vs,ve,vt,f) \ { \ - clk, hr, hs, he, ht, vr, vs, ve, vt, f, nm \ + clk, hr, hs, he, ht, vr, vs, ve, vt, 0, f, nm \ } /**************************************************************************** * Private Data ****************************************************************************/ -static const struct edid_videomode_s g_videomodes[] = +static const struct videomode_s g_videomodes[] = { M("640x350x85", 640, 350, 31500, 672, 736, 832, 382, 385, 445, HP|VN), M("640x400x85", 640, 400, 31500, 672, 736, 832, 401, 404, 445, HN|VP), @@ -178,14 +177,15 @@ static const int g_nvideomodes = 46; ****************************************************************************/ /**************************************************************************** - * Name: edid_mode_lookup + * Name: videomode_lookup_by_name * * Description: - * Find the video mode in a look-up table + * Find the video mode in a look-up table by the name assigned to the + * video mode. * ****************************************************************************/ -FAR const struct edid_videomode_s *edid_mode_lookup(FAR const char *name) +FAR const struct videomode_s *videomode_lookup_by_name(FAR const char *name) { int i; @@ -199,3 +199,122 @@ FAR const struct edid_videomode_s *edid_mode_lookup(FAR const char *name) return NULL; } + +/**************************************************************************** + * Name: videomode_lookup_by_dotclock + * + * Description: + * Find the video mode in a look-up table with the matching width and + * height and the closest dot clock that does not exceed the requested + * dot clock. + * + ****************************************************************************/ + +#if 0 /* Not used */ +FAR const struct videomode_s * + videomode_lookup_by_dotclock(uint16_t width, uint16_t height, + uint32_t dotclock) +{ + FAR const struct videomode_s *curr; + FAR const struct videomode_s *best = NULL; + int i; + + lcdinfo("Looking for %u x %u at up to %lu kHz\n", + width, height, (unsigned long)dotclock); + + for (i = 0; i < g_nvideomodes; i++) + { + curr = &g_videomodes[i]; + + if (curr->hdisplay == width && curr->vdisplay == height && + curr->dotclock <= dotclock) + { + if (best != NULL) + { + if (curr->dotclock > best->dotclock) + { + best = curr; + } + } + } + else + { + best = curr; + } + } + + if (best != NULL) + { + lcdinfo("Found %s\n", best->name); + } + + return best; +} +#endif + +/**************************************************************************** + * Name: videomode_lookup_by_refresh + * + * Description: + * Find the video mode in a look-up table with the matching width and + * height and the closest refrsh rate that does not exceed the requested + * rate. + * + ****************************************************************************/ + +#if 0 /* Not used */ +FAR const struct videomode_s * + videomode_lookup_by_refresh(uint16_t width, uint16_t height, + uint16_t refresh) +{ + FAR const struct videomode_s *curr; + FAR const struct videomode_s *best = NULL; + uint32_t mref; + int closest = 1000; + int diff; + int i; + + lcdinfo("Looking for %u x %u at up to %u Hz\n", + width, height, refresh); + + for (i = 0; i < g_nvideomodes; i++) + { + curr = &g_videomodes[i]; + + if (curr->hdisplay == width && curr->vdisplay == height) + { + mref = curr->dotclock * 1000 / (curr->htotal * curr->vtotal); + diff = mref - (uint32_t)refresh; + if (diff < 0) + { + diff = -diff; + } + + lcdinfo("%s in %lu Hz, diff %d\n", + curr->name, (unsigned long)mref, diff); + + if (best != NULL) + { + if (diff < closest) + { + best = curr; + closest = diff; + } + } + else + { + best = curr; + closest = diff; + } + } + } + + if (best != NULL) + { + lcdinfo("Found %s %lu\n", + best->name, (unsigned long)best->dotclock); + } + + return best; +} +#endif diff --git a/video/edid/edid_sort.c b/video/videomode/videomode_sort.c similarity index 91% rename from video/edid/edid_sort.c rename to video/videomode/videomode_sort.c index 6ccf22f9bf6..0d2cd802f60 100644 --- a/video/edid/edid_sort.c +++ b/video/videomode/videomode_sort.c @@ -1,5 +1,5 @@ /**************************************************************************** - * video/edid/edid_sort.c + * video/videomode/videomode_sort.c * * Copyright (C) 2019 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -43,7 +43,7 @@ #include #include -#include +#include /**************************************************************************** * Pre-processor Definitions @@ -55,10 +55,10 @@ * Private Functions ****************************************************************************/ -static inline void swap_modes(FAR struct edid_videomode_s *left, - FAR struct edid_videomode_s *right) +static inline void videomode_swap(FAR struct videomode_s *left, + FAR struct videomode_s *right) { - struct edid_videomode_s temp; + struct videomode_s temp; temp = *left; *left = *right; @@ -82,7 +82,7 @@ static inline int _abs(int a) ****************************************************************************/ /**************************************************************************** - * Name: edid_sort_modes + * Name: sort_videomodes * * Description: * Sort video modes by refresh rate, aspect ratio, then resolution. @@ -102,10 +102,11 @@ static inline int _abs(int a) * ****************************************************************************/ -void edid_sort_modes(FAR struct edid_videomode_s *modes, - FAR struct edid_videomode_s **preferred, unsigned int nmodes) +void sort_videomodes(FAR struct videomode_s *modes, + FAR struct videomode_s **preferred, + unsigned int nmodes) { - FAR struct edid_videomode_s *tmpmode = NULL; + FAR struct videomode_s *tmpmode = NULL; int aspect; int refresh; int hbest; @@ -131,7 +132,7 @@ void edid_sort_modes(FAR struct edid_videomode_s *modes, (*preferred)->htotal), (*preferred)->vtotal); if (*preferred != modes) { - swap_modes(*preferred, modes); + videomode_swap(*preferred, modes); *preferred = modes; } } @@ -165,7 +166,7 @@ void edid_sort_modes(FAR struct edid_videomode_s *modes, tmpmode->htotal), tmpmode->vtotal); if (tmpmode != modes) { - swap_modes(tmpmode, modes); + videomode_swap(tmpmode, modes); } } @@ -220,7 +221,7 @@ void edid_sort_modes(FAR struct edid_videomode_s *modes, if (tmpmode != &modes[j]) { - swap_modes(tmpmode, &modes[j]); + videomode_swap(tmpmode, &modes[j]); } } }