diff --git a/Documentation/README.html b/Documentation/README.html
index 7c44a55916c..84a0b18c435 100644
--- a/Documentation/README.html
+++ b/Documentation/README.html
@@ -288,6 +288,8 @@ nuttx/
| | `- README.txt
| |- stm32f746g-disco/
| | `- README.txt
+ | |- stm32f769i-disco/
+ | | `- README.txt
| |- stm32l476-mdk/
| | `- README.txt
| |- stm32l476vg-disco/
diff --git a/README.txt b/README.txt
index 42d51047c5c..f069a7ba20b 100644
--- a/README.txt
+++ b/README.txt
@@ -1827,6 +1827,8 @@ nuttx/
| | `- README.txt
| |- stm32f746g-disco/
| | `- README.txt
+ | |- stm32f769i-disco/
+ | | `- README.txt
| |- stm32l476-mdk/
| | `- README.txt
| |- stm32l476vg-disco/
diff --git a/arch/arm/include/stm32f7/dma2d.h b/arch/arm/include/stm32f7/dma2d.h
new file mode 100755
index 00000000000..0ebffb05f50
--- /dev/null
+++ b/arch/arm/include/stm32f7/dma2d.h
@@ -0,0 +1,415 @@
+/****************************************************************************
+ * arch/arm/include/stm32/dma2d.h
+ *
+ * Copyright (C) 2015 Marco Krahl. All rights reserved.
+ * Author: Marco Krahl
+ *
+ * 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 __ARCH_ARM_INCLUDE_STM32F7_DMA2D_H
+#define __ARCH_ARM_INCLUDE_STM32F7_DMA2D_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+#include
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct ltdc_area_s; /* see arch/chip/ltdc.h */
+
+/* Blend mode definitions */
+
+enum dma2d_blend_e
+{
+ DMA2D_BLEND_NONE = 0, /* Disable all blend operation */
+ DMA2D_BLEND_ALPHA = 0x1, /* Enable alpha blending */
+ DMA2D_BLEND_PIXELALPHA = 0x2, /* Enable alpha blending from pixel color */
+};
+
+/* The layer is controlled through the following structure */
+
+struct dma2d_layer_s
+{
+ /* Name: getvideoinfo
+ *
+ * Description:
+ * Get video information about the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * vinfo - Reference to the video info structure
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getvideoinfo)(FAR struct dma2d_layer_s *layer,
+ FAR struct fb_videoinfo_s *vinfo);
+
+ /* Name: getplaneinfo
+ *
+ * Description:
+ * Get plane information about the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * planeno - Number of the plane
+ * pinfo - Reference to the plane info structure
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getplaneinfo)(FAR struct dma2d_layer_s *layer, int planeno,
+ FAR struct fb_planeinfo_s *pinfo);
+
+ /* Name: getlid
+ *
+ * Description:
+ * Get a specific layer identifier.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * lid - Reference to store the layer id
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getlid)(FAR struct dma2d_layer_s *layer, int *lid);
+
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ /* Name: setclut
+ *
+ * Description:
+ * Configure layer clut (color lookup table).
+ * Non clut is defined during initializing.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * cmap - color lookup table with up the 256 entries
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*setclut)(FAR struct dma2d_layer_s *layer,
+ const FAR struct fb_cmap_s *cmap);
+
+ /* Name: getclut
+ *
+ * Description:
+ * Get configured layer clut (color lookup table).
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * cmap - Reference to valid color lookup table accept up the 256 color
+ * entries
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getclut)(FAR struct dma2d_layer_s *layer, FAR struct fb_cmap_s *cmap);
+#endif
+
+ /* Name: setalpha
+ *
+ * Description:
+ * Configure layer alpha value factor into blend operation.
+ * During the layer blend operation the source alpha value is multiplied
+ * with this alpha value. If the source color format doesn't support alpha
+ * channel (e.g. non ARGB8888) this alpha value will be used as constant
+ * alpha value for blend operation.
+ * Default value during initializing: 0xff
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * alpha - Alpha value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*setalpha)(FAR struct dma2d_layer_s *layer, uint8_t alpha);
+
+ /* Name: getalpha
+ *
+ * Description:
+ * Get configured layer alpha value factor for blend operation.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * alpha - Reference to store the alpha value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getalpha)(FAR struct dma2d_layer_s *layer, uint8_t *alpha);
+
+ /* Name: setblendmode
+ *
+ * Description:
+ * Configure blend mode of the layer.
+ * Default mode during initializing: DMA2D_BLEND_NONE
+ * Blendmode is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - Blend mode (see DMA2D_BLEND_*)
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ * Procedure information:
+ * DMA2D_BLEND_NONE:
+ * Informs the driver to disable all blend operation for the given layer.
+ * That means the layer is opaque.
+ *
+ * DMA2D_BLEND_ALPHA:
+ * Informs the driver to enable alpha blending for the given layer.
+ *
+ * DMA2D_BLEND_PIXELALPHA:
+ * Informs the driver to use the pixel alpha value of the layer instead
+ * the constant alpha value. This is only useful for ARGB8888
+ * color format.
+ */
+
+ int (*setblendmode)(FAR struct dma2d_layer_s *layer, uint32_t mode);
+
+ /* Name: getblendmode
+ *
+ * Description:
+ * Get configured blend mode of the layer.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - Reference to store the blend mode
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getblendmode)(FAR struct dma2d_layer_s *layer, uint32_t *mode);
+
+ /* Name: blit
+ *
+ * Description:
+ * Copy selected area from a source layer to selected position of the
+ * destination layer.
+ *
+ * Parameter:
+ * dest - Reference to the destination layer
+ * destxpos - Selected x target position of the destination layer
+ * destypos - Selected y target position of the destination layer
+ * src - Reference to the source layer
+ * srcarea - Reference to the selected area of the source layer
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the
+ * selected source area outside the visible area of the
+ * destination layer. (The visible area usually represents the
+ * display size)
+ * -ECANCELED - Operation cancelled, something goes wrong.
+ */
+
+ int (*blit)(FAR struct dma2d_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *src,
+ FAR const struct ltdc_area_s *srcarea);
+
+ /* Name: blend
+ *
+ * Description:
+ * Blends the selected area from a background layer with selected position
+ * of the foreground layer. Copies the result to the selected position of
+ * the destination layer. Note! The content of the foreground and background
+ * layer keeps unchanged as long destination layer is unequal to the
+ * foreground and background layer.
+ *
+ * Parameter:
+ * dest - Reference to the destination layer
+ * fore - Reference to the foreground layer
+ * forexpos - Selected x target position of the foreground layer
+ * foreypos - Selected y target position of the foreground layer
+ * back - Reference to the background layer
+ * backarea - Reference to the selected area of the background layer
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the
+ * selected source area outside the visible area of the
+ * destination layer. (The visible area usually represents the
+ * display size)
+ * -ECANCELED - Operation cancelled, something goes wrong.
+ */
+
+ int (*blend)(FAR struct dma2d_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *fore,
+ fb_coord_t forexpos, fb_coord_t foreypos,
+ FAR const struct dma2d_layer_s *back,
+ FAR const struct ltdc_area_s *backarea);
+
+ /* Name: fillarea
+ *
+ * Description:
+ * Fill the selected area of the whole layer with a specific color.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * area - Reference to the valid area structure select the area
+ * color - Color to fill the selected area. Color must be formatted
+ * according to the layer pixel format.
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the
+ * selected area outside the visible area of the layer.
+ * -ECANCELED - Operation cancelled, something goes wrong.
+ */
+
+ int (*fillarea)(FAR struct dma2d_layer_s *layer,
+ FAR const struct ltdc_area_s *area,
+ uint32_t color);
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_dma2dgetlayer
+ *
+ * Description:
+ * Get a dma2d layer structure by the layer identifier
+ *
+ * Parameter:
+ * lid - Layer identifier
+ *
+ * Return:
+ * Reference to the dma2d layer control structure on success or Null if no
+ * related exist.
+ *
+ ****************************************************************************/
+
+FAR struct dma2d_layer_s *up_dma2dgetlayer(int lid);
+
+/****************************************************************************
+ * Name: up_dma2dcreatelayer
+ *
+ * Description:
+ * Create a new dma2d layer object to interact with the dma2d controller
+ *
+ * Parameter:
+ * width - Layer width
+ * height - Layer height
+ * fmt - Pixel format of the layer
+ *
+ * Return:
+ * On success - A valid dma2d layer reference
+ * On error - NULL and errno is set to
+ * -EINVAL if one of the parameter is invalid
+ * -ENOMEM if no memory available or exceeds
+ * CONFIG_STM32F7_DMA2D_NLAYERS
+ *
+ ****************************************************************************/
+
+FAR struct dma2d_layer_s *up_dma2dcreatelayer(fb_coord_t width,
+ fb_coord_t height,
+ uint8_t fmt);
+
+/****************************************************************************
+ * Name: up_dma2dremovelayer
+ *
+ * Description:
+ * Remove and deallocate the dma2d layer
+ *
+ * Parameter:
+ * layer - Reference to the layer to remove
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+int up_dma2dremovelayer(FAR struct dma2d_layer_s *layer);
+
+/****************************************************************************
+ * Name: up_dma2dinitialize
+ *
+ * Description:
+ * Initialize the dma2d controller
+ *
+ * Return:
+ * OK - On success
+ * An error if initializing failed.
+ *
+ ****************************************************************************/
+
+int up_dma2dinitialize(void);
+
+/****************************************************************************
+ * Name: up_dma2duninitialize
+ *
+ * Description:
+ * Uninitialize the dma2d controller
+ *
+ ****************************************************************************/
+
+void up_dma2duninitialize(void);
+
+#endif /* __ARCH_ARM_INCLUDE_STM32F7_DMA2D_H */
diff --git a/arch/arm/include/stm32f7/ltdc.h b/arch/arm/include/stm32f7/ltdc.h
new file mode 100755
index 00000000000..0b1e509916b
--- /dev/null
+++ b/arch/arm/include/stm32f7/ltdc.h
@@ -0,0 +1,575 @@
+/****************************************************************************
+ * arch/arm/include/stm32/ltdc.h
+ *
+ * Copyright (C) 2014-2015 Marco Krahl. All rights reserved.
+ * Author: Marco Krahl
+ *
+ * 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 __ARCH_ARM_INCLUDE_STM32F7_LTDC_H
+#define __ARCH_ARM_INCLUDE_STM32F7_LTDC_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+#include
+
+#ifdef CONFIG_STM32F7_LTDC
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+struct dma2d_layer_s; /* see arch/chip/dma2d.h */
+
+/* Blend mode definitions */
+
+enum ltdc_blend_e
+{
+ LTDC_BLEND_NONE = 0, /* Disable all blend operation */
+ LTDC_BLEND_ALPHA = 0x1, /* Enable alpha blending */
+ LTDC_BLEND_PIXELALPHA = 0x2, /* Enable alpha blending from pixel color */
+ LTDC_BLEND_COLORKEY = 0x4, /* Enable colorkey */
+ LTDC_BLEND_ALPHAINV = 0x8, /* Inverse alpha blending of source */
+ LTDC_BLEND_PIXELALPHAINV = 0x10 /* Invers pixel alpha blending of source */
+};
+
+/* layer control definitions */
+
+enum ltdc_layer_e
+{
+ LTDC_LAYER_OWN = 0, /* The given layer */
+ LTDC_LAYER_TOP = 0x1, /* The initialized top layer */
+ LTDC_LAYER_BOTTOM = 0x2, /* the initialized bottom layer */
+ LTDC_LAYER_ACTIVE = 0x4, /* The current visible flip layer */
+ LTDC_LAYER_INACTIVE = 0x8 /* The current invisible flip layer */
+#ifdef CONFIG_STM32F7_DMA2D
+ ,LTDC_LAYER_DMA2D = 0x10 /* The dma2d interface layer id */
+#endif
+};
+
+/* Update operation flag */
+
+enum ltdc_update_e
+{
+ LTDC_UPDATE_NONE = 0, /* Update given layer only */
+ LTDC_UPDATE_SIM = 0x1, /* Update both layer simultaneous */
+ LTDC_UPDATE_FLIP = 0x2, /* Perform flip operation */
+ LTDC_UPDATE_ACTIVATE = 0x4 /* Set the given layer to the active layer */
+};
+
+/* sync mode definitions */
+
+enum ltdc_sync_e
+{
+ LTDC_SYNC_NONE = 0, /* Immediately */
+ LTDC_SYNC_VBLANK = 0x100, /* Upon vertical sync */
+ LTDC_SYNC_WAIT = 0x200 /* Waits upon vertical sync */
+};
+
+/* Definition of the visible layer position and size */
+
+struct ltdc_area_s
+{
+ fb_coord_t xpos; /* X position in pixel */
+ fb_coord_t ypos; /* Y position in pixel */
+ fb_coord_t xres; /* X resolution in pixel */
+ fb_coord_t yres; /* Y resolution in pixel */
+};
+
+/* The layer is controlled through the following structure */
+
+struct ltdc_layer_s
+{
+ /* Name: getvideoinfo
+ *
+ * Description:
+ * Get video information about the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * vinfo - Reference to the video info structure
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getvideoinfo)(FAR struct ltdc_layer_s *layer,
+ FAR struct fb_videoinfo_s *vinfo);
+
+ /* Name: getplaneinfo
+ *
+ * Description:
+ * Get plane information about the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * planeno - Number of the plane
+ * pinfo - Reference to the plane info structure
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getplaneinfo)(FAR struct ltdc_layer_s *layer, int planeno,
+ FAR struct fb_planeinfo_s *pinfo);
+
+ /* Name: getlid
+ *
+ * Description:
+ * Get a specific layer identifier.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * lid - Reference to store the layer id
+ * flag - Operation flag describe the layer identifier
+ * e.g. get the current active or inactive layer.
+ * See LTDC_LAYER_* for possible values
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getlid)(FAR struct ltdc_layer_s *layer, int *lid, uint32_t flag);
+
+#ifdef CONFIG_FB_CMAP
+ /* Name: setclut
+ *
+ * Description:
+ * Configure layer clut (color lookup table).
+ * Non clut is defined during initializing.
+ * Clut is active during next vertical blank period. Do not need an update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * cmap - color lookup table with up the 256 entries
+ * enable - Enable or disable clut support (if false cmap is ignored and can
+ * be NULL)
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*setclut)(FAR struct ltdc_layer_s *layer,
+ const FAR struct fb_cmap_s *cmap);
+
+ /* Name: getclut
+ *
+ * Description:
+ * Get configured layer clut (color lookup table).
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * cmap - Reference to valid color lookup table accept up the 256 color
+ * entries
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getclut)(FAR struct ltdc_layer_s *layer, FAR struct fb_cmap_s *cmap);
+#endif
+
+ /* Name: setcolor
+ *
+ * Description:
+ * Configure layer color for the non active layer area.
+ * Default value during initializing: 0x00000000
+ * Color is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * argb - ARGB8888 color value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*setcolor)(FAR struct ltdc_layer_s *layer, uint32_t argb);
+
+ /* Name: getcolor
+ *
+ * Description:
+ * Get configured layer color for the non active layer area.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * argb - Reference to store the ARGB8888 color value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getcolor)(FAR struct ltdc_layer_s *layer, uint32_t *argb);
+
+ /* Name: setcolorkey
+ *
+ * Description:
+ * Configure the layer color key (chromakey) for transparence.
+ * Default value during initializing: 0x00000000
+ * Colorkey is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * rgb - RGB888 color key
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*setcolorkey)(FAR struct ltdc_layer_s *layer, uint32_t rgb);
+
+ /* Name: getcolorkey
+ *
+ * Description:
+ * Get the configured layer color key (chromakey) for transparence.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * rgb - Reference to store the RGB888 color key
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getcolorkey)(FAR struct ltdc_layer_s *layer, uint32_t *rgb);
+
+ /* Name: setalpha
+ *
+ * Description:
+ * Configure layer alpha value factor into blend operation.
+ * During the layer blend operation the source alpha value is multiplied
+ * with this alpha value. If the source color format doesn't support alpha
+ * channel (e.g. non ARGB8888) this alpha value will be used as constant
+ * alpha value for blend operation.
+ * Default value during initializing: 0xff
+ * Alpha is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * alpha - Alpha value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*setalpha)(FAR struct ltdc_layer_s *layer, uint8_t alpha);
+
+ /* Name: getalpha
+ *
+ * Description:
+ * Get configured layer alpha value factor for blend operation.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * alpha - Reference to store the alpha value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getalpha)(FAR struct ltdc_layer_s *layer, uint8_t *alpha);
+
+ /* Name: setblendmode
+ *
+ * Description:
+ * Configure blend mode of the layer.
+ * Default mode during initializing: LTDC_BLEND_NONE
+ * Blendmode is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - Blend mode (see LTDC_BLEND_*)
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ * Procedure information:
+ * LTDC_BLEND_NONE:
+ * Informs the driver to disable all blend operation for the given layer.
+ * That means the layer is opaque. Note this has no effect on the
+ * colorkey settings.
+ *
+ * LTDC_BLEND_ALPHA:
+ * Informs the driver to enable alpha blending for the given layer.
+ *
+ * LTDC_BLEND_COLORKEY:
+ * Informs the driver to enable colorkeying for the given layer.
+ *
+ * LTDC_BLEND_SRCPIXELALPHA:
+ * Informs the driver to use the pixel alpha value of the layer instead
+ * the constant alpha value. This is only useful for ARGB8888
+ * color format.
+ *
+ * LTDC_BLEND_DESTPIXELALPHA:
+ * Informs the driver to use the pixel alpha value of the subjacent layer
+ * instead the constant alpha value. This is only useful for ARGB8888
+ * color format.
+ */
+
+ int (*setblendmode)(FAR struct ltdc_layer_s *layer, uint32_t mode);
+
+ /* Name: getblendmode
+ *
+ * Description:
+ * Get configured blend mode of the layer.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - Reference to store the blend mode
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getblendmode)(FAR struct ltdc_layer_s *layer, uint32_t *mode);
+
+ /* Name: setarea
+ *
+ * Description:
+ * Configure visible layer area and the reference position of the first
+ * pixel of the whole layer which is the first visible top left pixel in
+ * the active area.
+ * Default value during initializing:
+ * xpos = 0
+ * ypos = 0
+ * xres = display x resolution
+ * yres = display y resolution
+ *
+ * Area is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * area - Reference to the valid area structure for the new active area
+ * srcxpos - x position of the visible pixel of the whole layer
+ * srcypos - y position of the visible pixel of the whole layer
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ * Procedure Information:
+ * If the srcxpos and srcypos unequal the xpos and ypos of the coord
+ * structure this acts like moving the visible area to another position on
+ * the screen during the next update operation.
+ */
+
+ int (*setarea)(FAR struct ltdc_layer_s *layer,
+ FAR const struct ltdc_area_s *area,
+ fb_coord_t srcxpos,
+ fb_coord_t srcypos);
+
+ /* Name: getarea
+ *
+ * Description:
+ * Get configured visible layer area.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * area - Reference to the area structure to store the active area
+ * srcxpos - Reference to store the referenced x position of the whole layer
+ * srcypos - Reference to store the reterenced y position of the whole layer
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ */
+
+ int (*getarea)(FAR struct ltdc_layer_s *layer,
+ FAR struct ltdc_area_s *area,
+ fb_coord_t *srcxpos,
+ fb_coord_t *srcypos);
+
+ /* Name: update
+ *
+ * Description:
+ * Update current layer settings and make changes visible.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - operation mode (see LTDC_UPDATE_*)
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid
+ * -ECANCELED - Operation cancelled, something goes wrong
+ *
+ * Procedure information:
+ * LTDC_UPDATE_SIM:
+ * Informs the driver to update both ltdc layers simultaneously. Otherwise
+ * update the given layer only.
+ *
+ * LTDC_UPDATE_FLIP:
+ * Informs the driver to perform a flip operation.
+ * This only effects the ltdc layer 1 and 2 and can be useful for double
+ * buffering. Each flip operation changed the active layer ot the inactive
+ * and vice versa. In the context of the ltdc that means, the inactive layer
+ * is complete disabled. So the subjacent layer is the background layer
+ * (background color). To reactivate both layer and their settings perform
+ * an update without LTDC_UPDATE_FLIP flag.
+ *
+ * LTDC_UPDATE_ACTIVATE:
+ * Informs the driver that the given layer should be the active layer when
+ * the operation is complete.
+ *
+ * LTDC_SYNC_VBLANK:
+ * Informs the driver to update the layer upon vertical blank. Otherwise
+ * immediately.
+ */
+
+ int (*update)(FAR struct ltdc_layer_s *layer, uint32_t mode);
+
+#ifdef CONFIG_STM32F7_DMA2D
+ /* Name: blit
+ *
+ * Description:
+ * Copy selected area from a source layer to selected position of the
+ * destination layer.
+ *
+ * Parameter:
+ * dest - Reference to the destination layer
+ * destxpos - Selected x position of the destination layer
+ * destypos - Selected y position of the destination layer
+ * src - Reference to the source layer
+ * srcarea - Reference to the selected area of the source layer
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * source area outside the visible area of the destination layer.
+ * (The visible area usually represents the display size)
+ */
+
+ int (*blit)(FAR struct ltdc_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *src,
+ FAR const struct ltdc_area_s *srcarea);
+
+ /* Name: blend
+ *
+ * Description:
+ * Blends the selected area from a foreground layer with selected position
+ * of the background layer. Copy the result to the destination layer. Note!
+ * The content of the foreground and background layer is not changed.
+ *
+ * Parameter:
+ * dest - Reference to the destination layer
+ * destxpos - Selected x position of the destination layer
+ * destypos - Selected y position of the destination layer
+ * fore - Reference to the foreground layer
+ * forexpos - Selected x position of the foreground layer
+ * foreypos - Selected y position of the foreground layer
+ * back - Reference to the background layer
+ * backarea - Reference to the selected area of the background layer
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * source area outside the visible area of the destination layer.
+ * (The visible area usually represents the display size)
+ */
+
+ int (*blend)(FAR struct ltdc_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *fore,
+ fb_coord_t forexpos, fb_coord_t foreypos,
+ FAR const struct dma2d_layer_s *back,
+ FAR const struct ltdc_area_s *backarea);
+
+ /* Name: fillarea
+ *
+ * Description:
+ * Fill the selected area of the whole layer with a specific color.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * area - Reference to the valid area structure select the area
+ * color - Color to fill the selected area. Color must be formatted
+ * according to the layer pixel format.
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * area outside the visible area of the layer.
+ */
+
+ int (*fillarea)(FAR struct ltdc_layer_s *layer,
+ FAR const struct ltdc_area_s *area,
+ uint32_t color);
+#endif
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_ltdcgetlayer
+ *
+ * Description:
+ * Get the ltdc layer structure to perform hardware layer operation
+ *
+ * Parameter:
+ * lid - Layer identifier
+ *
+ * Return:
+ * Reference to the layer control structure on success or Null if parameter
+ * invalid.
+ *
+ ****************************************************************************/
+
+FAR struct ltdc_layer_s *up_ltdcgetlayer(int lid);
+
+#endif /* CONFIG_STM32F7_LTDC */
+#endif /* __ARCH_ARM_INCLUDE_STM32F7_LTDC_H */
+
diff --git a/arch/arm/src/samdl/chip/samd_gclk.h b/arch/arm/src/samdl/chip/samd_gclk.h
index 6c337d8bd75..5426dc394d3 100644
--- a/arch/arm/src/samdl/chip/samd_gclk.h
+++ b/arch/arm/src/samdl/chip/samd_gclk.h
@@ -127,10 +127,11 @@
# define GCLK_CLKCTRL_ID_WDT (3 << GCLK_CLKCTRL_ID_SHIFT) /* WDT */
# define GCLK_CLKCTRL_ID_RTC (4 << GCLK_CLKCTRL_ID_SHIFT) /* RTC */
# define GCLK_CLKCTRL_ID_EIC (5 << GCLK_CLKCTRL_ID_SHIFT) /* EIC */
+# define GCLK_CLKCTRL_ID_USB (6 << GCLK_CLKCTRL_ID_SHIFT) /* USB */
# define GCLK_CLKCTRL_ID_EVSYS(n) (((n)+7) << GCLK_CLKCTRL_ID_SHIFT)
# define GCLK_CLKCTRL_ID_EVSYS0 (7 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_0 */
# define GCLK_CLKCTRL_ID_EVSYS1 (8 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_1 */
-# define GCLK_CLKCTRL_ID_EVSYS2 (9 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_2 */
+# define GCLK_CLKCTRL_ID_EVSYS2 (9 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_2 */
# define GCLK_CLKCTRL_ID_EVSYS3 (10 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_3 */
# define GCLK_CLKCTRL_ID_EVSYS4 (11 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_4 */
# define GCLK_CLKCTRL_ID_EVSYS5 (12 << GCLK_CLKCTRL_ID_SHIFT) /* EVSYS_CHANNEL_5 */
diff --git a/arch/arm/src/samdl/chip/samd_i2c_master.h b/arch/arm/src/samdl/chip/samd_i2c_master.h
index 5b674729f35..0f459cd307b 100644
--- a/arch/arm/src/samdl/chip/samd_i2c_master.h
+++ b/arch/arm/src/samdl/chip/samd_i2c_master.h
@@ -235,10 +235,10 @@
#define I2C_BAUD_SHIFT (0) /* Bits 0-7: Master baud rate */
#define I2C_BAUD_MASK (0xff << I2C_BAUD_SHIFT)
-# define I2C_BAUD(n) ((uint16)(n) << I2C_BAUD_SHIFT)
+# define I2C_BAUD(n) ((uint16_t)(n) << I2C_BAUD_SHIFT)
#define I2C_BAUDLOW_SHIFT (8) /* Bits 8-15: Master baud rate low */
#define I2C_BAUDLOW_MASK (0xff << I2C_BAUDLOW_SHIFT)
-# define I2C_BAUDLOW(n) (uint16)(n) << I2C_BAUDLOW_SHIFT)
+# define I2C_BAUDLOW(n) (uint16_t)(n) << I2C_BAUDLOW_SHIFT
#ifdef CONFIG_ARCH_FAMILY_SAMD21
# define I2C_HSBAUD_SHIFT (16) /* Bits 16-23: High speed master baud rate */
@@ -246,7 +246,7 @@
# define I2C_HSBAUD(n) ((uint16)(n) << I2C_HSBAUD_SHIFT)
# define I2C_HSBAUDLOW_SHIFT (24) /* Bits 24-31: High speed master baud rate low */
# define I2C_HSBAUDLOW_MASK (0xff << I2C_HSBAUDLOW_SHIFT)
-# define I2C_HSBAUDLOW(n) (uint16)(n) << I2C_HSBAUDLOW_SHIFT)
+# define I2C_HSBAUDLOW(n) (uint16)(n) << I2C_HSBAUDLOW_SHIFT
#endif
/* Interrupt enable clear, interrupt enable set, interrupt enable set, interrupt flag and
diff --git a/arch/arm/src/samdl/chip/saml_usb.h b/arch/arm/src/samdl/chip/saml_usb.h
index 29ffadde9ae..fd2d733fe59 100644
--- a/arch/arm/src/samdl/chip/saml_usb.h
+++ b/arch/arm/src/samdl/chip/saml_usb.h
@@ -49,7 +49,7 @@
#include "chip.h"
-#ifdef CONFIG_ARCH_FAMILY_SAML21
+#if defined(CONFIG_ARCH_FAMILY_SAML21) || defined(CONFIG_ARCH_FAMILY_SAMD21)
/********************************************************************************************
* Pre-processor Definitions
diff --git a/arch/arm/src/samdl/sam_usb.c b/arch/arm/src/samdl/sam_usb.c
index 175e486a38a..02521250738 100644
--- a/arch/arm/src/samdl/sam_usb.c
+++ b/arch/arm/src/samdl/sam_usb.c
@@ -106,7 +106,13 @@
#include "up_arch.h"
#include "up_internal.h"
-#include "saml_periphclks.h"
+
+#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21)
+ #include "samd_periphclks.h"
+#elif defined(CONFIG_ARCH_FAMILY_SAML21)
+ #include "saml_periphclks.h"
+#endif
+
#include "sam_gclk.h"
#include "chip.h"
#include "sam_port.h"
@@ -133,7 +139,7 @@
* enabled.
*/
-#ifndef CONFIG_DEBUG
+#ifndef CONFIG_DEBUG_USB
# undef CONFIG_SAMDL_USB_REGDEBUG
#endif
@@ -891,7 +897,7 @@ static inline void sam_putreg8(uint8_t regval, uint32_t regaddr)
* Name: sam_dumpep
****************************************************************************/
-#if defined(CONFIG_SAMDL_USB_REGDEBUG) && defined(CONFIG_DEBUG)
+#if defined(CONFIG_SAMDL_USB_REGDEBUG) && defined(CONFIG_DEBUG_USB)
static void sam_dumpep(struct sam_usbdev_s *priv, uint8_t epno)
{
/* Global Registers */
@@ -1620,7 +1626,7 @@ static int sam_ep_configure(struct usbdev_ep_s *ep,
/* Verify parameters. Endpoint 0 is not available at this interface */
-#if defined(CONFIG_DEBUG) || defined(CONFIG_USBDEV_TRACE)
+#if defined(CONFIG_DEBUG_USB) || defined(CONFIG_USBDEV_TRACE)
uint8_t epno = USB_EPNO(desc->addr);
usbtrace(TRACE_EPCONFIGURE, (uint16_t)epno);
@@ -1666,7 +1672,7 @@ static int sam_ep_disable(struct usbdev_ep_s *ep)
irqstate_t flags;
uint8_t epno;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!ep)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -1703,7 +1709,7 @@ static struct usbdev_req_s *sam_ep_allocreq(struct usbdev_ep_s *ep)
{
struct sam_req_s *privreq;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!ep)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -1736,7 +1742,7 @@ static void sam_ep_freereq(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
{
struct sam_req_s *privreq = (struct sam_req_s*)req;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!ep || !req)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -1803,7 +1809,7 @@ static int sam_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
uint8_t epno;
int ret = OK;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!req || !req->callback || !req->buf || !ep)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -1816,7 +1822,7 @@ static int sam_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
usbtrace(TRACE_EPSUBMIT, USB_EPNO(ep->eplog));
priv = privep->dev;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!priv->driver)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_NOTCONFIGURED), priv->usbdev.speed);
@@ -1914,7 +1920,7 @@ static int sam_ep_cancel(struct usbdev_ep_s *ep, struct usbdev_req_s *req)
struct sam_ep_s *privep = (struct sam_ep_s *)ep;
irqstate_t flags;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!ep || !req)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -1940,7 +1946,7 @@ static int sam_ep_stallresume(struct usbdev_ep_s *ep, bool resume)
irqstate_t flags;
int ret;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!ep)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -2015,7 +2021,7 @@ static struct usbdev_ep_s *sam_allocep(struct usbdev_s *dev, uint8_t epno,
uint16_t epset = SAM_EPSET_NOTEP0;
usbtrace(TRACE_DEVALLOCEP, (uint16_t)epno);
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!dev)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -2077,7 +2083,7 @@ static void sam_freeep(struct usbdev_s *dev, struct usbdev_ep_s *ep)
struct sam_usbdev_s *priv;
struct sam_ep_s *privep;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!dev || !ep)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -2109,7 +2115,7 @@ static int sam_getframe(struct usbdev_s *dev)
uint32_t regval;
uint16_t frameno;
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!dev)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -2141,7 +2147,7 @@ static int sam_wakeup(struct usbdev_s *dev)
uint16_t regval;
usbtrace(TRACE_DEVWAKEUP, 0);
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!dev)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -2188,7 +2194,7 @@ static int sam_selfpowered(struct usbdev_s *dev, bool selfpowered)
usbtrace(TRACE_DEVSELFPOWERED, (uint16_t)selfpowered);
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!dev)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
@@ -3720,7 +3726,36 @@ static int sam_pullup(struct usbdev_s *dev, bool enable)
static void sam_enableclks(void)
{
sam_usb_enableperiph();
+
+#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21)
+ uint16_t regval;
+
+ /* Enable GCLK specified by BOARD_USB_GCLKGEN */
+
+ regval = GCLK_CLKCTRL_ID_USB;
+ putreg16(regval, SAM_GCLK_CLKCTRL);
+
+ /* Wait for clock to become disabled */
+
+ while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) != 0);
+
+ /* Select the USB source clock generator */
+
+ regval |= (uint16_t)BOARD_USB_GCLKGEN << GCLK_CLKCTRL_GEN_SHIFT;
+
+ /* Write the new configuration */
+
+ putreg16(regval, SAM_GCLK_CLKCTRL);
+
+ regval |= GCLK_CLKCTRL_CLKEN;
+ putreg16(regval, SAM_GCLK_CLKCTRL);
+
+ while ((getreg16(SAM_GCLK_CLKCTRL) & GCLK_CLKCTRL_CLKEN) == 0);
+
+#elif defined(CONFIG_ARCH_FAMILY_SAML21)
sam_gclk_chan_enable(GCLK_CHAN_USB, BOARD_USB_GCLKGEN);
+
+#endif
}
/****************************************************************************
@@ -3729,9 +3764,12 @@ static void sam_enableclks(void)
static void sam_disableclks(void)
{
- sam_gclk_chan_disable(GCLK_CHAN_USB);
- sam_usb_disableperiph();
+#if defined(CONFIG_ARCH_FAMILY_SAMD20) || defined(CONFIG_ARCH_FAMILY_SAMD21)
+#elif defined(CONFIG_ARCH_FAMILY_SAML21)
+ sam_gclk_chan_disable(GCLK_CHAN_USB);
+#endif
+ sam_usb_disableperiph();
}
/****************************************************************************
@@ -3901,7 +3939,8 @@ static void sam_sw_setup(struct sam_usbdev_s *priv)
/* Select a smaller endpoint size for EP0 */
-#if SAM_EP0_MAXPACKET < SAM_USB_MAXPACKETSIZE(0)
+//#if SAM_EP0_MAXPACKET < SAM_USB_MAXPACKETSIZE(0)
+#if SAM_EP0_MAXPACKET < 64
priv->eplist[EP0].ep.maxpacket = SAM_EP0_MAXPACKET;
#endif
}
@@ -3940,7 +3979,7 @@ int usbdev_register(struct usbdevclass_driver_s *driver)
usbtrace(TRACE_DEVREGISTER, 0);
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (!driver || !driver->ops->bind || !driver->ops->unbind ||
!driver->ops->disconnect || !driver->ops->setup)
{
@@ -4013,7 +4052,7 @@ int usbdev_unregister(struct usbdevclass_driver_s *driver)
usbtrace(TRACE_DEVUNREGISTER, 0);
-#ifdef CONFIG_DEBUG
+#ifdef CONFIG_DEBUG_USB
if (driver != priv->driver)
{
usbtrace(TRACE_DEVERROR(SAM_TRACEERR_INVALIDPARMS), 0);
diff --git a/arch/arm/src/samdl/sam_usb.h b/arch/arm/src/samdl/sam_usb.h
index 278f8e88ebf..bbc10e7caa5 100644
--- a/arch/arm/src/samdl/sam_usb.h
+++ b/arch/arm/src/samdl/sam_usb.h
@@ -88,7 +88,7 @@ extern "C"
*
*****************************************************************************/
-void sam_udp_suspend(FAR struct usbdev_s *dev, bool resume);
+void sam_usb_suspend(FAR struct usbdev_s *dev, bool resume);
#undef EXTERN
#if defined(__cplusplus)
diff --git a/arch/arm/src/stm32f7/Kconfig b/arch/arm/src/stm32f7/Kconfig
index 123277ba133..b26e05f49d0 100644
--- a/arch/arm/src/stm32f7/Kconfig
+++ b/arch/arm/src/stm32f7/Kconfig
@@ -1176,9 +1176,12 @@ config STM32F7_LTDC
depends on STM32F7_HAVE_LTDC
---help---
The STM32 LTDC is an LCD-TFT Display Controller available on
- the STM32F429 and STM32F439 devices. It is a standard parallel
- video interface (HSYNC, VSYNC, etc.) for controlling TFT
- LCD displays.
+ the STM32F7x6, STM32F7x7, STM32F7x8 and STM32F7x9 devices.
+ It features a standard RGB888 parallel video interface (along
+ with HSYNC, VSYNC, etc.) for controlling TFT LCD displays.
+ With the STM32F7x8/9, the graphics signals can optionally
+ be output via DSI instead of the parallel interface:
+ See config options STM32F7_DSIHOST and STM32F7_LTDC_USE_DSI.
config STM32F7_OTGFS
bool "OTG FS"
@@ -4652,7 +4655,221 @@ config STM32F7_ETHMAC_REGDEBUG
default n
depends on DEBUG_NET_INFO
---help---
- Enable very low-level register access debug. Depends on CONFIG_DEBUG_FEATURES.
+ Enable very low-level register access debug. Depends on
+ CONFIG_DEBUG_FEATURES.
endmenu # Ethernet MAC configuration
+
+if STM32F7_LTDC
+
+menu "LTDC Configuration"
+
+config STM32F7_LTDC_INTERFACE
+ bool "LTDC interface support"
+ default n
+ ---help---
+ Enable the ltdc interface to support ltdc layer control.
+
+config STM32F7_LTDC_USE_DSI
+ bool "Use DSI as display connection"
+ default n
+ depends on STM32F7_DSIHOST
+ ---help---
+ Select this if your display is connected via DSI.
+ Deselect option if your display is connected via digital
+ RGB+HSYNC+VSYNC
+
+config STM32F7_LTDC_BACKLIGHT
+ bool "Backlight support"
+ default y
+
+config STM32F7_LTDC_DEFBACKLIGHT
+ hex "Default backlight level"
+ default 0xf0
+
+config STM32F7_LTDC_BACKCOLOR
+ hex "Background color"
+ default 0x0
+ ---help---
+ This is the background color that will be used as the LTDC
+ background layer color. It is an RGB888 format value.
+
+config STM32F7_LTDC_DITHER
+ bool "Dither support"
+ default n
+
+config STM32F7_LTDC_DITHER_RED
+ depends on STM32F7_LTDC_DITHER
+ int "Dither red width"
+ range 0 7
+ default 2
+ ---help---
+ This is the dither red width.
+
+config STM32F7_LTDC_DITHER_GREEN
+ depends on STM32F7_LTDC_DITHER
+ int "Dither green width"
+ range 0 7
+ default 2
+ ---help---
+ This is the dither green width.
+
+config STM32F7_LTDC_DITHER_BLUE
+ depends on STM32F7_LTDC_DITHER
+ int "Dither blue width"
+ range 0 7
+ default 2
+ ---help---
+ This is the dither blue width.
+
+config STM32F7_LTDC_FB_BASE
+ hex "Framebuffer memory start address"
+ ---help---
+ If you are using the LTDC, then you must provide the address
+ of the start of the framebuffer. This address will typically
+ be in the SRAM or SDRAM memory region of the FSMC.
+
+config STM32F7_LTDC_FB_SIZE
+ int "Framebuffer memory size (bytes)"
+ default 0
+
+choice
+ prompt "Layer 1 color format"
+ default STM32F7_LTDC_L1_RGB565
+
+config STM32F7_LTDC_L1_L8
+ bool "8 bpp L8 (8-bit CLUT)"
+
+config STM32F7_LTDC_L1_AL44
+ bool "8 bpp AL44 (4-bit alpha + 4-bit CLUT)"
+
+config STM32F7_LTDC_L1_AL88
+ bool "16 bpp AL88 (8-bit alpha + 8-bit CLUT)"
+
+config STM32F7_LTDC_L1_RGB565
+ bool "16 bpp RGB 565"
+
+config STM32F7_LTDC_L1_ARGB4444
+ bool "16 bpp ARGB 4444"
+
+config STM32F7_LTDC_L1_ARGB1555
+ bool "16 bpp ARGB 1555"
+
+config STM32F7_LTDC_L1_RGB888
+ bool "24 bpp RGB 888"
+
+config STM32F7_LTDC_L1_ARGB8888
+ bool "32 bpp ARGB 8888"
+
+endchoice # Layer 1 color format
+
+config STM32F7_LTDC_L2
+ bool "Enable Layer 2 support"
+ default y
+
+if STM32F7_LTDC_L2
+
+choice
+ prompt "Layer 2 (top layer) color format"
+ default STM32F7_LTDC_L2_RGB565
+
+config STM32F7_LTDC_L2_L8
+ bool "8 bpp L8 (8-bit CLUT)"
+
+config STM32F7_LTDC_L2_AL44
+ bool "8 bpp AL44 (4-bit alpha + 4-bit CLUT)"
+
+config STM32F7_LTDC_L2_AL88
+ bool "16 bpp AL88 (8-bit alpha + 8-bit CLUT)"
+
+config STM32F7_LTDC_L2_RGB565
+ bool "16 bpp RGB 565"
+
+config STM32F7_LTDC_L2_ARGB4444
+ bool "16 bpp ARGB 4444"
+
+config STM32F7_LTDC_L2_ARGB1555
+ bool "16 bpp ARGB 1555"
+
+config STM32F7_LTDC_L2_RGB888
+ bool "24 bpp RGB 888"
+
+config STM32F7_LTDC_L2_ARGB8888
+ bool "32 bpp ARGB 8888"
+
+endchoice # Layer 2 color format
+
+endif # STM32F7_LTDC_L2
+
+if STM32F7_LTDC_L1_L8 || STM32F7_LTDC_L2_L8
+
+config FB_CMAP
+ bool "Enable color map support"
+ default y
+ ---help---
+ Enabling color map support is neccessary for ltdc L8 format.
+
+config FB_TRANSPARENCY
+ bool "Enable transparency color map support"
+ default y
+ ---help---
+ Enabling transparency color map support is neccessary for
+ ltdc L8 format.
+
+endif
+endmenu
+
+endif # STM32F7_LTDC
+
+if STM32F7_DMA2D
+
+menu "DMA2D Configuration"
+
+config STM32F7_DMA2D_NLAYERS
+ int "Number DMA2D layers"
+ default 2
+ ---help---
+ Number of allocatable DMA2D layers except the LTDC layer.
+
+menu "Supported pixel format"
+
+config STM32F7_DMA2D_L8
+ depends on FB_CMAP
+ bool "8 bpp L8 (8-bit CLUT)"
+ default y
+
+config STM32F7_DMA2D_AL44
+ depends on FB_CMAP
+ bool "8 bpp AL44 (4-bit alpha + 4-bit CLUT)"
+ default n
+
+config STM32F7_DMA2D_AL88
+ depends on FB_CMAP
+ bool "16 bpp AL88 (8-bit alpha + 8-bit CLUT)"
+ default n
+
+config STM32F7_DMA2D_RGB565
+ bool "16 bpp RGB 565"
+ default y
+
+config STM32F7_DMA2D_ARGB4444
+ bool "16 bpp ARGB 4444"
+ default n
+
+config STM32F7_DMA2D_ARGB1555
+ bool "16 bpp ARGB 1555"
+ default n
+
+config STM32F7_DMA2D_RGB888
+ bool "24 bpp RGB 888"
+ default y
+
+config STM32F7_DMA2D_ARGB8888
+ bool "32 bpp ARGB 8888"
+ default n
+
+endmenu
+endmenu
+endif # STM32F7_DMA2D
+
endif # ARCH_CHIP_STM32F7
diff --git a/arch/arm/src/stm32f7/Make.defs b/arch/arm/src/stm32f7/Make.defs
index 06a190f463f..283f28e172e 100644
--- a/arch/arm/src/stm32f7/Make.defs
+++ b/arch/arm/src/stm32f7/Make.defs
@@ -202,3 +202,11 @@ endif
ifeq ($(CONFIG_STM32F7_RNG),y)
CHIP_CSRCS += stm32_rng.c
endif
+
+ifeq ($(CONFIG_STM32F7_LTDC),y)
+CHIP_CSRCS += stm32_ltdc.c
+endif
+
+ifeq ($(CONFIG_STM32F7_DMA2D),y)
+CHIP_CSRCS += stm32_dma2d.c
+endif
diff --git a/arch/arm/src/stm32f7/chip/stm32_dma2d.h b/arch/arm/src/stm32f7/chip/stm32_dma2d.h
new file mode 100755
index 00000000000..7a44561a1db
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32_dma2d.h
@@ -0,0 +1,230 @@
+/****************************************************************************
+ * arch/arm/src/stm32/chip/stm32_dma2d.h
+ *
+ * Copyright (C) 2014-2015 Marco Krahl. All rights reserved.
+ * Author: Marco Krahl
+ *
+ * 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 __ARCH_ARM_SRC_STM32_CHIP_STM32_DMA2D_H
+#define __ARCH_ARM_SRC_STM32_CHIP_STM32_DMA2D_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include "chip/stm32_memorymap.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define STM32_DMA2D_NCLUT 256 /* Number of entries in the CLUT */
+
+/* DMA2D Register Offsets ****************************************************/
+
+#define STM32_DMA2D_CR_OFFSET 0x0000 /* DMA2D Control Register */
+#define STM32_DMA2D_ISR_OFFSET 0x0004 /* DMA2D Interrupt Status Register */
+#define STM32_DMA2D_IFCR_OFFSET 0x0008 /* DMA2D Interrupt Flag Clear Register */
+#define STM32_DMA2D_FGMAR_OFFSET 0x000C /* DMA2D Foreground Memory Address Register */
+#define STM32_DMA2D_FGOR_OFFSET 0x0010 /* DMA2D Foreground Offset Register */
+#define STM32_DMA2D_BGMAR_OFFSET 0x0014 /* DMA2D Background Memory Address Register */
+#define STM32_DMA2D_BGOR_OFFSET 0x0018 /* DMA2D Background Offset Register */
+#define STM32_DMA2D_FGPFCCR_OFFSET 0x001C /* DMA2D Foreground PFC Control Register */
+#define STM32_DMA2D_FGCOLR_OFFSET 0x0020 /* DMA2D Foreground Color Register */
+#define STM32_DMA2D_BGPFCCR_OFFSET 0x0024 /* DMA2D Background PFC Control Register */
+#define STM32_DMA2D_BGCOLR_OFFSET 0x0028 /* DMA2D Background Color Register */
+#define STM32_DMA2D_FGCMAR_OFFSET 0x002C /* DMA2D Foreground CLUT Memory Address Register */
+#define STM32_DMA2D_BGCMAR_OFFSET 0x0030 /* DMA2D Background CLUT Memory Address Register */
+#define STM32_DMA2D_OPFCCR_OFFSET 0x0034 /* DMA2D Output PFC Control Register */
+#define STM32_DMA2D_OCOLR_OFFSET 0x0038 /* DMA2D Output Color Register */
+#define STM32_DMA2D_OMAR_OFFSET 0x003C /* DMA2D Output Memory Address Register */
+#define STM32_DMA2D_OOR_OFFSET 0x0040 /* DMA2D Output Offset Register */
+#define STM32_DMA2D_NLR_OFFSET 0x0044 /* DMA2D Number Of Line Register */
+#define STM32_DMA2D_LWR_OFFSET 0x0048 /* DMA2D Line Watermark Register */
+#define STM32_DMA2D_AMTCR_OFFSET 0x004C /* DMA2D AHB Master Time Configuration Register */
+
+/* DMA2D Register Addresses **************************************************/
+
+#define STM32_DMA2D_CR (STM32_DMA2D_BASE+STM32_DMA2D_CR_OFFSET)
+#define STM32_DMA2D_ISR (STM32_DMA2D_BASE+STM32_DMA2D_ISR_OFFSET)
+#define STM32_DMA2D_IFCR (STM32_DMA2D_BASE+STM32_DMA2D_IFCR_OFFSET)
+#define STM32_DMA2D_FGMAR (STM32_DMA2D_BASE+STM32_DMA2D_FGMAR_OFFSET)
+#define STM32_DMA2D_FGOR (STM32_DMA2D_BASE+STM32_DMA2D_FGOR_OFFSET)
+#define STM32_DMA2D_BGMAR (STM32_DMA2D_BASE+STM32_DMA2D_BGMAR_OFFSET)
+#define STM32_DMA2D_BGOR (STM32_DMA2D_BASE+STM32_DMA2D_BGOR_OFFSET)
+#define STM32_DMA2D_FGPFCCR (STM32_DMA2D_BASE+STM32_DMA2D_FGPFCCR_OFFSET)
+#define STM32_DMA2D_FGCOLR (STM32_DMA2D_BASE+STM32_DMA2D_FGCOLR_OFFSET)
+#define STM32_DMA2D_BGPFCCR (STM32_DMA2D_BASE+STM32_DMA2D_BGPFCCR_OFFSET)
+#define STM32_DMA2D_BGCOLR (STM32_DMA2D_BASE+STM32_DMA2D_BGCOLR_OFFSET)
+#define STM32_DMA2D_FGCMAR (STM32_DMA2D_BASE+STM32_DMA2D_FGCMAR_OFFSET)
+#define STM32_DMA2D_BGCMAR (STM32_DMA2D_BASE+STM32_DMA2D_BGCMAR_OFFSET)
+#define STM32_DMA2D_OPFCCR (STM32_DMA2D_BASE+STM32_DMA2D_OPFCCR_OFFSET)
+#define STM32_DMA2D_OCOLR (STM32_DMA2D_BASE+STM32_DMA2D_OCOLR_OFFSET)
+#define STM32_DMA2D_OMAR (STM32_DMA2D_BASE+STM32_DMA2D_OMAR_OFFSET)
+#define STM32_DMA2D_OOR (STM32_DMA2D_BASE+STM32_DMA2D_OOR_OFFSET)
+#define STM32_DMA2D_NLR (STM32_DMA2D_BASE+STM32_DMA2D_NLR_OFFSET)
+#define STM32_DMA2D_LWR (STM32_DMA2D_BASE+STM32_DMA2D_LWR_OFFSET)
+
+/* DMA2D Register Bit Definitions ********************************************/
+
+/* DMA2D Control Register */
+
+#define DMA2D_CR_START (1 << 0) /* Start Bit */
+#define DMA2D_CR_SUSP (1 << 1) /* Suspend Bit */
+#define DMA2D_CR_ABORT (1 << 2) /* Abort Bit */
+#define DMA2D_CR_TEIE (1 << 8) /* Transfer Error Interupt Enable Bit */
+#define DMA2D_CR_TCIE (1 << 9) /* Transfer Complete Interrupt Enable Bit */
+#define DMA2D_CR_TWIE (1 << 10) /* Transfer Watermark Interrupt Enable Bit */
+#define DMA2D_CR_CAEIE (1 << 11) /* CLUT Access Error Interrupt Enable Bit */
+#define DMA2D_CR_CTCIE (1 << 12) /* CLUT Transfer Complete Interrupt Enable Bit */
+#define DMA2D_CR_CEIE (1 << 13) /* Configuration Error Interrupt Enable Bit */
+#define DMA2D_CR_MODE_SHIFT (16) /* Bits 16-17 DMA2D mode Bits */
+#define DMA2D_CR_MODE_MASK (3 << DMA2D_CR_MODE_SHIFT)
+#define DMA2D_CR_MODE(n) ((uint32_t)(n) << DMA2D_CR_MODE_SHIFT)
+
+/* DMA2D Interrupt Status Register */
+
+#define DMA2D_ISR_TEIF (1 << 0) /* Transfer error interrupt flag */
+#define DMA2D_ISR_TCIF (1 << 1) /* Transfer Complete Interrupt flag */
+#define DMA2D_ISR_TWIF (1 << 2) /* Transfer Watermark Interrupt flag */
+#define DMA2D_ISR_CAEIF (1 << 3) /* CLUT Access Error Interrupt flag */
+#define DMA2D_ISR_CTCIF (1 << 4) /* CLUT Transfer Complete Interrupt flag */
+#define DMA2D_ISR_CEIF (1 << 5) /* Configuration Error Interrupt flag */
+
+/* DMA2D Interrupt Flag Clear Register */
+
+#define DMA2D_IFCR_CTEIF (1 << 0) /* Clear Transfer Interrupt Flag */
+#define DMA2D_IFCR_CTCIF (1 << 1) /* Clear Transfer Complete Interrupt Flag */
+#define DMA2D_IFCR_CTWIF (1 << 2) /* Clear Transfer Watermark Interrupt Flag */
+#define DMA2D_IFCR_CAECIF (1 << 3) /* Clear CLUT Access Error Interrupt Flag */
+#define DMA2D_IFCR_CCTCIF (1 << 4) /* Clear CLUT Transfer Complete Interrupt Flag */
+#define DMA2D_IFCR_CCEIF (1 << 5) /* Clear Configuration Error Interrupt Flag */
+
+/* DMA2D Foreground Memory Access Register */
+
+/* DMA2D Background Memory Access Register */
+
+/* DMA2D Foreground/Background Offset Register */
+
+#define DMA2D_xGOR_SHIFT (0) /* Bits 0-13 Line Offset */
+#define DMA2D_xGOR_MASK (0x3FFF << DMA2D_xGOR_SHIFT)
+#define DMA2D_xGOR(n) ((uint32_t)(n) << DMA2D_xGOR_SHIFT)
+
+/* DMA2D Foreground/Background PFC Control Register */
+
+#define DMA2D_xGPFCCR_CM_SHIFT (0) /* Bits 0-3 Color Mode */
+#define DMA2D_xGPFCCR_CM_MASK (0xF << DMA2D_xGPFCCR_CM_SHIFT)
+#define DMA2D_xGPFCCR_CM(n) ((uint32_t)(n) << DMA2D_xGPFCCR_CM_SHIFT)
+#define DMA2D_xGPFCCR_CCM (1 << 4) /* CLUT Color Mode */
+#define DMA2D_xGPFCCR_START (1 << 5) /* Start */
+#define DMA2D_xGPFCCR_CS_SHIFT (8) /* Bits 8-15 CLUT Size */
+#define DMA2D_xGPFCCR_CS_MASK (0xFF << DMA2D_xGPFCCR_CS_SHIFT)
+#define DMA2D_xGPFCCR_CS(n) ((uint32_t)(n) << DMA2D_xGPFCCR_CS_SHIFT)
+#define DMA2D_xGPFCCR_AM_SHIFT (16) /* Bits 16-17 Alpha Mode */
+#define DMA2D_xGPFCCR_AM_MASK (3 << DMA2D_xGPFCCR_AM_SHIFT)
+#define DMA2D_xGPFCCR_AM(n) ((uint32_t)(n) << DMA2D_xGPFCCR_AM_SHIFT)
+#define DMA2D_xGPFCCR_ALPHA_SHIFT (24) /* Bits 24-31 Alpha Value */
+#define DMA2D_xGPFCCR_ALPHA_MASK (0xFF << DMA2D_xGPFCCR_ALPHA_SHIFT)
+#define DMA2D_xGPFCCR_ALPHA(n) ((uint32_t)(n) << DMA2D_xGPFCCR_ALPHA_SHIFT)
+
+/* DMA2D Foreground/Background Color Register */
+
+#define DMA2D_xGCOLR_BLUE_SHIFT (0) /* Bits 0-7 Blue Value */
+#define DMA2D_xGCOLR_BLUE_MASK (0xFF << DMA2D_xGCOLR_BLUE_SHIFT)
+#define DMA2D_xGCOLR_BLUE(n) ((uint32_t)(n) << DMA2D_xGCOLR_BLUE_SHIFT)
+#define DMA2D_xGCOLR_GREEN_SHIFT (8) /* Bits 8-15 Green Value */
+#define DMA2D_xGCOLR_GREEN_MASK (0xFF << DMA2D_xGCOLR_GREEN_SHIFT)
+#define DMA2D_xGCOLR_GREEN(n) ((uint32_t)(n) << DMA2D_xGCOLR_GREEN_SHIFT)
+#define DMA2D_xGCOLR_RED_SHIFT (16) /* Bits 16-23 Red Value */
+#define DMA2D_xGCOLR_RED_MASK (0xFF << DMA2D_xGCOLR_RED_SHIFT)
+#define DMA2D_xGCOLR_RED(n) ((uint32_t)(n) << DMA2D_xGCOLR_RED_SHIFT)
+
+/* DMA2D Foreground CLUT Memory Address Register */
+
+/* DMA2D Background CLUT Memory Address Register */
+
+/* DMA2D Output PFC Control Register */
+
+#define DMA2D_OPFCCR_CM_SHIFT (0) /* Bits 0-2 Color Mode */
+#define DMA2D_OPFCCR_CM_MASK (7 << DMA2D_OPFCCR_CM_SHIFT)
+#define DMA2D_OPFCCR_CM(n) ((uint32_t)(n) << DMA2D_OPFCCR_CM_SHIFT)
+
+/* DMA2D Output Color Register */
+
+#define DMA2D_OCOLR_BLUE_SHIFT (0) /* Bits 0-7 Blue Value */
+#define DMA2D_OCOLR_BLUE_MASK (0xFF << DMA2D_OCOLR_BLUE_SHIFT)
+#define DMA2D_OCOLR_BLUE(n) ((uint32_t)(n) << DMA2D_OCOLR_BLUE_SHIFT)
+#define DMA2D_OCOLR_GREEN_SHIFT (8) /* Bits 8-15 Green Value */
+#define DMA2D_OCOLR_GREEN_MASK (0xFF << DMA2D_OCOLR_GREEN_SHIFT)
+#define DMA2D_OCOLR_GREEN(n) ((uint32_t)(n) << DMA2D_OCOLR_GREEN_SHIFT)
+#define DMA2D_OCOLR_RED_SHIFT (16) /* Bits 16-23 Red Value */
+#define DMA2D_OCOLR_RED_MASK (0xFF << DMA2D_OCOLR_RED_SHIFT)
+#define DMA2D_OCOLR_RED(n) ((uint32_t)(n) << DMA2D_OCOLR_RED_SHIFT)
+#define DMA2D_OCOLR_ALPHA_SHIFT (24) /* Bits 24-31 Alpha Value */
+#define DMA2D_OCOLR_ALPHA_MASK (0xFF << DMA2D_OCOLR_ALPHA_SHIFT)
+#define DMA2D_OCOLR_ALPHA(n) ((uint32_t)(n) << DMA2D_OCOLR_ALPHA_SHIFT)
+
+/* DMA2D Output Memory Address Register */
+
+/* DMA2D Output Offset Register */
+
+#define DMA2D_OOR_LO_SHIFT (0) /* Bits 0-13 Line Offset */
+#define DMA2D_OOR_LO_MASK (0x3FFF << DMA2D_OOR_LO_SHIFT)
+#define DMA2D_OOR_LO(n) ((uint32_t)(n) << DMA2D_OOR_LO_SHIFT)
+
+/* DMA2D Number Of Line Register */
+
+#define DMA2D_NLR_NL_SHIFT (0) /* Bits 0-15 Number Of Lines */
+#define DMA2D_NLR_NL_MASK (0xFFFF << DMA2D_NLR_NL_SHIFT)
+#define DMA2D_NLR_NL(n) ((uint32_t)(n) << DMA2D_NLR_NL_SHIFT)
+#define DMA2D_NLR_PL_SHIFT (16) /* Bits 16-29 Pixel per Lines */
+#define DMA2D_NLR_PL_MASK (0x3FFF << DMA2D_NLR_PL_SHIFT)
+#define DMA2D_NLR_PL(n) ((uint32_t)(n) << DMA2D_NLR_PL_SHIFT)
+
+/* DMA2D Line Watermark Register */
+
+#define DMA2D_LWR_LW_SHIFT (0) /* Bits 0-15 Line Watermark */
+#define DMA2D_LWR_LW_MASK (0xFFFF << DMA2D_LWR_LW_SHIFT)
+#define DMA2D_LWR_LW(n) ((uint32_t)(n) << DMA2D_LWR_LW_SHIFT)
+
+/* DMA2D AHB Master Timer Configuration Register */
+
+#define DMA2D_AMTCR_EN (1 << 0) /* Enable */
+#define DMA2D_AMTCR_DT_SHIFT (0) /* Bits 8-15 Dead Time */
+#define DMA2D_AMTCR_DT_MASK (0xFF << DMA2D_AMTCR_DT_SHIFT)
+#define DMA2D_AMTCR_DT(n) ((uint32_t)(n) << DMA2D_AMTCR_DT_SHIFT)
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_DMA2D_H */
diff --git a/arch/arm/src/stm32f7/chip/stm32_ltdc.h b/arch/arm/src/stm32f7/chip/stm32_ltdc.h
new file mode 100755
index 00000000000..38068183c5d
--- /dev/null
+++ b/arch/arm/src/stm32f7/chip/stm32_ltdc.h
@@ -0,0 +1,381 @@
+/************************************************************************************
+ * arch/arm/src/stm32/chip/stm32_ltdc.h
+ *
+ * Copyright (C) 2013 Ken Pettit. All rights reserved.
+ * Author: Ken Pettit
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_CHIP_STM32_LTDC_H
+#define __ARCH_ARM_SRC_STM32F7_CHIP_STM32_LTDC_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+#include "chip/stm32_memorymap.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+#define STM32_LTDC_NCLUT 256 /* Number of entries in the CLUTs */
+
+/* LCDC Register Offsets ************************************************************/
+
+#define STM32_LTDC_SSCR_OFFSET 0x0008 /* LTDC Synchronization Size Config Register */
+#define STM32_LTDC_BPCR_OFFSET 0x000c /* LTDC Back Porch Configuration Register */
+#define STM32_LTDC_AWCR_OFFSET 0x0010 /* LTDC Active Width Configuration Register */
+#define STM32_LTDC_TWCR_OFFSET 0x0014 /* LTDC Total Width Configuration Register */
+#define STM32_LTDC_GCR_OFFSET 0x0018 /* LTDC Global Control Register */
+ /* 0x0020 Reserved */
+#define STM32_LTDC_SRCR_OFFSET 0x0024 /* LTDC Shadow Reload Configuration Register */
+ /* 0x0028 Reserved */
+#define STM32_LTDC_BCCR_OFFSET 0x002C /* LTDC Background Color Configuration Register */
+ /* 0x0030 Reserved */
+#define STM32_LTDC_IER_OFFSET 0x0034 /* LTDC Interrupt Enable Register */
+#define STM32_LTDC_ISR_OFFSET 0x0038 /* LTDC Interrupt Status Register */
+#define STM32_LTDC_ICR_OFFSET 0x003C /* LTDC Interrupt Clear Register */
+#define STM32_LTDC_LIPCR_OFFSET 0x0040 /* LTDC Line Interrupt Position Config Register */
+#define STM32_LTDC_CPSR_OFFSET 0x0044 /* LTDC Current Position Status Register */
+#define STM32_LTDC_CDSR_OFFSET 0x0048 /* LTDC Current Display Status Register */
+ /* 0x004c-0x0080 Reserved */
+
+#define STM32_LTDC_L1CR_OFFSET 0x0084 /* LTDC Layer 1 Control Register */
+#define STM32_LTDC_L1WHPCR_OFFSET 0x0088 /* LTDC Layer 1 Window Horiz Pos Config Register */
+#define STM32_LTDC_L1WVPCR_OFFSET 0x008C /* LTDC Layer 1 Window Vert Pos Config Register */
+#define STM32_LTDC_L1CKCR_OFFSET 0x0090 /* LTDC Layer 1 Color Keying Config Register */
+#define STM32_LTDC_L1PFCR_OFFSET 0x0094 /* LTDC Layer 1 Pixel Format Configuration Register */
+#define STM32_LTDC_L1CACR_OFFSET 0x0098 /* LTDC Layer 1 Constant Alpha Config Register */
+#define STM32_LTDC_L1DCCR_OFFSET 0x009C /* LTDC Layer 1 Default Color Config Register */
+#define STM32_LTDC_L1BFCR_OFFSET 0x00A0 /* LTDC Layer 1 Blending Factors Config Register */
+ /* 0x00A4-0x00A8 Reserved */
+#define STM32_LTDC_L1CFBAR_OFFSET 0x00AC /* LTDC Layer 1 Color Frame Buffer Address Register */
+#define STM32_LTDC_L1CFBLR_OFFSET 0x00B0 /* LTDC Layer 1 Color Frame Buffer Length Register */
+#define STM32_LTDC_L1CFBLNR_OFFSET 0x00B4 /* LTDC Layer 1 Color Frame Buffer Line Number Register */
+ /* 0x00B8-0x00C0 Reserved */
+#define STM32_LTDC_L1CLUTWR_OFFSET 0x00C4 /* LTDC Layer 1 CLUT Write Register */
+ /* 0x00C8-0x0100 Reserved */
+#define STM32_LTDC_L2CR_OFFSET 0x0104 /* LTDC Layer 2 Control Register */
+#define STM32_LTDC_L2WHPCR_OFFSET 0x0108 /* LTDC Layer 2 Window Horiz Pos Config Register */
+#define STM32_LTDC_L2WVPCR_OFFSET 0x010C /* LTDC Layer 2 Window Vert Pos Config Register */
+#define STM32_LTDC_L2CKCR_OFFSET 0x0110 /* LTDC Layer 2 Color Keying Config Register */
+#define STM32_LTDC_L2PFCR_OFFSET 0x0114 /* LTDC Layer 2 Pixel Format Configuration Register */
+#define STM32_LTDC_L2CACR_OFFSET 0x0118 /* LTDC Layer 2 Constant Alpha Config Register */
+#define STM32_LTDC_L2DCCR_OFFSET 0x011C /* LTDC Layer 2 Default Color Config Register */
+#define STM32_LTDC_L2BFCR_OFFSET 0x0120 /* LTDC Layer 2 Blending Factors Config Register */
+ /* 0x0124-0x0128 Reserved */
+#define STM32_LTDC_L2CFBAR_OFFSET 0x012C /* LTDC Layer 2 Color Frame Buffer Address Register */
+#define STM32_LTDC_L2CFBLR_OFFSET 0x0130 /* LTDC Layer 2 Color Frame Buffer Length Register */
+#define STM32_LTDC_L2CFBLNR_OFFSET 0x0134 /* LTDC Layer 2 Color Frame Buffer Line Number Register */
+ /* 0x0138-0x0130 Reserved */
+#define STM32_LTDC_L2CLUTWR_OFFSET 0x0144 /* LTDC Layer 2 CLUT Write Register */
+ /* 0x0148-0x03ff Reserved */
+
+/* LTDC Register Addresses *********************************************************/
+
+#define STM32_LTDC_SSCR (STM32_LTDC_BASE+STM32_LTDC_SSCR_OFFSET)
+#define STM32_LTDC_BPCR (STM32_LTDC_BASE+STM32_LTDC_BPCR_OFFSET)
+#define STM32_LTDC_AWCR (STM32_LTDC_BASE+STM32_LTDC_AWCR_OFFSET)
+#define STM32_LTDC_TWCR (STM32_LTDC_BASE+STM32_LTDC_TWCR_OFFSET)
+#define STM32_LTDC_GCR (STM32_LTDC_BASE+STM32_LTDC_GCR_OFFSET)
+#define STM32_LTDC_SRCR (STM32_LTDC_BASE+STM32_LTDC_SRCR_OFFSET)
+#define STM32_LTDC_BCCR (STM32_LTDC_BASE+STM32_LTDC_BCCR_OFFSET)
+#define STM32_LTDC_IER (STM32_LTDC_BASE+STM32_LTDC_IER_OFFSET)
+#define STM32_LTDC_ISR (STM32_LTDC_BASE+STM32_LTDC_ISR_OFFSET)
+#define STM32_LTDC_ICR (STM32_LTDC_BASE+STM32_LTDC_ICR_OFFSET)
+#define STM32_LTDC_LIPCR (STM32_LTDC_BASE+STM32_LTDC_LIPCR_OFFSET)
+#define STM32_LTDC_CPSR (STM32_LTDC_BASE+STM32_LTDC_CPSR_OFFSET)
+#define STM32_LTDC_CDSR (STM32_LTDC_BASE+STM32_LTDC_CDSR_OFFSET)
+
+#define STM32_LTDC_L1CR (STM32_LTDC_BASE+STM32_LTDC_L1CR_OFFSET)
+#define STM32_LTDC_L1WHPCR (STM32_LTDC_BASE+STM32_LTDC_L1WHPCR_OFFSET)
+#define STM32_LTDC_L1WVPCR (STM32_LTDC_BASE+STM32_LTDC_L1WVPCR_OFFSET)
+#define STM32_LTDC_L1CKCR (STM32_LTDC_BASE+STM32_LTDC_L1CKCR_OFFSET)
+#define STM32_LTDC_L1PFCR (STM32_LTDC_BASE+STM32_LTDC_L1PFCR_OFFSET)
+#define STM32_LTDC_L1CACR (STM32_LTDC_BASE+STM32_LTDC_L1CACR_OFFSET)
+#define STM32_LTDC_L1DCCR (STM32_LTDC_BASE+STM32_LTDC_L1DCCR_OFFSET)
+#define STM32_LTDC_L1BFCR (STM32_LTDC_BASE+STM32_LTDC_L1BFCR_OFFSET)
+#define STM32_LTDC_L1CFBAR (STM32_LTDC_BASE+STM32_LTDC_L1CFBAR_OFFSET)
+#define STM32_LTDC_L1CFBLR (STM32_LTDC_BASE+STM32_LTDC_L1CFBLR_OFFSET)
+#define STM32_LTDC_L1CFBLNR (STM32_LTDC_BASE+STM32_LTDC_L1CFBLNR_OFFSET)
+#define STM32_LTDC_L1CLUTWR (STM32_LTDC_BASE+STM32_LTDC_L1CLUTWR_OFFSET)
+
+#define STM32_LTDC_L2CR (STM32_LTDC_BASE+STM32_LTDC_L2CR_OFFSET)
+#define STM32_LTDC_L2WHPCR (STM32_LTDC_BASE+STM32_LTDC_L2WHPCR_OFFSET)
+#define STM32_LTDC_L2WVPCR (STM32_LTDC_BASE+STM32_LTDC_L2WVPCR_OFFSET)
+#define STM32_LTDC_L2CKCR (STM32_LTDC_BASE+STM32_LTDC_L2CKCR_OFFSET)
+#define STM32_LTDC_L2PFCR (STM32_LTDC_BASE+STM32_LTDC_L2PFCR_OFFSET)
+#define STM32_LTDC_L2CACR (STM32_LTDC_BASE+STM32_LTDC_L2CACR_OFFSET)
+#define STM32_LTDC_L2DCCR (STM32_LTDC_BASE+STM32_LTDC_L2DCCR_OFFSET)
+#define STM32_LTDC_L2BFCR (STM32_LTDC_BASE+STM32_LTDC_L2BFCR_OFFSET)
+#define STM32_LTDC_L2CFBAR (STM32_LTDC_BASE+STM32_LTDC_L2CFBAR_OFFSET)
+#define STM32_LTDC_L2CFBLR (STM32_LTDC_BASE+STM32_LTDC_L2CFBLR_OFFSET)
+#define STM32_LTDC_L2CFBLNR (STM32_LTDC_BASE+STM32_LTDC_L2CFBLNR_OFFSET)
+#define STM32_LTDC_L2CLUTWR (STM32_LTDC_BASE+STM32_LTDC_L2CLUTWR_OFFSET)
+
+/* LTDC Register Bit Definitions ***************************************************/
+
+/* LTDC Synchronization Size Configuration Register */
+
+#define LTDC_SSCR_VSH_SHIFT (0) /* Bits 0-10: Vertical Sync Height (scan lines) */
+#define LTDC_SSCR_VSH_MASK (0x7ff << LTDC_SSCR_VSH_SHIFT)
+# define LTDC_SSCR_VSH(n) ((uint32_t)(n) << LTDC_SSCR_VSH_SHIFT)
+#define LTDC_SSCR_HSW_SHIFT (16) /* Bits 16-27: Horizontal Sync Width (pixel clocks) */
+#define LTDC_SSCR_HSW_MASK (0xfff << LTDC_SSCR_HSW_SHIFT)
+# define LTDC_SSCR_HSW(n) ((uint32_t)(n) << LTDC_SSCR_HSW_SHIFT)
+
+/* LTDC Back Porch Configuration Register */
+
+#define LTDC_BPCR_AVBP_SHIFT (0) /* Bits 0-10: Accumulated Vertical back porch (scan lines) */
+#define LTDC_BPCR_AVBP_MASK (0x7ff << LTDC_BPCR_AVBP_SHIFT)
+# define LTDC_BPCR_AVBP(n) ((uint32_t)(n) << LTDC_BPCR_AVBP_SHIFT)
+#define LTDC_BPCR_AHBP_SHIFT (16) /* Bits 16-27: Accumulated Horizontal back porch (pixel clocks) */
+#define LTDC_BPCR_AHBP_MASK (0xfff << LTDC_BPCR_AVBP_SHIFT)
+# define LTDC_BPCR_AHBP(n) ((uint32_t)(n) << LTDC_BPCR_AHBP_SHIFT)
+
+/* LTDC Active Width Configuration Register */
+
+#define LTDC_AWCR_AAH_SHIFT (0) /* Bits 0-10: Accumulated Active Height (scan lines) */
+#define LTDC_AWCR_AAH_MASK (0x7ff << LTDC_AWCR_AAH_SHIFT)
+# define LTDC_AWCR_AAH(n) ((uint32_t)(n) << LTDC_AWCR_AAH_SHIFT)
+#define LTDC_AWCR_AAW_SHIFT (16) /* Bits 16-27: Accumulated Active Width (pixel clocks) */
+#define LTDC_AWCR_AAW_MASK (0xfff << LTDC_AWCR_AAW_SHIFT)
+# define LTDC_AWCR_AAW(n) ((uint32_t)(n) << LTDC_AWCR_AAW_SHIFT)
+
+/* LTDC Total Width Configuration Register */
+
+#define LTDC_TWCR_TOTALH_SHIFT (0) /* Bits 0-10: Total Height (scan lines) */
+#define LTDC_TWCR_TOTALH_MASK (0x7ff << LTDC_TWCR_TOTALH_SHIFT)
+# define LTDC_TWCR_TOTALH(n) ((uint32_t)(n) << LTDC_TWCR_TOTALH_SHIFT)
+#define LTDC_TWCR_TOTALW_SHIFT (16) /* Bits 16-27: Total Width (pixel clocks) */
+#define LTDC_TWCR_TOTALW_MASK (0xfff << LTDC_TWCR_TOTALW_SHIFT)
+# define LTDC_TWCR_TOTALW(n) ((uint32_t)(n) << LTDC_TWCR_TOTALW_SHIFT)
+
+/* LTDC Global Control Register */
+
+#define LTDC_GCR_LTDCEN (1 << 0) /* Bit 0: LCD-TFT Controller Enable Bit */
+#define LTDC_GCR_DBW_SHIFT (4) /* Bits 4-6: Dither Blue Width */
+#define LTDC_GCR_DBW_MASK (0x7 << LTDC_GCR_DBW_SHIFT)
+# define LTDC_GCR_DBW(n) ((uint32_t)(n) << LTDC_GCR_DBW_SHIFT)
+#define LTDC_GCR_DGW_SHIFT (8) /* Bits 8-10: Dither Green Width */
+#define LTDC_GCR_DGW_MASK (0x7 << LTDC_GCR_DGW_SHIFT)
+# define LTDC_GCR_DGW(n) ((uint32_t)(n) << LTDC_GCR_DGW_SHIFT)
+#define LTDC_GCR_DRW_SHIFT (12) /* Bits 12-14: Dither Red Width */
+#define LTDC_GCR_DRW_MASK (0x7 << LTDC_GCR_DRW_SHIFT)
+# define LTDC_GCR_DRW(n) ((uint32_t)(n) << LTDC_GCR_DRW_SHIFT)
+#define LTDC_GCR_DEN (1 << 16) /* Bit 16: Dither Enable */
+#define LTDC_GCR_PCPOL (1 << 28) /* Bit 28: Pixel Clock Polarity */
+#define LTDC_GCR_DEPOL (1 << 29) /* Bit 29: Data Enable Polarity */
+#define LTDC_GCR_VSPOL (1 << 30) /* Bit 30: Vertical Sync Polarity */
+#define LTDC_GCR_HSPOL (1 << 31) /* Bit 31: Horizontal Sync Polarity */
+
+/* LTDC Shadow Reload Configuration Register */
+
+#define LTDC_SRCR_IMR (1 << 0) /* Bit 0: Immediate Reload */
+#define LTDC_SRCR_VBR (1 << 1) /* Bit 1: Vertical Blanking Reload */
+
+/* LTDC Background Color Configuration Register */
+
+#define LTDC_BCCR_BCBLUE_SHIFT (0) /* Bits 0-7: Background Color Blue Value */
+#define LTDC_BCCR_BCBLUE_MASK (0xFF << LTDC_BCCR_BCBLUE_SHIFT)
+# define LTDC_BCCR_BCBLUE(n) ((uint32_t)(n) << LTDC_BCCR_BCBLUE_SHIFT)
+#define LTDC_BCCR_BCGREEN_SHIFT (8) /* Bits 8-15: Background Color Green Value */
+#define LTDC_BCCR_BCGREEN_MASK (0xFF << LTDC_BCCR_BCGREEN_SHIFT)
+# define LTDC_BCCR_BCGREEN(n) ((uint32_t)(n) << LTDC_BCCR_BCGREEN_SHIFT)
+#define LTDC_BCCR_BCRED_SHIFT (16) /* Bits 16-23: Background Color Red Value */
+#define LTDC_BCCR_BCRED_MASK (0xFF << LTDC_BCCR_BCRED_SHIFT)
+# define LTDC_BCCR_BCRED(n) ((uint32_t)(n) << LTDC_BCCR_BCRED_SHIFT)
+
+/* LTDC Interrupt Enable Register */
+
+#define LTDC_IER_LIE (1 << 0) /* Bit 0: Line Interrupt Enable */
+#define LTDC_IER_FUIE (1 << 1) /* Bit 1: FIFO Underrun Interrupt Enable */
+#define LTDC_IER_TERRIE (1 << 2) /* Bit 2: Transfer Error Interrupt Enable */
+#define LTDC_IER_RRIE (1 << 3) /* Bit 3: Register Reload Interrupt Enable */
+
+/* LTDC Interrupt Status Register */
+
+#define LTDC_ISR_LIF (1 << 0) /* Bit 0: Line Interrupt Flag */
+#define LTDC_ISR_FUIF (1 << 1) /* Bit 1: FIFO Underrun Interrupt Flag */
+#define LTDC_IER_TERRIF (1 << 2) /* Bit 2: Transfer Error Interrupt Flag */
+#define LTDC_ISR_RRIF (1 << 3) /* Bit 3: Register Reload Interrupt Flag */
+
+/* LTDC Interrupt Clear Register */
+
+#define LTDC_ICR_CLIF (1 << 0) /* Bit 0: Clear Line Interrupt Flag */
+#define LTDC_ICR_CFUIF (1 << 1) /* Bit 1: Clear FIFO Underrun Interrupt Flag */
+#define LTDC_ICR_CTERRIF (1 << 2) /* Bit 2: Clear Transfer Error Interrupt Flag */
+#define LTDC_ICR_CRRIF (1 << 3) /* Bit 3: Clear Register Reload Interrupt Flag */
+
+/* LTDC Line Interrupt Posittion Configuration Register */
+
+#define LTDC_LIPCR_LIPOS_SHIFT (0) /* Bits 0-10: Line Interrupt Position */
+#define LTDC_LIPCR_LIPOS_MASK (0x7FF << LTDC_LIPCR_LIPOS_SHIFT)
+# define LTDC_LIPCR_LIPOS(n) ((uint32_t)(n) << LTDC_LIPCR_LIPOS_SHIFT)
+
+/* LTDC Current Position Status Register */
+
+#define LTDC_CPSR_CYPOS_SHIFT (0) /* Bits 0-15: Current Y Position */
+#define LTDC_CPSR_CYPOS_MASK (0xFFFF << LTDC_CPSR_CYPOS_SHIFT)
+# define LTDC_CPSR_CYPOS(n) ((uint32_t)(n) << LTDC_CPSR_CYPOS_SHIFT)
+#define LTDC_CPSR_CXPOS_SHIFT (16) /* Bits 15-31: Current X Position */
+#define LTDC_CPSR_CXPOS_MASK (0xFFFF << LTDC_CPSR_CXPOS_SHIFT)
+# define LTDC_CPSR_CXPOS(n) ((uint32_t)(n) << LTDC_CPSR_CXPOS_SHIFT)
+
+/* LTDC Current Display Status Register */
+
+#define LTDC_CDSR_VDES (1 << 0) /* Bit 0: Vertical Data Enable display Status */
+#define LTDC_CDSR_HDES (1 << 1) /* Bit 1: Horizontal Data Enable display Status */
+#define LTDC_CDSR_VSYNCS (1 << 2) /* Bit 2: Vertical Sync display Status */
+#define LTDC_CDSR_HSYNCS (1 << 3) /* Bit 3: Horizontal Sync display Status */
+
+/* LTDC Layer x Control Register */
+
+#define LTDC_LxCR_LEN (1 << 0) /* Bit 0: Layer Enable */
+#define LTDC_LxCR_COLKEN (1 << 1) /* Bit 1: Color Keying Enable */
+#define LTDC_LxCR_CLUTEN (1 << 4) /* Bit 4: Color Look-Up Table Enable */
+
+/* LTDC Layer x Window Horizontal Position Configuration Register */
+
+#define LTDC_LxWHPCR_WHSTPOS_SHIFT (0) /* Bits 0-11: Window Horizontal Start Position */
+#define LTDC_LxWHPCR_WHSTPOS_MASK (0xFFF << LTDC_LxWHPCR_WHSTPOS_SHIFT)
+# define LTDC_LxWHPCR_WHSTPOS(n) ((uint32_t)(n) << LTDC_LxWHPCR_WHSTPOS_SHIFT)
+#define LTDC_LxWHPCR_WHSPPOS_SHIFT (16) /* Bits 16-27: Window Horizontal Stop Position */
+#define LTDC_LxWHPCR_WHSPPOS_MASK (0xFFF << LTDC_LxWHPCR_WHSPPOS_SHIFT)
+# define LTDC_LxWHPCR_WHSPPOS(n) ((uint32_t)(n) << LTDC_LxWHPCR_WHSPPOS_SHIFT)
+
+/* LTDC Layer x Window Vertical Position Configuration Register */
+
+#define LTDC_LxWVPCR_WVSTPOS_SHIFT (0) /* Bits 0-10: Window Vertical Start Position */
+#define LTDC_LxWVPCR_WVSTPOS_MASK (0x7FF << LTDC_LxWVPCR_WVSTPOS_SHIFT)
+# define LTDC_LxWVPCR_WVSTPOS(n) ((uint32_t)(n) << LTDC_LxWVPCR_WVSTPOS_SHIFT)
+#define LTDC_LxWVPCR_WVSPPOS_SHIFT (16) /* Bits 16-26: Window Vertical Stop Position */
+#define LTDC_LxWVPCR_WVSPPOS_MASK (0x7FF << LTDC_LxWVPCR_WVSPPOS_SHIFT)
+# define LTDC_LxWVPCR_WVSPPOS(n) ((uint32_t)(n) << LTDC_LxWVPCR_WVSPPOS_SHIFT)
+
+/* LTDC Layer x Color Keying Configuration Register */
+
+#define LTDC_LxCKCR_CKBLUE_SHIFT (0) /* Bits 0-7: Color Key Blue Value */
+#define LTDC_LxCKCR_CKBLUE_MASK (0xFF << LTDC_LxCKCR_CKBLUE_SHIFT)
+# define LTDC_LxCKCR_CKBLUE(n) ((uint32_t)(n) << LTDC_LxCKCR_CKBLUE_SHIFT)
+#define LTDC_LxCKCR_CKGREEN_SHIFT (8) /* Bits 8-15: Color Key Green Value */
+#define LTDC_LxCKCR_CKGREEN_MASK (0xFF << LTDC_LxCKCR_CKGREEN_SHIFT)
+# define LTDC_LxCKCR_CKGREEN(n) ((uint32_t)(n) << LTDC_LxCKCR_CKGREEN_SHIFT)
+#define LTDC_LxCKCR_CKRED_SHIFT (16) /* Bits 16-23: Color Key Red Value */
+#define LTDC_LxCKCR_CKRED_MASK (0xFF << LTDC_LxCKCR_CKRED_SHIFT)
+# define LTDC_LxCKCR_CKRED(n) ((uint32_t)(n) << LTDC_LxCKCR_CKRED_SHIFT)
+
+/* LTDC Layer x Pixel Format Configuration Register */
+
+#define LTDC_LxPFCR_PF_SHIFT (0) /* Bits 0-2: Pixel Format */
+#define LTDC_LxPFCR_PF_MASK (0x7 << LTDC_LxPFCR_PF_SHIFT)
+# define LTDC_LxPFCR_PF(n) ((uint32_t)(n) << LTDC_LxPFCR_PF_SHIFT)
+
+#define LTDC_PF_ARGB8888 0
+#define LTDC_PF_RGB888 1
+#define LTDC_PF_RGB565 2
+#define LTDC_PF_ARGB1555 3
+#define LTDC_PF_ARGB4444 4
+#define LTDC_PF_L8 5 /* 8-bit Luninance (CLUT lookup) */
+#define LTDC_PF_AL44 6 /* 4-bit Alpha, 4-bit Luminance */
+#define LTDC_PF_AL88 7 /* 8-bit Alpha, 8-bit Luminance */
+
+/* LTDC Layer x Constant Alpha Configuration Register */
+
+#define LTDC_LxCACR_CONSTA_SHIFT (0) /* Bits 0-7: Constant Alpha */
+#define LTDC_LxCACR_CONSTA_MASK (0x7 << LTDC_LxCACR_CONSTA_SHIFT)
+# define LTDC_LxCACR_CONSTA(n) ((uint32_t)(n) << LTDC_LxCACR_CONSTA_SHIFT)
+
+/* LTDC Layer x Default Color Configuration Register */
+
+#define LTDC_LxDCCR_DCBLUE_SHIFT (0) /* Bits 0-7: Default Color Blue Value */
+#define LTDC_LxDCCR_DCBLUE_MASK (0xFF << LTDC_LxDCCR_DCBLUE_SHIFT)
+# define LTDC_LxDCCR_DCBLUE(n) ((uint32_t)(n) << LTDC_LxDCCR_DCBLUE_SHIFT)
+#define LTDC_LxDCCR_DCGREEN_SHIFT (8) /* Bits 8-15: Default Color Green Value */
+#define LTDC_LxDCCR_DCGREEN_MASK (0xFF << LTDC_LxDCCR_DCGREEN_SHIFT)
+# define LTDC_LxDCCR_DCGREEN(n) ((uint32_t)(n) << LTDC_LxDCCR_DCGREEN_SHIFT)
+#define LTDC_LxDCCR_DCRED_SHIFT (16) /* Bits 16-23: Default Color Red Value */
+#define LTDC_LxDCCR_DCRED_MASK (0xFF << LTDC_LxDCCR_DCRED_SHIFT)
+# define LTDC_LxDCCR_DCRED(n) ((uint32_t)(n) << LTDC_LxDCCR_DCRED_SHIFT)
+#define LTDC_LxDCCR_DCALPHA_SHIFT (24) /* Bits 24-31: Default Color Alpha Value */
+#define LTDC_LxDCCR_DCALPHA_MASK (0xFF << LTDC_LxDCCR_DCALPHA_SHIFT)
+# define LTDC_LxDCCR_DCALPHA(n) ((uint32_t)(n) << LTDC_LxDCCR_DCALPHA_SHIFT)
+
+/* LTDC Layer x Blending Factors Configuration Register */
+
+#define LTDC_LxBFCR_BF2_SHIFT (0) /* Bits 0-2: Blending Factor 2 */
+#define LTDC_LxBFCR_BF2_MASK (0x7 << LTDC_LxBFCR_BF2_SHIFT)
+# define LTDC_LxBFCR_BF2(n) ((uint32_t)(n) << LTDC_LxBFCR_BF2_SHIFT)
+#define LTDC_LxBFCR_BF1_SHIFT (8) /* Bits 8-10: Blending Factor 1 */
+#define LTDC_LxBFCR_BF1_MASK (0x7 << LTDC_LxBFCR_BF1_SHIFT)
+# define LTDC_LxBFCR_BF1(n) ((uint32_t)(n) << LTDC_LxBFCR_BF1_SHIFT)
+
+#define LTDC_BF1_CONST_ALPHA 0x04 /* Constant Alpha */
+#define LTDC_BF1_PIXEL_ALPHA 0x06 /* Pixel Alpha x Constant Alpha */
+#define LTDC_BF2_CONST_ALPHA 0x05 /* Constant Alpha */
+#define LTDC_BF2_PIXEL_ALPHA 0x07 /* Pixel Alpha x Constant Alpha */
+
+/* LTDC Layer x Color Frame Buffer Length Configuration Register */
+
+#define LTDC_LxCFBLR_CFBLL_SHIFT (0) /* Bits 0-12: Color Frame Buffer Line Length */
+#define LTDC_LxCFBLR_CFBLL_MASK (0x1FFF << LTDC_LxCFBLR_CFBLL_SHIFT)
+# define LTDC_LxCFBLR_CFBLL(n) ((uint32_t)(n) << LTDC_LxCFBLR_CFBLL_SHIFT)
+#define LTDC_LxCFBLR_CFBP_SHIFT (16) /* Bits 16-28: Color Frame Buffer Pitch */
+#define LTDC_LxCFBLR_CFBP_MASK (0x1FFF << LTDC_LxCFBLR_CFBP_SHIFT)
+# define LTDC_LxCFBLR_CFBP(n) ((uint32_t)(n) << LTDC_LxCFBLR_CFBP_SHIFT)
+
+/* LTDC Layer x Color Frame Buffer Line Number Register */
+
+#define LTDC_LxCFBLNR_LN_SHIFT (0) /* Bits 0-10: Color Frame Buffer Line Number */
+#define LTDC_LxCFBLNR_LN_MASK (0x7FF << LTDC_LxCFBLNR_LN_SHIFT)
+# define LTDC_LxCFBLNR_LN(n) ((uint32_t)(n) << LTDC_LxCFBLNR_LN_SHIFT)
+
+/* LTDC Layer x CLUT Write Register */
+
+#define LTDC_LxCLUTWR_BLUE_SHIFT (0) /* Bits 0-7: Default Color Blue Value */
+#define LTDC_LxCLUTWR_BLUE_MASK (0xFF << LTDC_LxCLUTWR_BLUE_SHIFT)
+# define LTDC_LxCLUTWR_BLUE(n) ((uint32_t)(n) << LTDC_LxCLUTWR_BLUE_SHIFT)
+#define LTDC_LxCLUTWR_GREEN_SHIFT (8) /* Bits 8-15: Default Color Green Value */
+#define LTDC_LxCLUTWR_GREEN_MASK (0xFF << LTDC_LxCLUTWR_GREEN_SHIFT)
+# define LTDC_LxCLUTWR_GREEN(n) ((uint32_t)(n) << LTDC_LxCLUTWR_GREEN_SHIFT)
+#define LTDC_LxCLUTWR_RED_SHIFT (16) /* Bits 16-23: Default Color Red Value */
+#define LTDC_LxCLUTWR_RED_MASK (0xFF << LTDC_LxCLUTWR_RED_SHIFT)
+# define LTDC_LxCLUTWR_RED(n) ((uint32_t)(n) << LTDC_LxCLUTWR_RED_SHIFT)
+#define LTDC_LxCLUTWR_CLUTADD_SHIFT (24) /* Bits 24-31: CLUT Address */
+#define LTDC_LxCLUTWR_CLUTADD_MASK (0xFF << LTDC_LxCLUTWR_CLUTADD_SHIFT)
+# define LTDC_LxCLUTWR_CLUTADD(n) ((uint32_t)(n) << LTDC_LxCLUTWR_CLUTADD_SHIFT)
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+#endif /* __ARCH_ARM_SRC_STM32F7_CHIP_STM32_LTDC_H */
diff --git a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h
old mode 100644
new mode 100755
index 41675c60b37..7c7d25241bc
--- a/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h
+++ b/arch/arm/src/stm32f7/chip/stm32f74xx75xx_memorymap.h
@@ -160,7 +160,7 @@
#define STM32_SPI6_BASE 0x40015400 /* 0x40015400-0x400157ff: SPI6 */
#define STM32_SAI1_BASE 0x40015800 /* 0x40015800-0x40015bff: SAI1 */
#define STM32_SAI2_BASE 0x40015c00 /* 0x40015c00-0x40015fff: SAI2 */
-#define STM32_LCDTFT_BASE 0x40016800 /* 0x40016800-0x40016bff: LCD-TFT */
+#define STM32_LTDC_BASE 0x40016800 /* 0x40016800-0x40016bff: LCD-TFT */
/* AHB1 Base Addresses **************************************************************/
diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_memorymap.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_memorymap.h
old mode 100644
new mode 100755
index db2ca6d3a95..7af9b5243de
--- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_memorymap.h
+++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_memorymap.h
@@ -162,7 +162,7 @@
#define STM32_SPI6_BASE 0x40015400 /* 0x40015400-0x400157ff: SPI6 */
#define STM32_SAI1_BASE 0x40015800 /* 0x40015800-0x40015bff: SAI1 */
#define STM32_SAI2_BASE 0x40015c00 /* 0x40015c00-0x40015fff: SAI2 */
-#define STM32_LCDTFT_BASE 0x40016800 /* 0x40016800-0x40016bff: LCD-TFT */
+#define STM32_LTDC_BASE 0x40016800 /* 0x40016800-0x40016bff: LCD-TFT */
#define STM32_DSIHOST_BASE 0x40016c00 /* 0x40016c00-0x400173ff: DSI Host */
#define STM32_DFSDM1_BASE 0x40017400 /* 0x40017400-0x400174ff: DFSDM1 */
#define STM32_MDIOS_BASE 0x40017800 /* 0x40017800-0x40017bff: MDIOS */
diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h
index e951a8f9041..92c8553ea64 100644
--- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h
+++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_pinmap.h
@@ -631,6 +631,7 @@
#define GPIO_I2C4_SDA_2 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTF|GPIO_PIN15)
#define GPIO_I2C4_SDA_3 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTH|GPIO_PIN12)
#define GPIO_I2C4_SDA_4 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN9)
+#define GPIO_I2C4_SDA_5 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_OPENDRAIN|GPIO_PORTB|GPIO_PIN7)
#define GPIO_I2C4_SMBA_1 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTD|GPIO_PIN11)
#define GPIO_I2C4_SMBA_2 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTF|GPIO_PIN13)
#define GPIO_I2C4_SMBA_3 (GPIO_ALT|GPIO_AF4 |GPIO_SPEED_50MHz|GPIO_PUSHPULL|GPIO_PORTH|GPIO_PIN10)
diff --git a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h
index 6c8a7840681..1b9c041319b 100644
--- a/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h
+++ b/arch/arm/src/stm32f7/chip/stm32f76xx77xx_rcc.h
@@ -729,9 +729,9 @@
# define RCC_DCKCFGR2_SDMMC2SEL_48MHZ (0 << RCC_DCKCFGR2_SDMMC2SEL_SHIFT) /* 48 MHz clock is selected as SDMMC 2 clock */
# define RCC_DCKCFGR2_SDMMC2SEL_SYSCLK (1 << RCC_DCKCFGR2_SDMMC2SEL_SHIFT) /* System clock is selected as SDMMC 2 clock */
#define RCC_DCKCFGR2_DSISEL_SHIFT (30) /* Bit 30: DSI clock source selection */
-#define RCC_DCKCFGR2_DSISELL_MASK (1 << RCC_DCKCFGR2_DSISEL_SHIFT)
-# define RCC_DCKCFGR2_DSISEL_48MHZ (0 << RCC_DCKCFGR2_DSISEL_SHIFT) /* 48 MHz clock is selected as DSI clock */
-# define RCC_DCKCFGR2_DSISEL_SYSCLK (1 << RCC_DCKCFGR2_DSISEL_SHIFT) /* System clock is selected as DSI clock */
+#define RCC_DCKCFGR2_DSISEL_MASK (1 << RCC_DCKCFGR2_DSISEL_SHIFT)
+# define RCC_DCKCFGR2_DSISEL_PHY (0 << RCC_DCKCFGR2_DSISEL_SHIFT) /* DSI PHY sources DSI clock */
+# define RCC_DCKCFGR2_DSISEL_SYSCLK (1 << RCC_DCKCFGR2_DSISEL_SHIFT) /* System clock is selected as DSI clock */
#endif /* CONFIG_STM32F7_STM32F76XX || CONFIG_STM32F7_STM32F77XX */
#endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32F76XX77XX_RCC_H */
diff --git a/arch/arm/src/stm32f7/stm32_dma2d.c b/arch/arm/src/stm32f7/stm32_dma2d.c
new file mode 100644
index 00000000000..0e8d4edd751
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_dma2d.c
@@ -0,0 +1,2302 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_dma2d.c
+ *
+ * Copyright (C) 2014-2015 Marco Krahl. All rights reserved.
+ * Author: Marco Krahl
+ *
+ * References:
+ * STM32F429 Technical Reference Manual
+ *
+ * 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
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "chip/stm32_ltdc.h"
+#include "chip/stm32_dma2d.h"
+#include "chip/stm32_dtcm.h"
+#include "stm32_dma2d.h"
+#include "stm32_ltdc.h"
+#include "stm32_gpio.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* output, foreground and background layer */
+
+#define DMA2D_NLAYERS 3
+
+/* DMA2D PFC value definitions */
+
+#define DMA2D_PF_ARGB8888 0
+#define DMA2D_PF_RGB888 1
+#define DMA2D_PF_RGB565 2
+#define DMA2D_PF_ARGB1555 3
+#define DMA2D_PF_ARGB14444 4
+#define DMA2D_PF_L8 5
+#define DMA2D_PF_AL44 6
+#define DMA2D_PF_AL88 7
+#define DMA2D_PF_L4 8
+#define DMA2D_PF_A8 9
+#define DMA2D_PF_A4 10
+
+/* DMA2D blender control */
+
+#define STM32_DMA2D_CR_MODE_BLIT DMA2D_CR_MODE(0)
+#define STM32_DMA2D_CR_MODE_BLITPFC DMA2D_CR_MODE(1)
+#define STM32_DMA2D_CR_MODE_BLEND DMA2D_CR_MODE(2)
+#define STM32_DMA2D_CR_MODE_COLOR DMA2D_CR_MODE(3)
+#define STM32_DMA2D_CR_MODE_CLEAR STM32_DMA2D_CR_MODE_COLOR
+
+/* DMA2D PFC alpha mode */
+
+#define STM32_DMA2D_PFCCR_AM_NONE 0
+#define STM32_DMA2D_PFCCR_AM_CONST 1
+#define STM32_DMA2D_PFCCR_AM_PIXEL 10
+
+/* Only 8 bit per pixel overal supported */
+
+#define DMA2D_PF_BYPP(n) ((n) / 8)
+
+#define DMA2D_CLUT_SIZE STM32_LTDC_NCLUT - 1
+
+/* Layer argb cmap conversion */
+
+#define DMA2D_CLUT_ALPHA(n) ((uint32_t)(n) << 24)
+#define DMA2D_CLUT_RED(n) ((uint32_t)(n) << 16)
+#define DMA2D_CLUT_GREEN(n) ((uint32_t)(n) << 8)
+#define DMA2D_CLUT_BLUE(n) ((uint32_t)(n) << 0)
+
+#define DMA2D_CMAP_ALPHA(n) ((uint32_t)(n) >> 24)
+#define DMA2D_CMAP_RED(n) ((uint32_t)(n) >> 16)
+#define DMA2D_CMAP_GREEN(n) ((uint32_t)(n) >> 8)
+#define DMA2D_CMAP_BLUE(n) ((uint32_t)(n) >> 0)
+
+/* Define shadow layer for ltdc interface */
+
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+# ifdef CONFIG_STM32F7_LTDC_L2
+# define DMA2D_SHADOW_LAYER 2
+# define DMA2D_SHADOW_LAYER_L1 0
+# define DMA2D_SHADOW_LAYER_L2 1
+# else
+# define DMA2D_SHADOW_LAYER 1
+# define DMA2D_SHADOW_LAYER_L1 0
+# endif
+# define DMA2D_LAYER_NSIZE CONFIG_STM32F7_DMA2D_NLAYERS + DMA2D_SHADOW_LAYER
+#else
+# define DMA2D_LAYER_NSIZE CONFIG_STM32F7_DMA2D_NLAYERS
+# define DMA2D_SHADOW_LAYER 0
+#endif
+
+/* Debug option */
+
+#ifdef CONFIG_STM32F7_DMA2D_REGDEBUG
+# define regerr lcderr
+# define reginfo lcdinfo
+#else
+# define regerr(x...)
+# define reginfo(x...)
+#endif
+
+/* check clut support */
+
+#ifdef CONFIG_STM32F7_DMA2D_L8
+# ifndef CONFIG_FB_CMAP
+# error "Enable cmap to support the configured layer formats!"
+# endif
+#endif
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* DMA2D General layer information */
+
+struct stm32_dma2d_s
+{
+ struct dma2d_layer_s dma2d; /* public dma2d interface */
+
+ /* Fixed settings */
+
+ int lid; /* Layer identifier */
+ struct fb_videoinfo_s vinfo; /* Layer videoinfo */
+ struct fb_planeinfo_s pinfo; /* Layer planeinfo */
+
+ /* Blending */
+
+ uint32_t blendmode; /* the interface blendmode */
+ uint8_t alpha; /* the alpha value */
+
+ /* Coloring */
+
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ uint32_t *clut; /* Color lookup table */
+#endif
+
+ /* Operation */
+ uint8_t fmt; /* the controller pixel format */
+ sem_t *lock; /* Ensure mutually exclusive access */
+};
+
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+
+/* This structures provides the DMA2D layer for each LTDC layer */
+
+struct stm32_ltdc_dma2d_s
+{
+ struct stm32_dma2d_s dma2ddev;
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ FAR struct ltdc_layer_s *ltdc;
+#endif
+};
+
+struct stm32_ltdc_layer_s
+{
+ /* Layer state */
+
+ struct stm32_ltdc_dma2d_s layer[DMA2D_SHADOW_LAYER];
+};
+#endif
+
+/* Interrupt handling */
+
+struct stm32_interrupt_s
+{
+ bool wait; /* Informs that the task is waiting for the irq */
+ bool handled; /* Informs that an irq was handled */
+ int irq; /* irq number */
+ sem_t *sem; /* Semaphore for waiting for irq */
+};
+
+/* This enumeration foreground and background layer supported by the dma2d
+ * controller
+ */
+
+enum stm32_layer_e
+{
+ DMA2D_LAYER_LFORE = 0, /* Foreground Layer */
+ DMA2D_LAYER_LBACK, /* Background Layer */
+ DMA2D_LAYER_LOUT, /* Output Layer */
+};
+
+/* DMA2D memory address register */
+
+static const uintptr_t stm32_mar_layer_t[DMA2D_NLAYERS] =
+{
+ STM32_DMA2D_FGMAR,
+ STM32_DMA2D_BGMAR,
+ STM32_DMA2D_OMAR
+};
+
+/* DMA2D offset register */
+
+static const uintptr_t stm32_or_layer_t[DMA2D_NLAYERS] =
+{
+ STM32_DMA2D_FGOR,
+ STM32_DMA2D_BGOR,
+ STM32_DMA2D_OOR
+};
+
+/* DMA2D pfc control register */
+
+static const uintptr_t stm32_pfccr_layer_t[DMA2D_NLAYERS] =
+{
+ STM32_DMA2D_FGPFCCR,
+ STM32_DMA2D_BGPFCCR,
+ STM32_DMA2D_OPFCCR
+};
+
+/* DMA2D color register */
+
+static const uintptr_t stm32_color_layer_t[DMA2D_NLAYERS] =
+{
+ STM32_DMA2D_FGCOLR,
+ STM32_DMA2D_BGCOLR,
+ STM32_DMA2D_OCOLR
+};
+
+/* DMA2D clut memory address register */
+#if defined(CONFIG_STM32F7_DMA2D_L8)
+static const uintptr_t stm32_cmar_layer_t[DMA2D_NLAYERS - 1] =
+{
+ STM32_DMA2D_FGCMAR,
+ STM32_DMA2D_BGCMAR
+};
+#endif
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Private functions */
+
+static int stm32_dma2d_pixelformat(uint8_t fmt, uint8_t *fmtmap);
+static int stm32_dma2d_bpp(uint8_t fmt, uint8_t *bpp);
+static void stm32_dma2d_control(uint32_t setbits, uint32_t clrbits);
+static int stm32_dma2dirq(int irq, void *context, FAR void *arg);
+static int stm32_dma2d_waitforirq(void);
+static int stm32_dma2d_start(void);
+#ifdef CONFIG_STM32F7_DMA2D_L8
+static int stm32_dma2d_loadclut(uintptr_t reg);
+#endif
+static uint32_t stm32_dma2d_memaddress(FAR const struct stm32_dma2d_s *layer,
+ fb_coord_t xpos, fb_coord_t ypos);
+static fb_coord_t stm32_dma2d_lineoffset(FAR const struct stm32_dma2d_s *layer,
+ FAR const struct ltdc_area_s *area);
+
+static int stm32_dma2d_lfreelid(void);
+static FAR struct stm32_dma2d_s * stm32_dma2d_lalloc(void);
+static void stm32_dma2d_lfree(FAR struct stm32_dma2d_s *layer);
+static void stm32_dma2d_llayerscleanup(void);
+static bool stm32_dma2d_lvalidate(FAR const struct stm32_dma2d_s *layer);
+static bool stm32_dma2d_lvalidatesize(FAR const struct stm32_dma2d_s *layer,
+ fb_coord_t xpos, fb_coord_t ypos,
+ FAR const struct ltdc_area_s *area);
+static void stm32_dma2d_linit(FAR struct stm32_dma2d_s *layer,
+ int lid, uint8_t fmt);
+
+static void stm32_dma2d_lfifo(FAR const struct stm32_dma2d_s *layer, int lid,
+ fb_coord_t xpos, fb_coord_t ypos,
+ FAR const struct ltdc_area_s *area);
+static void stm32_dma2d_lcolor(FAR const struct stm32_dma2d_s *layer,
+ int lid, uint32_t color);
+static void stm32_dma2d_llnr(FAR struct stm32_dma2d_s *layer,
+ FAR const struct ltdc_area_s *area);
+static int stm32_dma2d_loutpfc(FAR const struct stm32_dma2d_s *layer);
+static void stm32_dma2d_lpfc(FAR const struct stm32_dma2d_s *layer,
+ int lid, uint32_t blendmode);
+/* Public functions */
+
+static int stm32_dma2dgetvideoinfo(FAR struct dma2d_layer_s *layer,
+ FAR struct fb_videoinfo_s *vinfo);
+static int stm32_dma2dgetplaneinfo(FAR struct dma2d_layer_s *layer, int planeno,
+ FAR struct fb_planeinfo_s *pinfo);
+static int stm32_dma2dgetlid(FAR struct dma2d_layer_s *layer, int *lid);
+#ifdef CONFIG_STM32F7_DMA2D_L8
+static int stm32_dma2dsetclut(FAR struct dma2d_layer_s *layer,
+ const FAR struct fb_cmap_s *cmap);
+static int stm32_dma2dgetclut(FAR struct dma2d_layer_s *layer,
+ FAR struct fb_cmap_s *cmap);
+#endif
+static int stm32_dma2dsetalpha(FAR struct dma2d_layer_s *layer, uint8_t alpha);
+static int stm32_dma2dgetalpha(FAR struct dma2d_layer_s *layer, uint8_t *alpha);
+static int stm32_dma2dsetblendmode(FAR struct dma2d_layer_s *layer,
+ uint32_t mode);
+static int stm32_dma2dgetblendmode(FAR struct dma2d_layer_s *layer,
+ uint32_t *mode);
+static int stm32_dma2dblit(FAR struct dma2d_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *src,
+ FAR const struct ltdc_area_s *srcarea);
+static int stm32_dma2dblend(FAR struct dma2d_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *fore,
+ fb_coord_t forexpos, fb_coord_t foreypos,
+ FAR const struct dma2d_layer_s *back,
+ FAR const struct ltdc_area_s *backarea);
+static int stm32_dma2dfillarea(FAR struct dma2d_layer_s *layer,
+ FAR const struct ltdc_area_s *area, uint32_t color);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Remember the layer references for alloc/deallocation */
+
+static struct stm32_dma2d_s *g_layers[DMA2D_LAYER_NSIZE];
+
+/* The DMA2D semaphore that enforces mutually exclusive access */
+
+static sem_t g_lock;
+
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+/* This structure provides the DMA2D layer for each LTDC layer */
+
+static struct stm32_ltdc_layer_s g_ltdc_layer;
+#endif
+
+/* The initalized state of the driver */
+
+static bool g_initialized;
+
+/* Semaphore for interrupt handling */
+
+static sem_t g_semirq;
+
+/* This structure provides irq handling */
+
+static struct stm32_interrupt_s g_interrupt =
+{
+ .wait = false,
+ .handled = true,
+ .irq = STM32_IRQ_DMA2D,
+ .sem = &g_semirq
+};
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dma2d_control
+ *
+ * Description:
+ * Change the DMA2D control register
+ *
+ * Parameter:
+ * setbits - The bits to set
+ * clrbits - The bits to clear
+ *
+ ****************************************************************************/
+
+static void stm32_dma2d_control(uint32_t setbits, uint32_t clrbits)
+{
+ uint32_t cr;
+
+ lcdinfo("setbits=%08x, clrbits=%08x\n", setbits, clrbits);
+
+ cr = getreg32(STM32_DMA2D_CR);
+ cr &= ~clrbits;
+ cr |= setbits;
+ putreg32(cr, STM32_DMA2D_CR);
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dirq
+ *
+ * Description:
+ * DMA2D interrupt handler
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dirq(int irq, void *context, FAR void *arg)
+{
+ uint32_t regval = getreg32(STM32_DMA2D_ISR);
+ FAR struct stm32_interrupt_s *priv = &g_interrupt;
+
+ reginfo("irq = %d, regval = %08x\n", irq, regval);
+
+ if (regval & DMA2D_ISR_TCIF)
+ {
+ /* Transfer complete interrupt */
+
+ /* Clear the interrupt status register */
+
+ putreg32(DMA2D_IFCR_CTCIF, STM32_DMA2D_IFCR);
+ }
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ else if (regval & DMA2D_ISR_CTCIF)
+ {
+ /* CLUT transfer complete interrupt */
+
+ /* Clear the interrupt status register */
+
+ putreg32(DMA2D_IFCR_CCTCIF, STM32_DMA2D_IFCR);
+ }
+#endif
+ else
+ {
+ /* Unknown irq, should not occur */
+
+ return OK;
+ }
+
+ /* Update the handled flag */
+
+ priv->handled = true;
+
+ /* Unlock the semaphore if locked */
+
+ if (priv->wait)
+ {
+
+ int ret = sem_post(priv->sem);
+
+ if (ret != OK)
+ {
+ lcderr("ERROR: sem_post() failed\n");
+ return ret;
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_waitforirq
+ *
+ * Description:
+ * Helper waits until the dma2d irq occurs. That means that an ongoing clut
+ * loading or dma transfer was completed.
+ * Note! The caller must use this function within a critical section.
+ *
+ * Return:
+ * On success OK otherwise ERROR
+ *
+ ****************************************************************************/
+
+static int stm32_dma2d_waitforirq(void)
+{
+ FAR struct stm32_interrupt_s *priv = &g_interrupt;
+
+ /* Only waits if last enabled interrupt is currently not handled */
+
+ if (!priv->handled)
+ {
+ int ret;
+
+ /* Inform the irq handler the task is able to wait for the irq */
+
+ priv->wait = true;
+
+ ret = sem_wait(priv->sem);
+
+ /* irq or an error occurs, reset the wait flag */
+
+ priv->wait = false;
+
+ if (ret != OK)
+ {
+ lcderr("ERROR: sem_wait() failed\n");
+ return ret;
+ }
+ }
+
+ return OK;
+}
+
+#ifdef CONFIG_STM32F7_DMA2D_L8
+/****************************************************************************
+ * Name: stm32_dma2d_loadclut
+ *
+ * Description:
+ * Starts clut loading but doesn't wait until loading is complete!
+ *
+ * Parameter:
+ * pfcreg - PFC control Register
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2d_loadclut(uintptr_t pfcreg)
+{
+ int ret;
+ uint32_t regval;
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ ret = stm32_dma2d_waitforirq();
+ if (ret == OK)
+ {
+ FAR struct stm32_interrupt_s *priv = &g_interrupt;
+
+ /* Reset the handled flag */
+
+ priv->handled = false;
+
+ /* Start clut loading */
+
+ regval = getreg32(pfcreg);
+ regval |= DMA2D_xGPFCCR_START;
+ reginfo("set regval=%08x\n", regval);
+ putreg32(regval, pfcreg);
+ reginfo("configured regval=%08x\n", getreg32(pfcreg));
+ }
+
+ leave_critical_section(flags);
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_dma2d_start
+ *
+ * Description:
+ * Starts the dma transfer and waits until completed.
+ *
+ * Parameter:
+ * reg - Register to set the start
+ * startflag - The related flag to start the dma transfer
+ * irqflag - The interrupt enable flag in the DMA2D_CR register
+ *
+ ****************************************************************************/
+
+static int stm32_dma2d_start(void)
+{
+ int ret;
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ ret = stm32_dma2d_waitforirq();
+ if (ret == OK)
+ {
+ FAR struct stm32_interrupt_s *priv = &g_interrupt;
+
+ /* Reset the handled flag */
+
+ priv->handled = false;
+
+ /* Start clut loading */
+
+ stm32_dma2d_control(DMA2D_CR_START, 0);
+
+ /* wait until transfer is complete */
+
+ ret = stm32_dma2d_waitforirq();
+ }
+
+ leave_critical_section(flags);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_memaddress
+ *
+ * Description:
+ * Helper to calculate the layer memory address
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ *
+ * Return:
+ * memory address
+ *
+ ****************************************************************************/
+
+static uint32_t stm32_dma2d_memaddress(FAR const struct stm32_dma2d_s *layer,
+ fb_coord_t xpos, fb_coord_t ypos)
+{
+ FAR const struct fb_planeinfo_s *pinfo = &layer->pinfo;
+ uint32_t offset;
+
+ offset = xpos * DMA2D_PF_BYPP(layer->pinfo.bpp) + layer->pinfo.stride * ypos;
+
+ lcdinfo("%p\n", ((uint32_t) pinfo->fbmem) + offset);
+ return ((uint32_t) pinfo->fbmem) + offset;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lineoffset
+ *
+ * Description:
+ * Helper to calculate the layer line offset
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ *
+ * Return:
+ * line offset
+ *
+ ****************************************************************************/
+
+static fb_coord_t stm32_dma2d_lineoffset(FAR const struct stm32_dma2d_s *layer,
+ FAR const struct ltdc_area_s *area)
+{
+ /* offset at the end of each line in the context to the area layer */
+
+ lcdinfo("%d\n", layer->vinfo.xres - area->xres);
+ return layer->vinfo.xres - area->xres;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_pixelformat
+ *
+ * Description:
+ * Helper to map to dma2d controller pixel format
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ * fmt - Reference to the location to store the pixel format
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2d_pixelformat(uint8_t fmt, uint8_t *fmtmap)
+{
+ lcdinfo("fmt=%d, fmtmap=%p\n", fmt, fmtmap);
+
+ /* Map to the controller known format
+ *
+ * Not supported by NuttX:
+ * ARGB8888
+ * ARGB1555
+ * ARGB4444
+ * AL44
+ * AL88
+ * L8 (non output layer only)
+ * L4
+ * A8
+ * A4
+ */
+
+ switch (fmt)
+ {
+#ifdef CONFIG_STM32F7_DMA2D_RGB565
+ case FB_FMT_RGB16_565:
+ *fmtmap = DMA2D_PF_RGB565;
+ break;
+#endif
+#ifdef CONFIG_STM32F7_DMA2D_RGB888
+ case FB_FMT_RGB24:
+ *fmtmap = DMA2D_PF_RGB888;
+ break;
+#endif
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ case FB_FMT_RGB8:
+ *fmtmap = DMA2D_PF_L8;
+ break;
+#endif
+ default:
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_bpp
+ *
+ * Description:
+ * Helper to get the bits per pixel
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ * bpp - Reference to the location to store the pixel format
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2d_bpp(uint8_t fmt, uint8_t *bpp)
+{
+ lcdinfo("fmt=%d, bpp=%p\n", fmt, bpp);
+
+ switch (fmt)
+ {
+#ifdef CONFIG_STM32F7_DMA2D_RGB565
+ case FB_FMT_RGB16_565:
+ *bpp = 16;
+ break;
+#endif
+#ifdef CONFIG_STM32F7_DMA2D_RGB888
+ case FB_FMT_RGB24:
+ *bpp = 24;
+ break;
+#endif
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ case FB_FMT_RGB8:
+ *bpp = 8;
+ break;
+#endif
+ default:
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lfreelid
+ *
+ * Description:
+ * Get a free layer id
+ *
+ * Return:
+ * The number of the free layer
+ * -1 if no free layer is available
+ *
+ ****************************************************************************/
+
+static int stm32_dma2d_lfreelid(void)
+{
+ int n;
+
+ for (n = DMA2D_SHADOW_LAYER; n < DMA2D_LAYER_NSIZE; n++)
+ {
+ if (g_layers[n] == NULL)
+ {
+ return n;
+ }
+ }
+
+ return -1;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lalloc
+ *
+ * Description:
+ * Allocate a new layer structure
+ *
+ * Return:
+ * A new allocated layer structure or NULL on error.
+ *
+ ****************************************************************************/
+
+static FAR struct stm32_dma2d_s * stm32_dma2d_lalloc(void)
+{
+ FAR struct stm32_dma2d_s *layer;
+
+#ifdef HAVE_DTCM_HEAP
+ /* First try to allocate from the dtcm heap */
+
+ layer = dtcm_malloc(sizeof(struct stm32_dma2d_s));
+
+ if (!layer)
+ {
+ /* Use default allocator */
+
+ layer = kmm_malloc(sizeof(struct stm32_dma2d_s));
+ }
+#else
+ layer = kmm_malloc(sizeof(struct stm32_dma2d_s));
+#endif
+
+ return layer;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lfree
+ *
+ * Description:
+ * Deallocate the dynamic allocated layer structure
+ *
+ * Input Parameters:
+ * A previous allocated layer structure
+ *
+ ****************************************************************************/
+
+static void stm32_dma2d_lfree(FAR struct stm32_dma2d_s *layer)
+{
+ if (layer)
+ {
+#ifdef HAVE_DTCM_HEAP
+ if ( (void*)(DTCM_START) <= layer && layer <= (void*)(DTCM_END) )
+ {
+ dtcm_free(layer);
+ }
+ else
+ {
+ kmm_free(layer);
+ }
+#else
+ kmm_free(layer);
+#endif
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_llayerscleanup
+ *
+ * Description:
+ * Cleanup all allocated layers
+ *
+ ****************************************************************************/
+
+static void stm32_dma2d_llayerscleanup(void)
+{
+ int n;
+
+ /* Do not uninitialize the ltdc related dma2d layer */
+
+ for (n = DMA2D_SHADOW_LAYER; n < DMA2D_LAYER_NSIZE; n++)
+ {
+ FAR struct stm32_dma2d_s *priv = g_layers[n];
+ if (priv)
+ {
+ kmm_free(priv->pinfo.fbmem);
+ stm32_dma2d_lfree(priv);
+ g_layers[n] = NULL;
+ }
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lvalidate
+ *
+ * Description:
+ * Helper to validate if the layer is valid
+ *
+ * Return:
+ * true if validates otherwise false
+ *
+ ****************************************************************************/
+
+static inline bool stm32_dma2d_lvalidate(FAR const struct stm32_dma2d_s *layer)
+{
+ return layer && layer->lid < DMA2D_LAYER_NSIZE;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lvalidatesize
+ *
+ * Description:
+ * Helper to check if area is outside the whole layer.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * xpos - The x position inside the whole layer
+ * ypos - The y position inside the whole layer
+ * area - the area inside the whole layer
+ *
+ * Return:
+ * true if area is inside the whole layer otherwise false
+ *
+ ****************************************************************************/
+
+static bool stm32_dma2d_lvalidatesize(FAR const struct stm32_dma2d_s *layer,
+ fb_coord_t xpos, fb_coord_t ypos,
+ FAR const struct ltdc_area_s *area)
+{
+ return stm32_dma2d_lvalidate(layer) &&
+ ((layer->vinfo.xres - xpos) * (layer->vinfo.yres - ypos) >=
+ area->xres * area->yres);
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_linit
+ *
+ * Description:
+ * Initialize the internal layer structure
+ *
+ * Parameter:
+ *
+ *
+ ****************************************************************************/
+
+static void stm32_dma2d_linit(FAR struct stm32_dma2d_s *layer,
+ int lid, uint8_t fmt)
+{
+ FAR struct dma2d_layer_s *priv = &layer->dma2d;
+
+ lcdinfo("layer=%p, lid=%d, fmt=%02x\n", layer, lid, fmt);
+
+ /* initialize the layer interface */
+
+ priv->getvideoinfo = stm32_dma2dgetvideoinfo;
+ priv->getplaneinfo = stm32_dma2dgetplaneinfo;
+ priv->getlid = stm32_dma2dgetlid;
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ priv->setclut = stm32_dma2dsetclut;
+ priv->getclut = stm32_dma2dgetclut;
+#endif
+ priv->setalpha = stm32_dma2dsetalpha;
+ priv->getalpha = stm32_dma2dgetalpha;
+ priv->setblendmode = stm32_dma2dsetblendmode;
+ priv->getblendmode = stm32_dma2dgetblendmode;
+ priv->blit = stm32_dma2dblit;
+ priv->blend = stm32_dma2dblend;
+ priv->fillarea = stm32_dma2dfillarea;
+
+ /* Initialize the layer structure */
+
+ layer->lid = lid;
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ layer->clut = 0;
+#endif
+ layer->blendmode = DMA2D_BLEND_NONE;
+ layer->alpha = 255;
+ layer->fmt = fmt;
+ layer->lock = &g_lock;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lfifo
+ *
+ * Description:
+ * Set the fifo for the foreground, background and output layer
+ * Configures the memory address register
+ * Configures the line offset register
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ *
+ ****************************************************************************/
+
+static void stm32_dma2d_lfifo(FAR const struct stm32_dma2d_s *layer, int lid,
+ fb_coord_t xpos, fb_coord_t ypos,
+ FAR const struct ltdc_area_s *area)
+{
+ lcdinfo("layer=%p, lid=%d, xpos=%d, ypos=%d, area=%p\n",
+ layer, lid, xpos, ypos, area);
+
+ putreg32(stm32_dma2d_memaddress(layer, xpos, ypos), stm32_mar_layer_t[lid]);
+ putreg32(stm32_dma2d_lineoffset(layer, area), stm32_or_layer_t[lid]);
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lcolor
+ *
+ * Description:
+ * Set the color for the layer
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ *
+ ****************************************************************************/
+
+static void stm32_dma2d_lcolor(FAR const struct stm32_dma2d_s *layer,
+ int lid, uint32_t color)
+{
+ lcdinfo("layer=%p, lid=%d, color=%08x\n", layer, lid, color);
+ putreg32(color, stm32_color_layer_t[lid]);
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_llnr
+ *
+ * Description:
+ * Set the number of line register
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ * area - Reference to the area to copy
+ *
+ ****************************************************************************/
+
+static void stm32_dma2d_llnr(FAR struct stm32_dma2d_s *layer,
+ FAR const struct ltdc_area_s *area)
+{
+ uint32_t nlrreg;
+
+ lcdinfo("pixel per line: %d, number of lines: %d\n", area->xres, area->yres);
+
+ nlrreg = getreg32(STM32_DMA2D_NLR);
+ nlrreg = (DMA2D_NLR_PL(area->xres) | DMA2D_NLR_NL(area->yres));
+ putreg32(nlrreg, STM32_DMA2D_NLR);
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_loutpfc
+ *
+ * Description:
+ * Set the output PFC control register
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ *
+ ****************************************************************************/
+
+static int stm32_dma2d_loutpfc(FAR const struct stm32_dma2d_s *layer)
+{
+ lcdinfo("layer=%p\n", layer);
+
+ /* CLUT format isn't supported by the dma2d controller */
+
+ if (layer->fmt == DMA2D_PF_L8)
+ {
+ /* Destination layer doesn't support CLUT output */
+
+ lcderr("ERROR: Returning ENOSYS, "
+ "output to layer with CLUT format not supported.\n");
+ return -ENOSYS;
+ }
+
+ /* Set the mapped pixel format of source layer */
+
+ putreg32(DMA2D_OPFCCR_CM(layer->fmt), STM32_DMA2D_OPFCCR);
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2d_lpfc
+ *
+ * Description:
+ * Configure foreground and background layer PFC control register
+ *
+ * Parameter:
+ * layer - Reference to the common layer state structure
+ *
+ ****************************************************************************/
+
+static void stm32_dma2d_lpfc(FAR const struct stm32_dma2d_s *layer,
+ int lid, uint32_t blendmode)
+{
+ uint32_t pfccrreg;
+
+ lcdinfo("layer=%p, lid=%d, blendmode=%08x\n", layer, lid, blendmode);
+
+ /* Set color format */
+
+ pfccrreg = DMA2D_xGPFCCR_CM(layer->fmt);
+
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ if (layer->fmt == DMA2D_PF_L8)
+ {
+ /* Load CLUT automatically */
+
+ pfccrreg |= DMA2D_xGPFCCR_START;
+
+ /* Set the CLUT color mode */
+
+#ifndef CONFIG_FB_TRANSPARENCY
+ pfccrreg |= DMA2D_xGPFCCR_CCM;
+#endif
+
+ /* Set CLUT size */
+
+ pfccrreg |= DMA2D_xGPFCCR_CS(DMA2D_CLUT_SIZE);
+
+ /* Set the CLUT memory address */
+
+ putreg32((uint32_t) layer->clut, stm32_cmar_layer_t[lid]);
+
+ /* Start async clut loading */
+
+ stm32_dma2d_loadclut(stm32_pfccr_layer_t[lid]);
+ }
+#endif
+
+ if (blendmode & DMA2D_BLEND_NONE)
+ {
+ /* No blend operation */
+
+ pfccrreg |= DMA2D_xGPFCCR_AM(STM32_DMA2D_PFCCR_AM_NONE);
+ }
+ else
+ {
+ /* Set alpha value */
+
+ pfccrreg |= DMA2D_xGPFCCR_ALPHA(layer->alpha);
+
+ /* Set alpha mode */
+
+ if (layer->blendmode & DMA2D_BLEND_ALPHA)
+ {
+ /* Blend with constant alpha */
+
+ pfccrreg |= DMA2D_xGPFCCR_AM(STM32_DMA2D_PFCCR_AM_CONST);
+ }
+ else if (layer->blendmode & DMA2D_BLEND_PIXELALPHA)
+ {
+ /* Blend with pixel alpha value */
+
+ pfccrreg |= DMA2D_xGPFCCR_AM(STM32_DMA2D_PFCCR_AM_PIXEL);
+ }
+ }
+
+ putreg32(pfccrreg, stm32_pfccr_layer_t[lid]);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_dma2dgetvideoinfo
+ *
+ * Description:
+ * Get video information about the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * vinfo - Reference to the video info structure
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dgetvideoinfo(FAR struct dma2d_layer_s *layer,
+ FAR struct fb_videoinfo_s *vinfo)
+{
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, vinfo=%p\n", layer, vinfo);
+
+ if (stm32_dma2d_lvalidate(priv) && vinfo)
+ {
+ sem_wait(priv->lock);
+ memcpy(vinfo, &priv->vinfo, sizeof(struct fb_videoinfo_s));
+ sem_post(priv->lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -ENOSYS;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dgetplaneinfo
+ *
+ * Description:
+ * Get plane information about the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * planeno - Number of the plane
+ * pinfo - Reference to the plane info structure
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dgetplaneinfo(FAR struct dma2d_layer_s *layer, int planeno,
+ FAR struct fb_planeinfo_s *pinfo)
+{
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, planeno=%d, pinfo=%p\n", layer, planeno, pinfo);
+
+ if (stm32_dma2d_lvalidate(priv) && pinfo && planeno == 0)
+ {
+ sem_wait(priv->lock);
+ memcpy(pinfo, &priv->pinfo, sizeof(struct fb_planeinfo_s));
+ sem_post(priv->lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dgetlid
+ *
+ * Description:
+ * Get a specific layer identifier.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * lid - Reference to store the layer id
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dgetlid(FAR struct dma2d_layer_s *layer, int *lid)
+{
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, lid=%p\n", layer, lid);
+
+ if (stm32_dma2d_lvalidate(priv) && lid)
+ {
+ sem_wait(priv->lock);
+ *lid = priv->lid;
+ sem_post(priv->lock);
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+#ifdef CONFIG_STM32F7_DMA2D_L8
+/****************************************************************************
+ * Name: stm32_dma2dsetclut
+ *
+ * Description:
+ * Configure layer clut (color lookup table).
+ * Non clut is defined during initializing.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * cmap - color lookup table with up the 256 entries
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dsetclut(FAR struct dma2d_layer_s *layer,
+ const FAR struct fb_cmap_s *cmap)
+{
+ int ret;
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, cmap=%p\n", layer, cmap);
+
+ if (stm32_dma2d_lvalidate(priv) && cmap)
+ {
+ sem_wait(priv->lock);
+
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+ if (priv->lid < DMA2D_SHADOW_LAYER)
+ {
+ /* Update the shared color lookup table.
+ *
+ * Background:
+ *
+ * We share the same memory region of the clut table with the LTDC
+ * driver. (see stm32_dma2dinitltdc). This is important because any
+ * changes to the framebuffer and color lookup table by the ltdc
+ * related dma2d layer should also effects to the ltdc visibility,
+ * except operation settings, alpha and blendmode.
+ *
+ * But we can not only update the clut memory region. The LTDC driver
+ * also must update they own LTDC clut register to make the changes
+ * visible. Using the LTDC interface to update the clut table will
+ * also update the clut table of the related dma2d layer.
+ */
+
+ FAR struct ltdc_layer_s *ltdc =
+ g_ltdc_layer.layer[DMA2D_SHADOW_LAYER_L1].ltdc;
+
+ ret = ltdc->setclut(ltdc, cmap);
+
+ sem_post(priv->lock);
+
+ return ret;
+ }
+#endif
+
+ if (priv->fmt != DMA2D_PF_L8)
+ {
+ lcderr("ERROR: CLUT is not supported for the pixel format: %d\n",
+ priv->vinfo.fmt);
+ ret = -EINVAL;
+ }
+ else if (cmap->first >= STM32_DMA2D_NCLUT)
+ {
+ lcderr("ERROR: only %d color table entries supported\n",
+ STM32_DMA2D_NCLUT);
+ ret = -EINVAL;
+ }
+ else
+ {
+ uint32_t *clut;
+ int n;
+
+ clut = priv->clut;
+
+ for (n = cmap->first; n < cmap->len && n < STM32_DMA2D_NCLUT; n++)
+ {
+ /* Update the layer clut entry */
+
+#ifndef CONFIG_FB_TRANSPARENCY
+ uint8_t *clut888 = (uint8_t *)clut;
+ uint16_t offset = 3 * n;
+
+ clut888[offset] = cmap->blue[n];
+ clut888[offset + 1] = cmap->green[n];
+ clut888[offset + 2] = cmap->red[n];
+
+ reginfo("n=%d, red=%02x, green=%02x, blue=%02x\n", n,
+ clut888[offset], clut888[offset + 1],
+ clut888[offset + 2]);
+#else
+ clut[n] = (uint32_t)DMA2D_CLUT_RED(cmap->transp[n]) |
+ (uint32_t)DMA2D_CLUT_GREEN(cmap->red[n]) |
+ (uint32_t)DMA2D_CLUT_GREEN(cmap->green[n]) |
+ (uint32_t)DMA2D_CLUT_BLUE(cmap->blue[n]);
+
+ reginfo("n=%d, alpha=%02x, red=%02x, green=%02x, blue=%02x\n", n,
+ DMA2D_CLUT_ALPHA(cmap->alpha[n]),
+ DMA2D_CLUT_RED(cmap->red[n]),
+ DMA2D_CLUT_GREEN(cmap->green[n]),
+ DMA2D_CLUT_BLUE(cmap->blue[n]));
+#endif
+ }
+
+
+ ret = OK;
+ }
+
+ sem_post(priv->lock);
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dgetclut
+ *
+ * Description:
+ * Get configured layer clut (color lookup table).
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * cmap - Reference to valid color lookup table accept up the 256 color
+ * entries
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dgetclut(FAR struct dma2d_layer_s *layer,
+ FAR struct fb_cmap_s *cmap)
+{
+ int ret;
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, cmap=%p\n", layer, cmap);
+
+ if (stm32_dma2d_lvalidate(priv) && cmap)
+ {
+ sem_wait(priv->lock);
+
+ if (priv->fmt != DMA2D_PF_L8)
+ {
+ lcderr("ERROR: CLUT is not supported for the pixel format: %d\n",
+ priv->vinfo.fmt);
+ ret = -EINVAL;
+ }
+ else if (cmap->first >= STM32_DMA2D_NCLUT)
+ {
+ lcderr("ERROR: only %d color table entries supported\n",
+ STM32_DMA2D_NCLUT);
+ ret = -EINVAL;
+ }
+ else
+ {
+ /* Copy from the layer clut */
+
+ uint32_t *clut;
+ int n;
+
+ clut = priv->clut;
+
+ for (n = cmap->first; n < cmap->len && n < STM32_DMA2D_NCLUT; n++)
+ {
+#ifndef CONFIG_FB_TRANSPARENCY
+ uint8_t *clut888 = (uint8_t *)clut;
+ uint16_t offset = 3 * n;
+
+ cmap->blue[n] = clut888[offset];
+ cmap->green[n] = clut888[offset + 1];
+ cmap->red[n] = clut888[offset + 2];
+
+ reginfo("n=%d, red=%02x, green=%02x, blue=%02x\n", n,
+ clut888[offset], clut888[offset + 1],
+ clut888[offset + 2]);
+#else
+ cmap->transp[n] = (uint8_t)DMA2D_CMAP_ALPHA(clut[n]);
+ cmap->red[n] = (uint8_t)DMA2D_CMAP_RED(clut[n]);
+ cmap->green[n] = (uint8_t)DMA2D_CMAP_GREEN(clut[n]);
+ cmap->blue[n] = (uint8_t)DMA2D_CMAP_BLUE(clut[n]);
+
+ reginfo("n=%d, alpha=%02x, red=%02x, green=%02x, blue=%02x\n", n,
+ DMA2D_CMAP_ALPHA(clut[n]), DMA2D_CMAP_RED(clut[n]),
+ DMA2D_CMAP_GREEN(clut[n]), DMA2D_CMAP_BLUE(clut[n]));
+#endif
+ }
+
+ ret = OK;
+ }
+
+ sem_post(priv->lock);
+
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_dma2dsetalpha
+ *
+ * Description:
+ * Configure layer alpha value factor into blend operation.
+ * During the layer blend operation the source alpha value is multiplied
+ * with this alpha value. If the source color format doesn't support alpha
+ * channel (e.g. non ARGB8888) this alpha value will be used as constant
+ * alpha value for blend operation.
+ * Default value during initializing: 0xff
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * alpha - Alpha value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dsetalpha(FAR struct dma2d_layer_s *layer, uint8_t alpha)
+{
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, alpha=%02x\n", layer, alpha);
+
+ if (stm32_dma2d_lvalidate(priv))
+ {
+ sem_wait(priv->lock);
+ priv->alpha = alpha;
+ sem_post(priv->lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dgetalpha
+ *
+ * Description:
+ * Get configured layer alpha value factor for blend operation.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * alpha - Reference to store the alpha value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dgetalpha(FAR struct dma2d_layer_s *layer, uint8_t *alpha)
+{
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, alpha=%p\n", layer, alpha);
+
+ if (stm32_dma2d_lvalidate(priv))
+ {
+ sem_wait(priv->lock);
+ *alpha = priv->alpha;
+ sem_post(priv->lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dsetblendmode
+ *
+ * Description:
+ * Configure blend mode of the layer.
+ * Default mode during initializing: DMA2D_BLEND_NONE
+ * Blendmode is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - Blend mode (see DMA2D_BLEND_*)
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ * Procedure information:
+ * DMA2D_BLEND_NONE:
+ * Informs the driver to disable all blend operation for the given layer.
+ * That means the layer is opaque.
+ *
+ * DMA2D_BLEND_ALPHA:
+ * Informs the driver to enable alpha blending for the given layer.
+ *
+ * DMA2D_BLEND_PIXELALPHA:
+ * Informs the driver to use the pixel alpha value of the layer instead
+ * the constant alpha value. This is only useful for ARGB8888
+ * color format.
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dsetblendmode(FAR struct dma2d_layer_s *layer,
+ uint32_t mode)
+{
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, mode=%08x\n", layer, mode);
+
+ if (stm32_dma2d_lvalidate(priv))
+ {
+ sem_wait(priv->lock);
+ priv->blendmode = mode;
+ sem_post(priv->lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getblendmode
+ *
+ * Description:
+ * Get configured blend mode of the layer.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - Reference to store the blend mode
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dgetblendmode(FAR struct dma2d_layer_s *layer,
+ uint32_t *mode)
+{
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, mode=%p\n", layer, mode);
+
+ if (stm32_dma2d_lvalidate(priv) && mode)
+ {
+ sem_wait(priv->lock);
+ *mode = priv->blendmode;
+ sem_post(priv->lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dblit
+ *
+ * Description:
+ * Copy selected area from a source layer to selected position of the
+ * destination layer.
+ *
+ * Parameter:
+ * dest - Valid reference to the destination layer
+ * destxpos - Valid selected x position of the destination layer
+ * destypos - Valid selected y position of the destination layer
+ * src - Valid reference to the source layer
+ * srcarea - Valid reference to the selected area of the source layer
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * source area outside the visible area of the destination layer.
+ * (The visible area usually represents the display size)
+ * -ECANCELED - Operation cancelled, something goes wrong.
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dblit(FAR struct dma2d_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *src,
+ FAR const struct ltdc_area_s *srcarea)
+{
+ uint32_t mode;
+ int ret;
+ FAR struct stm32_dma2d_s * destlayer = (FAR struct stm32_dma2d_s *)dest;
+ FAR struct stm32_dma2d_s * srclayer = (FAR struct stm32_dma2d_s *)src;
+
+ lcdinfo("dest=%p, destxpos=%d, destypos=%d, src=%p, srcarea=%p\n",
+ dest, destxpos, destypos, src, srcarea);
+
+ if (stm32_dma2d_lvalidatesize(destlayer, destxpos, destypos, srcarea) &&
+ stm32_dma2d_lvalidatesize(srclayer, srcarea->xpos,
+ srcarea->ypos, srcarea))
+ {
+ sem_wait(destlayer->lock);
+
+ /* Set output pfc */
+
+ ret = stm32_dma2d_loutpfc(destlayer);
+
+ if (ret == OK)
+ {
+ /* Set foreground pfc */
+
+ stm32_dma2d_lpfc(srclayer, DMA2D_LAYER_LFORE, DMA2D_BLEND_NONE);
+
+ /* Set foreground fifo */
+
+ stm32_dma2d_lfifo(srclayer, DMA2D_LAYER_LFORE,
+ srcarea->xpos, srcarea->ypos, srcarea);
+
+ /* Set output fifo */
+
+ stm32_dma2d_lfifo(destlayer, DMA2D_LAYER_LOUT,
+ destxpos, destypos, srcarea);
+
+ /* Set number of lines and pixel per line */
+
+ stm32_dma2d_llnr(destlayer, srcarea);
+
+ /* Set dma2d mode for blit operation */
+
+ if (destlayer->fmt == srclayer->fmt)
+ {
+ /* Blit without pfc */
+
+ mode = STM32_DMA2D_CR_MODE_BLIT;
+ }
+ else
+ {
+ /* Blit with pfc */
+
+ mode = STM32_DMA2D_CR_MODE_BLITPFC;
+ }
+
+ stm32_dma2d_control(mode, STM32_DMA2D_CR_MODE_CLEAR);
+
+ /* Start DMA2D and wait until completed */
+
+ ret = stm32_dma2d_start();
+
+ if (ret != OK)
+ {
+ ret = -ECANCELED;
+ lcderr("ERROR: Returning ECANCELED\n");
+ }
+ }
+
+ sem_post(destlayer->lock);
+ }
+ else
+ {
+ ret = -EINVAL;
+ lcderr("ERROR: Returning EINVAL\n");
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dblend
+ *
+ * Description:
+ * Blends the selected area from a background layer with selected position
+ * of the foreground layer. Copies the result to the selected position of
+ * the destination layer. Note! The content of the foreground and background
+ * layer keeps unchanged as long destination layer is unequal to the
+ * foreground and background layer.
+ *
+ * Parameter:
+ * dest - Reference to the destination layer
+ * fore - Reference to the foreground layer
+ * forexpos - Selected x target position of the foreground layer
+ * foreypos - Selected y target position of the foreground layer
+ * back - Reference to the background layer
+ * backarea - Reference to the selected area of the background layer
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * source area outside the visible area of the destination layer.
+ * (The visible area usually represents the display size)
+ * -ECANCELED - Operation cancelled, something goes wrong.
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dblend(FAR struct dma2d_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *fore,
+ fb_coord_t forexpos, fb_coord_t foreypos,
+ FAR const struct dma2d_layer_s *back,
+ FAR const struct ltdc_area_s *backarea)
+{
+ int ret;
+ FAR struct stm32_dma2d_s * destlayer = (FAR struct stm32_dma2d_s *)dest;
+ FAR struct stm32_dma2d_s * forelayer = (FAR struct stm32_dma2d_s *)fore;
+ FAR struct stm32_dma2d_s * backlayer = (FAR struct stm32_dma2d_s *)back;
+
+ lcdinfo("dest=%p, destxpos=%d, destypos=%d, "
+ "fore=%p, forexpos=%d, foreypos=%d, "
+ "back=%p, backarea=%p\n",
+ dest, destxpos, destypos, fore, forexpos, foreypos, back, backarea);
+
+ if (stm32_dma2d_lvalidatesize(destlayer, destxpos, destypos, backarea) &&
+ stm32_dma2d_lvalidatesize(forelayer, forexpos, foreypos, backarea) &&
+ stm32_dma2d_lvalidatesize(backlayer, backarea->xpos,
+ backarea->ypos, backarea))
+ {
+
+ sem_wait(destlayer->lock);
+
+ /* Set output pfc */
+
+ ret = stm32_dma2d_loutpfc(destlayer);
+
+ if (ret == OK)
+ {
+ /* Set background pfc */
+
+ stm32_dma2d_lpfc(backlayer, DMA2D_LAYER_LBACK, backlayer->blendmode);
+
+ /* Set foreground pfc */
+
+ stm32_dma2d_lpfc(forelayer, DMA2D_LAYER_LFORE, forelayer->blendmode);
+
+ /* Set background fifo */
+
+ stm32_dma2d_lfifo(backlayer, DMA2D_LAYER_LBACK,
+ backarea->xpos, backarea->ypos, backarea);
+
+ /* Set foreground fifo */
+
+ stm32_dma2d_lfifo(forelayer, DMA2D_LAYER_LFORE,
+ forexpos, foreypos, backarea);
+
+ /* Set output fifo */
+
+ stm32_dma2d_lfifo(destlayer, DMA2D_LAYER_LOUT,
+ destxpos, destypos, backarea);
+
+ /* Set number of lines and pixel per line */
+
+ stm32_dma2d_llnr(destlayer, backarea);
+
+ /* Set watermark */
+
+ /* Enable DMA2D blender */
+
+ stm32_dma2d_control(STM32_DMA2D_CR_MODE_BLEND,
+ STM32_DMA2D_CR_MODE_CLEAR);
+
+ /* Start DMA2D and wait until completed */
+
+ ret = stm32_dma2d_start();
+
+ if (ret != OK)
+ {
+ ret = -ECANCELED;
+ lcderr("ERROR: Returning ECANCELED\n");
+ }
+ }
+
+ sem_post(destlayer->lock);
+ }
+ else
+ {
+ ret = -EINVAL;
+ lcderr("ERROR: Returning EINVAL\n");
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_dma2dfillarea
+ *
+ * Description:
+ * Fill the selected area of the whole layer with a specific color.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * area - Reference to the valid area structure select the area
+ * color - Color to fill the selected area. Color must be formatted
+ * according to the layer pixel format.
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * area outside the visible area of the layer.
+ * -ECANCELED - Operation cancelled, something goes wrong.
+ *
+ ****************************************************************************/
+
+static int stm32_dma2dfillarea(FAR struct dma2d_layer_s *layer,
+ FAR const struct ltdc_area_s *area,
+ uint32_t color)
+{
+ int ret;
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ lcdinfo("layer=%p, area=%p, color=%08x\n", layer, area, color);
+
+ if (stm32_dma2d_lvalidatesize(priv, area->xpos, area->ypos, area))
+ {
+
+ sem_wait(priv->lock);
+
+ /* Set output pfc */
+
+ ret = stm32_dma2d_loutpfc(priv);
+
+ if (ret == OK)
+ {
+ /* Set output fifo */
+
+ stm32_dma2d_lfifo(priv, DMA2D_LAYER_LOUT,
+ area->xpos, area->ypos, area);
+
+ /* Set the output color register */
+
+ stm32_dma2d_lcolor(priv, DMA2D_LAYER_LOUT, color);
+
+ /* Set number of lines and pixel per line */
+
+ stm32_dma2d_llnr(priv, area);
+
+ /* Set register to memory transfer */
+
+ stm32_dma2d_control(STM32_DMA2D_CR_MODE_COLOR,
+ STM32_DMA2D_CR_MODE_CLEAR);
+
+ /* Start DMA2D and wait until completed */
+
+ ret = stm32_dma2d_start();
+
+ if (ret != OK)
+ {
+ ret = -ECANCELED;
+ lcderr("ERROR: Returning ECANCELED\n");
+ }
+ }
+
+ sem_post(priv->lock);
+ }
+ else
+ {
+ ret = -EINVAL;
+ lcderr("ERROR: Returning EINVAL\n");
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: up_dma2dgetlayer
+ *
+ * Description:
+ * Get a dma2d layer structure by the layer identifier
+ *
+ * Parameter:
+ * lid - Layer identifier
+ *
+ * Return:
+ * Reference to the dma2d layer control structure on success or Null if no
+ * related exist.
+ *
+ ****************************************************************************/
+
+FAR struct dma2d_layer_s * up_dma2dgetlayer(int lid)
+{
+ if (lid < DMA2D_LAYER_NSIZE)
+ {
+ FAR struct stm32_dma2d_s *priv;
+ sem_wait(&g_lock);
+ priv = g_layers[lid];
+ sem_post(&g_lock);
+
+ return &priv->dma2d;
+ }
+
+ lcderr("ERROR: EINVAL, Unknown layer identifier\n");
+ errno = EINVAL;
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: up_dma2dcreatelayer
+ *
+ * Description:
+ * Create a new dma2d layer object to interact with the dma2d controller
+ *
+ * Parameter:
+ * width - Layer width
+ * height - Layer height
+ * fmt - Pixel format of the layer
+ *
+ * Return:
+ * On success - A valid dma2d layer reference
+ * On error - NULL and errno is set to
+ * -EINVAL if one of the parameter is invalid
+ * -ENOMEM if no memory available or exceeds
+ * CONFIG_STM32F7_DMA2D_NLAYERS
+ *
+ ****************************************************************************/
+
+FAR struct dma2d_layer_s *up_dma2dcreatelayer(fb_coord_t width,
+ fb_coord_t height,
+ uint8_t fmt)
+{
+ int ret;
+ int lid;
+ uint8_t fmtmap;
+ uint8_t bpp = 0;
+ FAR struct stm32_dma2d_s *layer = NULL;
+
+ lcdinfo("width=%d, height=%d, fmt=%02x \n", width, height, fmt);
+
+ /* Validate if pixel format supported */
+
+ ret = stm32_dma2d_pixelformat(fmt, &fmtmap);
+
+ if (ret != OK)
+ {
+ errno = -ret;
+ return NULL;
+ }
+
+ ret = stm32_dma2d_bpp(fmt, &bpp);
+
+ sem_wait(&g_lock);
+
+ /* Get a free layer identifier */
+
+ lid = stm32_dma2d_lfreelid();
+
+ if (lid >= 0)
+ {
+ layer = stm32_dma2d_lalloc();
+
+ if (layer)
+ {
+ uint32_t fblen;
+ void *fbmem;
+ fb_coord_t stride;
+
+ /* Stride calculation for the supported formats */
+
+ stride = width * bpp / 8;
+
+ /* Calculate buffer size */
+
+ fblen = stride * height;
+
+ /* Allocate 32-bit aligned memory for the layer buffer. As reported in
+ * mm_memalign 8-byte alignment is guaranteed by normal malloc calls.
+ * We have also ensure memory is allocated from the SRAM1/2/3 block.
+ */
+
+ fbmem = kmm_zalloc(fblen); /* STM32F7: Should use DTCM ? */
+
+ if (fbmem)
+ {
+ FAR struct fb_videoinfo_s *vinfo = &layer->vinfo;
+ FAR struct fb_planeinfo_s *pinfo = &layer->pinfo;
+
+ /* Initialize dma2d structure */
+
+ stm32_dma2d_linit(layer, lid, fmtmap);
+
+ /* Initialize the videoinfo structure */
+
+ vinfo->fmt = fmt;
+ vinfo->xres = width;
+ vinfo->yres = height;
+ vinfo->nplanes = 1;
+
+ /* Initialize the planeinfo structure */
+
+ pinfo->fbmem = fbmem;
+ pinfo->fblen = fblen;
+ pinfo->stride = stride;
+ pinfo->display = 0;
+ pinfo->bpp = bpp;
+
+ /* Bind the layer to the identifier */
+
+ g_layers[lid] = layer;
+ }
+ else
+ {
+ /* free the layer struture */
+
+ kmm_free(layer);
+ layer = NULL;
+ lcderr("ERROR: ENOMEM, Unable to allocate layer buffer\n");
+ errno = ENOMEM;
+ }
+ }
+ else
+ {
+ lcderr("ERROR: ENOMEM, unable to allocate layer structure\n");
+ errno = ENOMEM;
+ }
+ }
+ else
+ {
+ lcderr("ERROR: EINVAL, no free layer available\n");
+ errno = EINVAL;
+ }
+
+ sem_post(&g_lock);
+ return (FAR struct dma2d_layer_s *)layer;
+}
+
+/****************************************************************************
+ * Name: up_dma2dremovelayer
+ *
+ * Description:
+ * Remove and deallocate the dma2d layer
+ *
+ * Parameter:
+ * layer - Reference to the layer to remove
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+int up_dma2dremovelayer(FAR struct dma2d_layer_s *layer)
+{
+ int ret = -EINVAL;
+ FAR struct stm32_dma2d_s *priv = (FAR struct stm32_dma2d_s *)layer;
+
+ /* Check if the layer is valid and unlike a ltdc related layer */
+
+ if (stm32_dma2d_lvalidate(priv) && priv->lid >= DMA2D_SHADOW_LAYER)
+ {
+ sem_wait(priv->lock);
+
+ /* Check also if the layer id is valid to the layer reference */
+
+ if (priv == g_layers[priv->lid])
+ {
+ int lid = priv->lid;
+
+ kmm_free(priv->pinfo.fbmem);
+ stm32_dma2d_lfree(priv);
+
+ g_layers[lid] = NULL;
+ ret = OK;
+ }
+
+ sem_post(priv->lock);
+ }
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: up_dma2dinitialize
+ *
+ * Description:
+ * Initialize the dma2d controller
+ *
+ * Return:
+ * OK - On success
+ * An error if initializing failed.
+ *
+ ****************************************************************************/
+
+int up_dma2dinitialize(void)
+{
+ lcdinfo("Initialize DMA2D driver\n");
+
+ if (g_initialized == false)
+ {
+ /* Abort current dma2d data transfer */
+
+ up_dma2duninitialize();
+
+ /* Enable dma2d is done in rcc_enableahb1, see
+ * arch/arm/src/stm32/stm32f40xxx_rcc.c
+ */
+
+ /* Initialize the DMA2D semaphore that enforces mutually exclusive access
+ * to the driver
+ */
+
+ sem_init(&g_lock, 0, 1);
+
+ /* Initialize the semaphore for interrupt handling. This waitsem
+ * semaphore is used for signaling and, hence, should not have
+ * priority inheritance enabled.
+ */
+
+ sem_init(g_interrupt.sem, 0, 0);
+ sem_setprotocol(g_interrupt.sem, SEM_PRIO_NONE);
+
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ /* Enable dma2d transfer and clut loading interrupts only */
+
+ stm32_dma2d_control(DMA2D_CR_TCIE | DMA2D_CR_CTCIE, DMA2D_CR_TEIE |
+ DMA2D_CR_TWIE | DMA2D_CR_CAEIE | DMA2D_CR_CEIE);
+#else
+ /* Enable dma transfer interrupt only */
+
+ stm32_dma2d_control(DMA2D_CR_TCIE, DMA2D_CR_TEIE | DMA2D_CR_TWIE |
+ DMA2D_CR_CAEIE | DMA2D_CR_CTCIE | DMA2D_CR_CEIE);
+#endif
+
+ /* Attach DMA2D interrupt vector */
+
+ (void)irq_attach(g_interrupt.irq, stm32_dma2dirq, NULL);
+
+ /* Enable the IRQ at the NVIC */
+
+ up_enable_irq(g_interrupt.irq);
+
+ /* Initialize the dma2d layer for ltdc binding */
+
+#ifdef DMA2D_SHADOW_LAYER_L1
+ g_layers[DMA2D_SHADOW_LAYER_L1] =
+ &g_ltdc_layer.layer[DMA2D_SHADOW_LAYER_L1].dma2ddev;
+#endif
+#ifdef DMA2D_SHADOW_LAYER_L2
+ g_layers[DMA2D_SHADOW_LAYER_L2] =
+ &g_ltdc_layer.layer[DMA2D_SHADOW_LAYER_L2].dma2ddev;
+#endif
+ /* Set initialized state */
+
+ g_initialized = true;
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: up_dma2duninitialize
+ *
+ * Description:
+ * Uninitialize the dma2d controller
+ *
+ ****************************************************************************/
+
+void up_dma2duninitialize(void)
+{
+ /* Disable DMA2D interrupts */
+
+ up_disable_irq(g_interrupt.irq);
+ irq_detach(g_interrupt.irq);
+
+ /* Cleanup all layers */
+
+ stm32_dma2d_llayerscleanup();
+
+ /* Abort current dma2d transfer */
+
+ stm32_dma2d_control(DMA2D_CR_ABORT, 0);
+
+ /* Set initialized state */
+
+ g_initialized = false;
+}
+
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+/****************************************************************************
+ * Name: stm32_dma2dinitltdc
+ *
+ * Description:
+ * Get a reference to the dma2d layer coupled with the ltdc layer.
+ * It not intends to use this by user space applications.
+ * It resolves the following requirements:
+ * 1. Share the color lookup table
+ * 2. Share the planeinfo information
+ * 3. Share the videoinfo information
+ *
+ * Parameter:
+ * layer - a valid reference to the low level ltdc layer structure
+ * clut - a pointer to a valid memory region to hold 256 clut colors
+ *
+ * Return:
+ * On success - A valid dma2d layer reference
+ * On error - NULL and errno is set to
+ * -EINVAL if one of the parameter is invalid
+ *
+ ****************************************************************************/
+
+FAR struct dma2d_layer_s * stm32_dma2dinitltdc(FAR struct stm32_ltdc_s *layer)
+{
+ int ret;
+ uint8_t fmt = 0;
+ FAR struct stm32_ltdc_dma2d_s *priv;
+
+ lcdinfo("layer=%p\n", layer);
+ DEBUGASSERT(layer && layer->lid >= 0 && layer->lid < DMA2D_SHADOW_LAYER);
+
+ ret = stm32_dma2d_pixelformat(layer->vinfo.fmt, &fmt);
+
+ if (ret != OK)
+ {
+ lcderr("ERROR: Returning -EINVAL, unsupported pixel format: %d\n",
+ layer->vinfo.fmt);
+ errno = -EINVAL;
+ return NULL;
+ }
+
+ priv = &g_ltdc_layer.layer[layer->lid];
+
+ stm32_dma2d_linit(&priv->dma2ddev, layer->lid, fmt);
+
+ memcpy(&priv->dma2ddev.vinfo, &layer->vinfo, sizeof(struct fb_videoinfo_s));
+ memcpy(&priv->dma2ddev.pinfo, &layer->pinfo, sizeof(struct fb_planeinfo_s));
+
+#ifdef CONFIG_STM32F7_DMA2D_L8
+ /* Verifies that the ltdc layer has a clut. This ensures that DMA2D driver can
+ * support clut format but the LTDC driver does not and vice versa.
+ */
+
+ if (layer->vinfo.fmt == FB_FMT_RGB8)
+ {
+ priv->dma2ddev.clut = layer->clut;
+ priv->ltdc = stm32_ltdcgetlayer(layer->lid);
+ DEBUGASSERT(priv->ltdc != NULL);
+ }
+#endif
+
+ return &priv->dma2ddev.dma2d;
+}
+#endif /* CONFIG_STM32F7_LTDC_INTERFACE */
diff --git a/arch/arm/src/stm32f7/stm32_dma2d.h b/arch/arm/src/stm32f7/stm32_dma2d.h
new file mode 100644
index 00000000000..7e0f0213ad4
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_dma2d.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_dma2d.h
+ *
+ * Copyright (C) 2014-2015 Marco Krahl. All rights reserved.
+ * Author: Marco Krahl
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_STM32_DMA2D_H
+#define __ARCH_ARM_SRC_STM32F7_STM32_DMA2D_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include
+#include
+#include
+
+#ifdef CONFIG_STM32F7_DMA2D
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+# ifdef CONFIG_STM32F7_LTDC_INTERFACE
+/****************************************************************************
+ * Name: stm32_dma2dinitltdc
+ *
+ * Description:
+ * Get a reference to the dma2d layer coupled with the ltdc layer.
+ * It not intends to use this function by user space applications.
+ * It resolves the following requirements:
+ * 1. Share the color lookup table
+ * 2. Share the planeinfo information
+ * 3. Share the videoinfo information
+ *
+ * Parameter:
+ * layer - a valid reference to the low level ltdc layer structure
+ *
+ * Return:
+ * On success - A valid dma2d layer reference
+ * On error - NULL and errno is set to
+ * -EINVAL if one of the parameter is invalid
+ *
+ ****************************************************************************/
+
+struct stm32_ltdc_s; // fwd decl
+
+FAR struct dma2d_layer_s *stm32_dma2dinitltdc(FAR struct stm32_ltdc_s *layer);
+# endif /* CONFIG_STM32F7_LTDC_INTERFACE */
+
+#endif /* CONFIG_STM32F7_DMA2D */
+#endif /* __ARCH_ARM_SRC_STM32F7_STM32_DMA2D_H */
diff --git a/arch/arm/src/stm32f7/stm32_ltdc.c b/arch/arm/src/stm32f7/stm32_ltdc.c
new file mode 100644
index 00000000000..36c1d628f61
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_ltdc.c
@@ -0,0 +1,3627 @@
+/****************************************************************************
+ * arch/arm/src/stm32/stm32_ltdc.c
+ *
+ * Copyright (C) 2013-2015 Ken Pettit. All rights reserved.
+ * Authors: Ken Pettit
+ * Marco Krahl
+ *
+ * References:
+ * STM32F429 Technical Reference Manual and Data Sheet
+ *
+ * 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
+
+#include "up_arch.h"
+#include "up_internal.h"
+#include "chip/stm32_ltdc.h"
+#include "stm32_ltdc.h"
+#include "stm32_dma2d.h"
+#include "stm32_gpio.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Register definition ******************************************************/
+
+#ifndef BOARD_LTDC_WIDTH
+# error BOARD_LTDC_WIDTH must be defined in the board.h header file
+#endif
+
+#ifndef BOARD_LTDC_HEIGHT
+# error BOARD_LTDC_HEIGHT must be defined in the board.h header file
+#endif
+
+#define STM32_LTDC_HEIGHT BOARD_LTDC_HEIGHT
+#define STM32_LTDC_WIDTH BOARD_LTDC_WIDTH
+
+/* Configure LTDC register */
+
+/* LTDC_LxWHPCR register */
+
+#define STM32_LTDC_LxWHPCR_WHSTPOS (BOARD_LTDC_HSYNC + BOARD_LTDC_HBP - 1)
+#define STM32_LTDC_LxWHPCR_WHSPPOS (BOARD_LTDC_HSYNC + BOARD_LTDC_HBP + \
+ STM32_LTDC_WIDTH - 1)
+
+/* LTDC_LxWVPCR register */
+
+#define STM32_LTDC_LxWVPCR_WVSTPOS (BOARD_LTDC_VSYNC + BOARD_LTDC_VBP - 1)
+#define STM32_LTDC_LxWVPCR_WVSPPOS (BOARD_LTDC_VSYNC + BOARD_LTDC_VBP + \
+ STM32_LTDC_HEIGHT - 1)
+
+/* LTDC_SSCR register */
+
+#define STM32_LTDC_SSCR_VSH LTDC_SSCR_VSH(BOARD_LTDC_VSYNC - 1)
+#define STM32_LTDC_SSCR_HSW LTDC_SSCR_HSW(BOARD_LTDC_HSYNC - 1)
+
+/* LTDC_BPCR register */
+
+#define STM32_LTDC_BPCR_AVBP LTDC_BPCR_AVBP(STM32_LTDC_LxWVPCR_WVSTPOS)
+#define STM32_LTDC_BPCR_AHBP LTDC_BPCR_AHBP(STM32_LTDC_LxWHPCR_WHSTPOS)
+
+/* LTDC_AWCR register */
+
+#define STM32_LTDC_AWCR_AAH LTDC_AWCR_AAH(STM32_LTDC_LxWVPCR_WVSPPOS)
+#define STM32_LTDC_AWCR_AAW LTDC_AWCR_AAW(STM32_LTDC_LxWHPCR_WHSPPOS)
+
+/* LTDC_TWCR register */
+
+#define STM32_LTDC_TWCR_TOTALH LTDC_TWCR_TOTALH(BOARD_LTDC_VSYNC + \
+ BOARD_LTDC_VBP + \
+ STM32_LTDC_HEIGHT + BOARD_LTDC_VFP - 1)
+#define STM32_LTDC_TWCR_TOTALW LTDC_TWCR_TOTALW(BOARD_LTDC_HSYNC + \
+ BOARD_LTDC_HBP + \
+ STM32_LTDC_WIDTH + BOARD_LTDC_HFP - 1)
+
+/* Global GCR register */
+
+/* Synchronisation and Polarity */
+
+#define STM32_LTDC_GCR_PCPOL BOARD_LTDC_GCR_PCPOL
+#define STM32_LTDC_GCR_DEPOL BOARD_LTDC_GCR_DEPOL
+#define STM32_LTDC_GCR_VSPOL BOARD_LTDC_GCR_VSPOL
+#define STM32_LTDC_GCR_HSPOL BOARD_LTDC_GCR_HSPOL
+
+/* Dither */
+
+#define STM32_LTDC_GCR_DEN BOARD_LTDC_GCR_DEN
+#define STM32_LTDC_GCR_DBW LTDC_GCR_GBW(BOARD_LTDC_GCR_DBW)
+#define STM32_LTDC_GCR_DGW LTDC_GCR_DGW(BOARD_LTDC_GCR_DGW)
+#define STN32_LTDC_GCR_DRW LTDC_GCR_DBW(BOARD_LTDC_GCR_DRW)
+
+/* LIPCR register */
+
+#define STM32_LTDC_LIPCR_LIPOS LTDC_LIPCR_LIPOS(STM32_LTDC_TWCR_TOTALW)
+
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_STM32F7_LTDC_DEFBACKLIGHT
+# define CONFIG_STM32F7_LTDC_DEFBACKLIGHT 0xf0
+#endif
+#define STM32_LTDC_BACKLIGHT_OFF 0x00
+
+/* Color/video formats */
+
+/* Layer 1 format */
+
+#if defined(CONFIG_STM32F7_LTDC_L1_L8)
+# define STM32_LTDC_L1_BPP 8
+# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB8
+# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_L8)
+# define STM32_LTDC_L1CMAP
+#elif defined(CONFIG_STM32F7_LTDC_L1_AL44)
+# define STM32_LTDC_L1_BPP 8
+# define STM32_LTDC_L1_COLOR_FMT ???
+# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_AL44)
+#elif defined(CONFIG_STM32F7_LTDC_L1_AL88)
+# define STM32_LTDC_L1_BPP 16
+# define STM32_LTDC_L1_COLOR_FMT ???
+# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_AL88)
+#elif defined(CONFIG_STM32F7_LTDC_L1_ARGB4444)
+# define STM32_LTDC_L1_BPP 16
+# define STM32_LTDC_L1_COLOR_FMT ???
+# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB4444)
+#elif defined(CONFIG_STM32F7_LTDC_L1_RGB565)
+# define STM32_LTDC_L1_BPP 16
+# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB16_565
+# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_RGB565)
+#elif defined(CONFIG_STM32F7_LTDC_L1_ARGB1555)
+# define STM32_LTDC_L1_BPP 16
+# define STM32_LTDC_L1_COLOR_FMT ???
+# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB1555)
+#elif defined(CONFIG_STM32F7_LTDC_L1_RGB888)
+# define STM32_LTDC_L1_BPP 24
+# define STM32_LTDC_L1_COLOR_FMT FB_FMT_RGB24
+# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_RGB888)
+#elif defined(CONFIG_STM32F7_LTDC_L1_ARGB8888)
+# define STM32_LTDC_L1_BPP 32
+# define STM32_LTDC_L1_COLOR_FMT ???
+# define STM32_LTDC_L1PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB8888)
+#endif
+
+/* Layer 2 format */
+
+#if defined(CONFIG_STM32F7_LTDC_L2_L8)
+# define STM32_LTDC_L2_BPP 8
+# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB8
+# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_L8)
+# define STM32_LTDC_L2CMAP
+#elif defined(CONFIG_STM32F7_LTDC_L2_AL44)
+# define STM32_LTDC_L2_BPP 8
+# define STM32_LTDC_L2_COLOR_FMT ???
+# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_AL44)
+#elif defined(CONFIG_STM32F7_LTDC_L2_AL88)
+# define STM32_LTDC_L2_BPP 16
+# define STM32_LTDC_L2_COLOR_FMT ???
+# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_AL88)
+#elif defined(CONFIG_STM32F7_LTDC_L2_ARGB4444)
+# define STM32_LTDC_L2_BPP 16
+# define STM32_LTDC_L2_COLOR_FMT ???
+# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB4444)
+#elif defined(CONFIG_STM32F7_LTDC_L2_RGB565)
+# define STM32_LTDC_L2_BPP 16
+# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB16_565
+# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_RGB565)
+#elif defined(CONFIG_STM32F7_LTDC_L2_ARGB1555)
+# define STM32_LTDC_L2_BPP 16
+# define STM32_LTDC_L2_COLOR_FMT ???
+# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB1555)
+#elif defined(CONFIG_STM32F7_LTDC_L2_RGB888)
+# define STM32_LTDC_L2_BPP 24
+# define STM32_LTDC_L2_COLOR_FMT FB_FMT_RGB24
+# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_RGB888)
+#elif defined(CONFIG_STM32F7_LTDC_L2_ARGB8888)
+# define STM32_LTDC_L2_BPP 32
+# define STM32_LTDC_L2_COLOR_FMT ???
+# define STM32_LTDC_L2PFCR_PF LTDC_LxPFCR_PF(LTDC_PF_ARGB8888)
+#endif
+
+/* Framebuffer sizes in bytes */
+
+#if STM32_LTDC_L1_BPP == 8
+# define STM32_L1_STRIDE (STM32_LTDC_WIDTH)
+#elif STM32_LTDC_L1_BPP == 16
+# define STM32_L1_STRIDE ((STM32_LTDC_WIDTH * 16 + 7) / 8)
+#elif STM32_LTDC_L1_BPP == 24
+# define STM32_L1_STRIDE ((STM32_LTDC_WIDTH * 24 + 7) / 8)
+#elif STM32_LTDC_L1_BPP == 32
+# define STM32_L1_STRIDE ((STM32_LTDC_WIDTH * 32 + 7) / 8)
+#else
+# error Undefined or unrecognized base resolution
+#endif
+
+/* LTDC only supports 8 bit per pixel overal */
+
+#define STM32_LTDC_Lx_BYPP(n) ((n) / 8)
+
+#define STM32_L1_FBSIZE (STM32_L1_STRIDE * STM32_LTDC_HEIGHT)
+
+#ifdef CONFIG_STM32F7_LTDC_L2
+# ifndef CONFIG_STM32F7_LTDC_L2_WIDTH
+# define CONFIG_STM32F7_LTDC_L2_WIDTH STM32_LTDC_WIDTH
+# endif
+
+# if CONFIG_STM32F7_LTDC_L2_WIDTH > STM32_LTDC_WIDTH
+# error Width of Layer 2 exceeds the width of the display
+# endif
+
+# ifndef CONFIG_STM32F7_LTDC_L2_HEIGHT
+# define CONFIG_STM32F7_LTDC_L2_HEIGHT STM32_LTDC_HEIGHT
+# endif
+
+# if CONFIG_STM32F7_LTDC_L2_HEIGHT > STM32_LTDC_HEIGHT
+# error Height of Layer 2 exceeds the height of the display
+# endif
+
+# if STM32_LTDC_L2_BPP == 8
+# define STM32_L2_STRIDE (CONFIG_STM32F7_LTDC_L2_WIDTH)
+# elif STM32_LTDC_L2_BPP == 16
+# define STM32_L2_STRIDE ((CONFIG_STM32F7_LTDC_L2_WIDTH * 16 + 7) / 8)
+# elif STM32_LTDC_L2_BPP == 24
+# define STM32_L2_STRIDE ((CONFIG_STM32F7_LTDC_L2_WIDTH * 24 + 7) / 8)
+# elif STM32_LTDC_L2_BPP == 32
+# define STM32_L2_STRIDE ((CONFIG_STM32F7_LTDC_L2_WIDTH * 32 + 7) / 8)
+# else
+# error Undefined or unrecognized base resolution
+# endif
+
+# define STM32_L2_FBSIZE (STM32_L2_STRIDE * CONFIG_STM32F7_LTDC_L2_HEIGHT)
+
+#else
+# define STM32_L2_FBSIZE (0)
+#endif
+
+/* Total memory used for framebuffers */
+
+#define STM32_TOTAL_FBSIZE (STM32_L1_FBSIZE + STM32_L2_FBSIZE)
+
+/* Debug option */
+
+#ifdef CONFIG_STM32F7_LTDC_REGDEBUG
+# define regerr lcderr
+# define reginfo lcdinfo
+#else
+# define regerr(x...)
+# define reginfo(x...)
+#endif
+
+/* Preallocated LTDC framebuffers */
+
+/* Position the framebuffer memory in the center of the memory set aside. We
+ * will use any skirts before or after the framebuffer memory as a guard against
+ * wild framebuffer writes.
+ */
+
+#define STM32_LTDC_BUFFER_SIZE CONFIG_STM32F7_LTDC_FB_SIZE
+#define STM32_LTDC_BUFFER_FREE (STM32_LTDC_BUFFER_SIZE - STM32_TOTAL_FBSIZE)
+#define STM32_LTDC_BUFFER_START (CONFIG_STM32F7_LTDC_FB_BASE + \
+ STM32_LTDC_BUFFER_FREE/2)
+
+#if STM32_LTDC_BUFFER_FREE < 0
+# error "STM32_LTDC_BUFFER_SIZE not large enough for frame buffers"
+#endif
+
+/* Layer frame buffer */
+
+#define STM32_LTDC_BUFFER_L1 STM32_LTDC_BUFFER_START
+#define STM32_LTDC_ENDBUF_L1 (STM32_LTDC_BUFFER_L1 + STM32_L1_FBSIZE)
+
+#ifdef CONFIG_STM32F7_LTDC_L2
+# define STM32_LTDC_BUFFER_L2 STM32_LTDC_ENDBUF_L1
+# define STM32_LTDC_ENDBUF_L2 (STM32_LTDC_BUFFER_L2 + STM32_L2_FBSIZE)
+#else
+# define STM32_LTDC_ENDBUF_L2 STM32_LTDC_ENDBUF_L1
+#endif
+
+/* Layer helpers */
+
+#ifdef CONFIG_STM32F7_LTDC_L2
+# define LTDC_NLAYERS 2
+#else
+# define LTDC_NLAYERS 1
+#endif
+
+#define LAYER(i) g_ltdc.layer[i]
+#define LAYER_L1 g_ltdc.layer[LTDC_LAYER_L1]
+#define LAYER_L2 g_ltdc.layer[LTDC_LAYER_L2]
+
+/* Dithering */
+
+#ifndef CONFIG_STM32F7_LTDC_DITHER_RED
+# define STM32_LTDC_DITHER_RED 0
+#else
+# define STM32_LTDC_DITHER_RED CONFIG_STM32F7_LTDC_DITHER_RED
+#endif
+#ifndef CONFIG_STM32F7_LTDC_DITHER_GREEN
+# define STM32_LTDC_DITHER_GREEN 0
+#else
+# define STM32_LTDC_DITHER_GREEN CONFIG_STM32F7_LTDC_DITHER_GREEN
+#endif
+#ifndef CONFIG_STM32F7_LTDC_DITHER_BLUE
+# define STM32_LTDC_DITHER_BLUE 0
+#else
+# define STM32_LTDC_DITHER_BLUE CONFIG_STM32F7_LTDC_DITHER_BLUE
+#endif
+
+/* Background color */
+
+#ifndef CONFIG_STM32F7_LTDC_BACKCOLOR
+# define STM32_LTDC_BACKCOLOR 0
+#else
+# define STM32_LTDC_BACKCOLOR CONFIG_STM32F7_LTDC_BACKCOLOR
+#endif
+
+/* Internal operation flags */
+
+#define LTDC_LAYER_SETAREA (1 << 0) /* Change visible area */
+#define LTDC_LAYER_SETALPHAVALUE (1 << 1) /* Change constant alpha value */
+#define LTDC_LAYER_SETBLENDMODE (1 << 2) /* Change blendmode */
+#define LTDC_LAYER_SETCOLORKEY (1 << 3) /* Change color key */
+#define LTDC_LAYER_ENABLECOLORKEY (1 << 4) /* Enable colorkey */
+#define LTDC_LAYER_SETCOLOR (1 << 5) /* Change default color */
+#define LTDC_LAYER_SETENABLE (1 << 6) /* Change enabled state */
+#define LTDC_LAYER_ENABLE (1 << 7) /* Enable the layer */
+
+/* Layer initializing state */
+
+#define LTDC_LAYER_INIT LTDC_LAYER_SETAREA | \
+ LTDC_LAYER_SETALPHAVALUE | \
+ LTDC_LAYER_SETBLENDMODE | \
+ LTDC_LAYER_SETCOLORKEY | \
+ LTDC_LAYER_SETCOLOR | \
+ LTDC_LAYER_SETENABLE | \
+ LTDC_LAYER_ENABLE
+
+/* Blendfactor reset values for flip operation */
+
+#define STM32_LTDC_BF1_RESET 6
+#define STM32_LTDC_BF2_RESET 7
+
+/* Check pixel format support by DMA2D driver */
+
+#ifdef CONFIG_STM32F7_DMA2D
+# if defined(CONFIG_STM32F7_LTDC_L1_L8) || \
+ defined(CONFIG_STM32F7_LTDC_L2_L8)
+# if !defined(CONFIG_STM32F7_DMA2D_L8)
+# error "DMA2D must support FB_FMT_RGB8 pixel format"
+# endif
+# endif
+# if defined(CONFIG_STM32F7_LTDC_L1_RGB565) || \
+ defined(CONFIG_STM32F7_LTDC_L2_RGB565)
+# if !defined(CONFIG_STM32F7_DMA2D_RGB565)
+# error "DMA2D must support FB_FMT_RGB16_565 pixel format"
+# endif
+# endif
+# if defined(CONFIG_STM32F7_LTDC_L1_RGB888) || \
+ defined(CONFIG_STM32F7_LTDC_L2_RGB888)
+# if !defined(CONFIG_STM32F7_DMA2D_RGB888)
+# error "DMA2D must support FB_FMT_RGB24 pixel format"
+# endif
+# endif
+#endif
+
+/* Calculate the size of the layers clut table */
+
+#ifdef CONFIG_FB_CMAP
+# if defined(CONFIG_STM32F7_DMA2D) && !defined(CONFIG_STM32F7_DMA2D_L8)
+# error "DMA2D must also support L8 CLUT pixel format if supported by LTDC"
+# endif
+# ifdef STM32_LTDC_L1CMAP
+# ifdef CONFIG_FB_TRANSPARENCY
+# define STM32_LAYER_CLUT_SIZE STM32_LTDC_NCLUT * sizeof(uint32_t)
+# else
+# define STM32_LAYER_CLUT_SIZE STM32_LTDC_NCLUT * 3 * sizeof(uint8_t)
+# endif
+# endif
+# ifdef STM32_LTDC_L2CMAP
+# undef STM32_LAYER_CLUT_SIZE
+# ifdef CONFIG_FB_TRANSPARENCY
+# define STM32_LAYER_CLUT_SIZE STM32_LTDC_NCLUT * sizeof(uint32_t) * 2
+# else
+# define STM32_LAYER_CLUT_SIZE STM32_LTDC_NCLUT * 3 * sizeof(uint8_t) * 2
+# endif
+# endif
+#endif
+
+#ifndef CONFIG_FB_CMAP
+# if defined(STM32_LTDC_L1CMAP) || defined(STM32_LTDC_L2CMAP)
+# undef STM32_LTDC_L1CMAP
+# undef STM32_LTDC_L2CMAP
+# error "Enable cmap to support the configured layer format!"
+# endif
+#endif
+
+/* Layer clut rgb value positioning */
+
+#define LTDC_L1CLUT_REDOFFSET 0
+#define LTDC_L1CLUT_GREENOFFSET 256
+#define LTDC_L1CLUT_BLUEOFFSET 512
+#define LTDC_L2CLUT_REDOFFSET 768
+#define LTDC_L2CLUT_GREENOFFSET 1024
+#define LTDC_L2CLUT_BLUEOFFSET 1280
+
+/* Layer argb clut register position */
+
+#define LTDC_CLUT_ADD(n) ((uint32_t)(n) << 24)
+#define LTDC_CLUT_ALPHA(n) LTDC_CLUT_ADD(n)
+#define LTDC_CLUT_RED(n) ((uint32_t)(n) << 16)
+#define LTDC_CLUT_GREEN(n) ((uint32_t)(n) << 8)
+#define LTDC_CLUT_BLUE(n) ((uint32_t)(n) << 0)
+#define LTDC_CLUT_RGB888_MASK 0xffffff
+
+/* Layer argb cmap conversion */
+
+#define LTDC_CMAP_ALPHA(n) ((uint32_t)(n) >> 24)
+#define LTDC_CMAP_RED(n) ((uint32_t)(n) >> 16)
+#define LTDC_CMAP_GREEN(n) ((uint32_t)(n) >> 8)
+#define LTDC_CMAP_BLUE(n) ((uint32_t)(n) >> 0)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* This enumeration names each layer supported by the hardware */
+
+enum stm32_layer_e
+{
+ LTDC_LAYER_L1 = 0, /* LCD Layer 1 */
+ LTDC_LAYER_L2, /* LCD Layer 2 */
+};
+
+/* LTDC General layer information */
+
+struct stm32_layer_s
+{
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+ /* LTDC interface */
+
+ struct ltdc_layer_s ltdc; /* Layer control structure */
+#endif
+
+ struct stm32_ltdc_s state; /* Layer state structure */
+
+ /* Blending */
+
+ uint8_t opac; /* Opacity value for blending */
+ uint8_t bf1; /* Blend factor 1 */
+ uint8_t bf2; /* Blend factor 2 */
+
+ /* Operation */
+
+ uint8_t operation; /* Operation flags */
+#ifdef CONFIG_STM32F7_DMA2D
+ FAR struct dma2d_layer_s *dma2d; /* dma2d interface */
+#endif
+};
+
+/* This structure provides the state of each LTDC layer */
+
+struct stm32_state_s
+{
+ /* Layer state */
+
+ struct stm32_ltdc_s state[LTDC_NLAYERS];
+};
+
+/* This structure provides the overall state of the LTDC layer */
+
+struct stm32_ltdcdev_s
+{
+ /* Layer information */
+
+ struct stm32_layer_s layer[LTDC_NLAYERS];
+};
+
+/* Layer cmap table description */
+
+#ifdef STM32_LAYER_CLUT_SIZE
+enum stm32_clut_e
+{
+ LTDC_L1CLUT_OFFSET = 0,
+ LTDC_L2CLUT_OFFSET = STM32_LTDC_NCLUT * sizeof(uint32_t)
+};
+#endif
+
+/* Interrupt handling */
+
+struct stm32_interrupt_s
+{
+ bool wait; /* Informs that the task is waiting for the irq */
+ bool handled; /* Informs that an irq was handled */
+ int irq; /* irq number */
+ sem_t *sem; /* Semaphore for waiting for irq */
+};
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Global register operation */
+
+static void stm32_lcd_enable(bool enable);
+#if !defined(CONFIG_STM32F7_LTDC_USE_DSI)
+static void stm32_ltdc_gpioconfig(void);
+#endif
+static void stm32_ltdc_periphconfig(void);
+static void stm32_ltdc_bgcolor(uint32_t rgb);
+static void stm32_ltdc_dither(bool enable, uint8_t red,
+ uint8_t green, uint8_t blue);
+static int stm32_ltdcirq(int irq, void *context, FAR void *arg);
+static int stm32_ltdc_waitforirq(void);
+static int stm32_ltdc_reload(uint8_t value, bool waitvblank);
+
+/* Layer and layer register operation */
+
+static inline void stm32_ltdc_lsetopac(FAR struct stm32_layer_s *layer);
+static inline void stm32_ltdc_lunsetopac(FAR struct stm32_layer_s *layer);
+static inline uint8_t stm32_ltdc_lgetopac(FAR struct stm32_layer_s *layer);
+static inline bool stm32_ltdc_lvalidate(FAR const struct stm32_layer_s *layer);
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+static int stm32_ltdc_lvalidatearea(FAR struct stm32_layer_s *layer,
+ fb_coord_t xpos, fb_coord_t ypos,
+ fb_coord_t xres, fb_coord_t yres,
+ fb_coord_t srcxpos, fb_coord_t srcypos);
+#endif
+static void stm32_ltdc_lupdate(FAR struct stm32_layer_s *layer);
+
+static void stm32_ltdc_lpixelformat(FAR struct stm32_layer_s *layer);
+static inline void stm32_ltdc_lframebuffer(FAR struct stm32_layer_s *layer);
+static void stm32_ltdc_larea(FAR struct stm32_layer_s *layer);
+static void stm32_ltdc_lcolor(FAR struct stm32_layer_s *layer, uint32_t argb);
+static void stm32_ltdc_lcolorkey(FAR struct stm32_layer_s *layer);
+static void stm32_ltdc_lalpha(FAR struct stm32_layer_s *layer);
+static void stm32_ltdc_lblendmode(FAR struct stm32_layer_s *layer,
+ uint8_t bf1, uint8_t bf2);
+
+#ifdef STM32_LAYER_CLUT_SIZE
+static void stm32_ltdc_lclut(FAR struct stm32_layer_s *layer,
+ FAR const struct fb_cmap_s *cmap);
+static void stm32_ltdc_lclutenable(FAR struct stm32_layer_s *layer,
+ bool enable);
+#endif
+static void stm32_ltdc_linit(int lid);
+static void stm32_ltdc_lenable(FAR struct stm32_layer_s *layer);
+static void stm32_ltdc_lclear(FAR struct stm32_layer_s *layer,
+ nxgl_mxpixel_t color);
+
+/* Generic frame buffer interface */
+
+static int stm32_getvideoinfo(FAR struct fb_vtable_s *vtable,
+ struct fb_videoinfo_s *vinfo);
+static int stm32_getplaneinfo(FAR struct fb_vtable_s *vtable,
+ int planeno, struct fb_planeinfo_s *pinfo);
+
+/* The following is provided only if the video hardware supports RGB color
+ * mapping
+ */
+
+#ifdef STM32_LAYER_CLUT_SIZE
+static int stm32_getcmap(struct fb_vtable_s *vtable,
+ struct fb_cmap_s *cmap);
+static int stm32_putcmap(struct fb_vtable_s *vtable,
+ const struct fb_cmap_s *cmap);
+#endif
+
+/* ltdc interface */
+
+#ifdef STM32_LAYER_CLUT_SIZE
+static int stm32_setclut(struct ltdc_layer_s *layer,
+ const struct fb_cmap_s *cmap);
+static int stm32_getclut(struct ltdc_layer_s *layer,
+ struct fb_cmap_s *cmap);
+#endif
+static int stm32_lgetvideoinfo(struct ltdc_layer_s *layer,
+ struct fb_videoinfo_s *vinfo);
+static int stm32_lgetplaneinfo(struct ltdc_layer_s *layer, int planeno,
+ struct fb_planeinfo_s *pinfo);
+
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+static int stm32_getlid(FAR struct ltdc_layer_s *layer,
+ int *lid, uint32_t flag);
+static int stm32_setcolor(FAR struct ltdc_layer_s *layer, uint32_t argb);
+static int stm32_getcolor(FAR struct ltdc_layer_s *layer, uint32_t *argb);
+static int stm32_setcolorkey(FAR struct ltdc_layer_s *layer, uint32_t argb);
+static int stm32_getcolorkey(FAR struct ltdc_layer_s *layer, uint32_t *argb);
+static int stm32_setalpha(FAR struct ltdc_layer_s *layer, uint8_t alpha);
+static int stm32_getalpha(FAR struct ltdc_layer_s *layer, uint8_t *alpha);
+static int stm32_setblendmode(FAR struct ltdc_layer_s *layer, uint32_t mode);
+static int stm32_getblendmode(FAR struct ltdc_layer_s *layer, uint32_t *mode);
+static int stm32_setarea(FAR struct ltdc_layer_s *layer,
+ FAR const struct ltdc_area_s *area,
+ fb_coord_t srcxpos, fb_coord_t srcypos);
+static int stm32_getarea(FAR struct ltdc_layer_s *layer,
+ FAR struct ltdc_area_s *area,
+ fb_coord_t *srcxpos, fb_coord_t *srcypos);
+static int stm32_update(FAR struct ltdc_layer_s *layer, uint32_t mode);
+
+#ifdef CONFIG_STM32F7_DMA2D
+static int stm32_blit(FAR struct ltdc_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *src,
+ FAR const struct ltdc_area_s *srcarea);
+static int stm32_blend(FAR struct ltdc_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *fore,
+ fb_coord_t forexpos, fb_coord_t foreypos,
+ FAR const struct dma2d_layer_s *back,
+ FAR const struct ltdc_area_s *backarea);
+static int stm32_fillarea(FAR struct ltdc_layer_s *layer,
+ FAR const struct ltdc_area_s *area,
+ uint32_t color);
+#endif
+#endif /* CONFIG_STM32F7_LTDC_INTERFACE */
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+#if !defined(CONFIG_STM32F7_LTDC_USE_DSI)
+/* PIO pin configurations */
+
+static const uint32_t g_ltdcpins[] =
+{
+ GPIO_LTDC_R4, GPIO_LTDC_R5, GPIO_LTDC_R6, GPIO_LTDC_R7,
+ GPIO_LTDC_G4, GPIO_LTDC_G5, GPIO_LTDC_G6, GPIO_LTDC_G7,
+ GPIO_LTDC_B4, GPIO_LTDC_B5, GPIO_LTDC_B6, GPIO_LTDC_B7,
+#if BOARD_LTDC_OUTPUT_BPP > 12
+ GPIO_LTDC_R3, GPIO_LTDC_G2, GPIO_LTDC_G3, GPIO_LTDC_B3,
+# if BOARD_LTDC_OUTPUT_BPP > 16
+ GPIO_LTDC_R2, GPIO_LTDC_B2,
+# if BOARD_LTDC_OUTPUT_BPP > 18
+ GPIO_LTDC_R0, GPIO_LTDC_R1, GPIO_LTDC_G0, GPIO_LTDC_G1,
+ GPIO_LTDC_B0, GPIO_LTDC_B1,
+# endif
+# endif
+#endif
+ GPIO_LTDC_VSYNC, GPIO_LTDC_HSYNC, GPIO_LTDC_DE, GPIO_LTDC_CLK
+};
+
+#define STM32_LTDC_NPINCONFIGS (sizeof(g_ltdcpins) / sizeof(uint32_t))
+#endif /* !CONFIG_STM32F7_LTDC_USE_DSI */
+
+/* This structure provides the base layer interface */
+
+static const struct fb_vtable_s g_vtable =
+{
+ .getvideoinfo = stm32_getvideoinfo,
+ .getplaneinfo = stm32_getplaneinfo
+#ifdef STM32_LAYER_CLUT_SIZE
+ ,
+ .getcmap = stm32_getcmap,
+ .putcmap = stm32_putcmap
+#endif
+};
+
+/* The LTDC semaphore that enforces mutually exclusive access */
+
+static sem_t g_lock;
+
+/* The semaphore for interrupt handling */
+
+static sem_t g_semirq;
+
+/* This structure provides irq handling */
+
+static struct stm32_interrupt_s g_interrupt =
+{
+ .wait = false,
+ .handled = true,
+ .irq = STM32_IRQ_LTDCINT,
+ .sem = &g_semirq
+};
+
+/* The layer active state */
+
+static uint8_t g_lactive;
+
+#ifdef STM32_LAYER_CLUT_SIZE
+/* The layers clut table entries */
+
+static uint32_t g_clut[STM32_LAYER_CLUT_SIZE];
+#endif
+
+/* The initialized state of the overall LTDC layers */
+
+static struct stm32_ltdcdev_s g_ltdc =
+{
+ .layer[LTDC_LAYER_L1] =
+ {
+ .state =
+ {
+ .lid = LTDC_LAYER_L1,
+ .pinfo =
+ {
+ .fbmem = (uint8_t *)STM32_LTDC_BUFFER_L1,
+ .fblen = STM32_L1_FBSIZE,
+ .stride = STM32_L1_STRIDE,
+ .display = 0,
+ .bpp = STM32_LTDC_L1_BPP
+ },
+ .vinfo =
+ {
+ .fmt = STM32_LTDC_L1_COLOR_FMT,
+ .xres = STM32_LTDC_WIDTH,
+ .yres = STM32_LTDC_HEIGHT,
+ .nplanes = 1
+ }
+#ifdef STM32_LTDC_L1CMAP
+ , .clut = &g_clut[LTDC_L1CLUT_OFFSET]
+#endif
+ }
+ }
+#ifdef CONFIG_STM32F7_LTDC_L2
+ ,
+ .layer[LTDC_LAYER_L2] =
+ {
+ .state =
+ {
+ .lid = LTDC_LAYER_L2,
+ .pinfo =
+ {
+ .fbmem = (uint8_t *)STM32_LTDC_BUFFER_L2,
+ .fblen = STM32_L2_FBSIZE,
+ .stride = STM32_L2_STRIDE,
+ .display = 1,
+ .bpp = STM32_LTDC_L2_BPP
+ },
+ .vinfo =
+ {
+ .fmt = STM32_LTDC_L2_COLOR_FMT,
+ .xres = STM32_LTDC_WIDTH,
+ .yres = STM32_LTDC_HEIGHT,
+ .nplanes = 1
+ }
+#ifdef STM32_LTDC_L2CMAP
+ , .clut = &g_clut[LTDC_L2CLUT_OFFSET]
+#endif
+ }
+ }
+#endif
+};
+
+/* Pixel format lookup table */
+
+static const uint32_t stm32_fmt_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1PFCR_PF
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2PFCR_PF
+#endif
+};
+
+/* Register lookup tables */
+
+/* LTDC_LxCR */
+
+static const uintptr_t stm32_cr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1CR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2CR
+#endif
+};
+
+/* LTDC_LxWHPCR */
+
+static const uintptr_t stm32_whpcr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1WHPCR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2WHPCR
+#endif
+};
+
+/* LTDC_LxWVPCR */
+
+static const uintptr_t stm32_wvpcr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1WVPCR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2WVPCR
+#endif
+};
+
+/* LTDC_LxPFCR */
+
+static const uintptr_t stm32_pfcr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1PFCR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2PFCR
+#endif
+};
+
+/* LTDC_LxDCCR */
+
+static const uintptr_t stm32_dccr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1DCCR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2DCCR
+#endif
+};
+
+/* LTDC_LxCKCR */
+
+static const uintptr_t stm32_ckcr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1CKCR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2CKCR
+#endif
+};
+
+/* LTDC_LxCACR */
+
+static const uintptr_t stm32_cacr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1CACR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2CACR
+#endif
+};
+
+/* LTDC_LxBFCR */
+
+static const uintptr_t stm32_bfcr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1BFCR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2BFCR
+#endif
+};
+
+/* LTDC_LxCFBAR */
+
+static const uintptr_t stm32_cfbar_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1CFBAR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2CFBAR
+#endif
+};
+
+/* LTDC_LxCFBLR */
+
+static const uintptr_t stm32_cfblr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1CFBLR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2CFBLR
+#endif
+};
+
+/* LTDC_LxCFBLNR */
+
+static const uintptr_t stm32_cfblnr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1CFBLNR
+#ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2CFBLNR
+#endif
+};
+
+/* LTDC_LxCLUTWR */
+
+#ifdef STM32_LAYER_CLUT_SIZE
+static const uintptr_t stm32_clutwr_layer_t[LTDC_NLAYERS] =
+{
+ STM32_LTDC_L1CLUTWR
+# ifdef CONFIG_STM32F7_LTDC_L2
+ , STM32_LTDC_L2CLUTWR
+# endif
+};
+#endif
+
+/* The initialized state of the driver */
+
+static bool g_initialized;
+
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_ltdc_gpioconfig
+ *
+ * Description:
+ * Configure GPIO pins for use with the LTDC
+ *
+ ****************************************************************************/
+
+#if !defined(CONFIG_STM32F7_LTDC_USE_DSI)
+static void stm32_ltdc_gpioconfig(void)
+{
+ int i;
+
+ lcdinfo("Configuring pins\n");
+
+ /* Configure each pin */
+
+ for (i = 0; i < STM32_LTDC_NPINCONFIGS; i++)
+ {
+ reginfo("set gpio%d = %08x\n", i, g_ltdcpins[i]);
+ stm32_configgpio(g_ltdcpins[i]);
+ }
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_ltdc_periphconfig
+ *
+ * Description:
+ * Configures the synchronous timings
+ * Configures the synchronous signals and clock polarity
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_periphconfig(void)
+{
+ uint32_t regval;
+
+#if defined(CONFIG_STM32F7_LTDC_USE_DSI)
+ /* work in progress; maybe move to lcdinfo when everything is OK. */
+ lcdwarn("LTDC: Expecting preconfigured DSI; not configuring pins for LCD interface\n");
+#else
+ /* Configure GPIO's */
+ stm32_ltdc_gpioconfig();
+#endif
+
+ /* Configure APB2 LTDC clock external */
+
+ reginfo("configured RCC_APB2ENR=%08x\n", getreg32(STM32_RCC_APB2ENR));
+
+ /* Configure the SAI PLL external to provide the LCD_CLK */
+
+ reginfo("configured RCC_PLLSAI=%08x\n", getreg32(STM32_RCC_PLLSAICFGR));
+
+ /* Configure dedicated clock external */
+
+ reginfo("configured RCC_DCKCFGR=%08x\n", getreg32(STM32_RCC_DCKCFGR));
+
+ /* Configure LTDC_SSCR */
+
+ regval = (STM32_LTDC_SSCR_VSH | STM32_LTDC_SSCR_HSW);
+ reginfo("set LTDC_SSCR=%08x\n", regval);
+ putreg32(regval, STM32_LTDC_SSCR);
+ reginfo("configured LTDC_SSCR=%08x\n", getreg32(STM32_LTDC_SSCR));
+
+ /* Configure LTDC_BPCR */
+
+ regval = (STM32_LTDC_BPCR_AVBP | STM32_LTDC_BPCR_AHBP);
+ reginfo("set LTDC_BPCR=%08x\n", regval);
+ putreg32(regval, STM32_LTDC_BPCR);
+ reginfo("configured LTDC_BPCR=%08x\n", getreg32(STM32_LTDC_BPCR));
+
+ /* Configure LTDC_AWCR */
+
+ regval = (STM32_LTDC_AWCR_AAH | STM32_LTDC_AWCR_AAW);
+ reginfo("set LTDC_AWCR=%08x\n", regval);
+ putreg32(regval, STM32_LTDC_AWCR);
+ reginfo("configured LTDC_AWCR=%08x\n", getreg32(STM32_LTDC_AWCR));
+
+ /* Configure LTDC_TWCR */
+
+ regval = (STM32_LTDC_TWCR_TOTALH | STM32_LTDC_TWCR_TOTALW);
+ reginfo("set LTDC_TWCR=%08x\n", regval);
+ putreg32(regval, STM32_LTDC_TWCR);
+ reginfo("configured LTDC_TWCR=%08x\n", getreg32(STM32_LTDC_TWCR));
+
+ /* Configure LTDC_GCR */
+
+ regval = (STM32_LTDC_GCR_PCPOL | STM32_LTDC_GCR_DEPOL
+ | STM32_LTDC_GCR_VSPOL | STM32_LTDC_GCR_HSPOL);
+ reginfo("set LTDC_GCR=%08x\n", regval);
+ putreg32(regval, STM32_LTDC_GCR);
+ reginfo("configured LTDC_GCR=%08x\n", getreg32(STM32_LTDC_GCR));
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_bgcolor
+ *
+ * Description:
+ * Configures background color of the LCD controller.
+ *
+ * Parameter:
+ * rgb - RGB888 background color
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_bgcolor(uint32_t rgb)
+{
+ reginfo("set LTDC_BCCR=%08x\n", rgb);
+ putreg32(rgb, STM32_LTDC_BCCR);
+ reginfo("configured LTDC_BCCR=%08x\n", getreg32(STM32_LTDC_BCCR));
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_dither
+ *
+ * Description:
+ * Configures dither settings of the LCD controller.
+ *
+ * Parameter:
+ * enable - Enable dithering
+ * red - Red dither width
+ * green - Green dither width
+ * blue - Blue dither width
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_dither(bool enable,
+ uint8_t red,
+ uint8_t green,
+ uint8_t blue)
+{
+ uint32_t regval;
+
+ regval = getreg32(STM32_LTDC_GCR);
+
+ if (enable == true)
+ {
+ regval |= LTDC_GCR_DEN;
+ }
+ else
+ {
+ regval &= ~LTDC_GCR_DEN;
+ }
+
+ regval &= ~(!LTDC_GCR_DEN | LTDC_GCR_DRW(0) |
+ LTDC_GCR_DGW(0) | LTDC_GCR_DBW(0));
+ regval |= (LTDC_GCR_DRW(red) | LTDC_GCR_DGW(green) | LTDC_GCR_DBW(blue));
+
+ reginfo("set LTDC_GCR=%08x\n", regval);
+ putreg32(regval, STM32_LTDC_GCR);
+ reginfo("configured LTDC_GCR=%08x\n", getreg32(STM32_LTDC_GCR));
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_linepos
+ *
+ * Description:
+ * Configures line position register
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_linepos(void)
+{
+ /* Configure LTDC_LIPCR */
+
+ reginfo("set LTDC_LIPCR=%08x\n", STM32_LTDC_LIPCR_LIPOS);
+ putreg32(STM32_LTDC_LIPCR_LIPOS, STM32_LTDC_LIPCR);
+ reginfo("configured LTDC_LIPCR=%08x\n", getreg32(STM32_LTDC_LIPCR));
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_irqctrl
+ *
+ * Description:
+ * Control interrupts generated by the ltdc controller
+ *
+ * Parameter:
+ * setirqs - set interrupt mask
+ * clrirqs - clear interrupt mask
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_irqctrl(uint32_t setirqs, uint32_t clrirqs)
+{
+ uint32_t regval;
+
+ regval = getreg32(STM32_LTDC_IER);
+ regval &= ~clrirqs;
+ regval |= setirqs;
+ reginfo("set LTDC_IER=%08x\n", regval);
+ putreg32(regval, STM32_LTDC_IER);
+ reginfo("configured LTDC_IER=%08x\n", getreg32(STM32_LTDC_IER));
+}
+
+/****************************************************************************
+ * Name: stm32_ltdcirq
+ *
+ * Description:
+ * LTDC interrupt handler
+ *
+ ****************************************************************************/
+
+static int stm32_ltdcirq(int irq, void *context, FAR void *arg)
+{
+ FAR struct stm32_interrupt_s *priv = &g_interrupt;
+
+ uint32_t regval = getreg32(STM32_LTDC_ISR);
+
+ reginfo("irq = %d, regval = %08x\n", irq, regval);
+
+ if (regval & LTDC_ISR_RRIF)
+ {
+ /* Register reload interrupt */
+
+ /* Clear the interrupt status register */
+
+ putreg32(LTDC_ICR_CRRIF, STM32_LTDC_ICR);
+
+ /* Update the handled flag */
+
+ priv->handled = true;
+
+ /* Unlock the semaphore if locked */
+
+ if (priv->wait)
+ {
+ int ret = sem_post(priv->sem);
+
+ if (ret != OK)
+ {
+ lcderr("ERROR: sem_post() failed\n");
+ return ret;
+ }
+ }
+ }
+
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_waitforirq
+ *
+ * Description:
+ * Helper waits until the ltdc irq occurs. In the current design That means
+ * that a register reload was been completed.
+ * Note! The caller must use this function within a critical section.
+ *
+ * Return:
+ * OK - On success otherwise ERROR
+ *
+ ****************************************************************************/
+
+static int stm32_ltdc_waitforirq(void)
+{
+ int ret = OK;
+ FAR struct stm32_interrupt_s *priv = &g_interrupt;
+
+ irqstate_t flags;
+
+ flags = enter_critical_section();
+
+ /* Only waits if last enabled interrupt is currently not handled */
+
+ if (!priv->handled)
+ {
+ /* Inform the irq handler the task is able to wait for the irq */
+
+ priv->wait = true;
+
+ ret = sem_wait(priv->sem);
+
+ /* irq or an error occurs, reset the wait flag */
+
+ priv->wait = false;
+
+ if (ret != OK)
+ {
+ lcderr("ERROR: sem_wait() failed\n");
+ }
+ }
+
+ leave_critical_section(flags);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_reload
+ *
+ * Description:
+ * Reload the layer shadow register and make layer changes visible.
+ * Note! The caller must ensure that a previous register reloading has been
+ * completed.
+ *
+ * Parameter:
+ * value - Reload flag (e.g. upon vertical blank or immediately)
+ * waitvblank - Wait until register reload is finished
+ *
+ ****************************************************************************/
+
+static int stm32_ltdc_reload(uint8_t value, bool waitvblank)
+{
+ int ret = OK;
+ FAR struct stm32_interrupt_s *priv = &g_interrupt;
+
+ if (value == LTDC_SRCR_VBR)
+ {
+ irqstate_t flags;
+
+ /* Prepare shadow register reload for later detection by the task.
+ * At this point the last register reload must be completed. This is done
+ * in stm32_update before the next operation is triggered and manipulates
+ * the shadow register. This handling is only neccessary in the case of
+ * the application causes shadow register reload.
+ */
+
+ flags = enter_critical_section();
+
+ ASSERT(priv->handled == true);
+
+ /* Reset the handled flag */
+
+ priv->handled = false;
+ leave_critical_section(flags);
+ }
+
+ /* Reloads the shadow register.
+ * Note! This will not trigger an register reload interrupt if
+ * immediately reload is set.
+ */
+
+ reginfo("set LTDC_SRCR=%08x\n", value);
+ putreg32(value, STM32_LTDC_SRCR);
+ reginfo("configured LTDC_SRCR=%08x\n", getreg32(STM32_LTDC_SRCR));
+
+ if (waitvblank & (value == LTDC_SRCR_VBR))
+ {
+ /* Wait upon vertical blanking period */
+
+ ret = stm32_ltdc_waitforirq();
+ }
+
+ /* Otherwise check if reload is completed before the next operation */
+
+ return ret;
+}
+
+/****************************************************************************
+ * Name: stm32_global_configure
+ *
+ * Description:
+ * Configure background color
+ * Configure interrupts
+ * Configure dithering
+ *
+ ****************************************************************************/
+
+static void stm32_global_configure(void)
+{
+ /* Initialize the LTDC semaphore that enforces mutually exclusive access */
+
+ sem_init(&g_lock, 0, 1);
+
+ /* Initialize the semaphore for interrupt handling. This waitsem
+ * semaphore is used for signaling and, hence, should not have priority
+ * inheritance enabled.
+ */
+
+ sem_init(g_interrupt.sem, 0, 0);
+ sem_setprotocol(g_interrupt.sem, SEM_PRIO_NONE);
+
+ /* Attach LTDC interrupt vector */
+
+ (void)irq_attach(g_interrupt.irq, stm32_ltdcirq, NULL);
+
+ /* Enable the IRQ at the NVIC */
+
+ up_enable_irq(g_interrupt.irq);
+
+ /* Enable register reload interrupt only */
+
+ stm32_ltdc_irqctrl(LTDC_IER_RRIE, LTDC_IER_TERRIE | LTDC_IER_FUIE | LTDC_IER_LIE);
+
+ /* Configure line interrupt */
+
+ stm32_ltdc_linepos();
+
+ /* Set the default active layer */
+
+#ifndef CONFIG_STM32F7_LTDC_L2
+ g_lactive = LTDC_LAYER_L1;
+#else
+ g_lactive = LTDC_LAYER_L2;
+#endif
+
+#ifdef STM32_LAYER_CLUT_SIZE
+ /* cleanup clut */
+
+ memset(g_clut, 0, sizeof(g_clut));
+#endif
+
+ /* Configure dither */
+
+ stm32_ltdc_dither(
+#ifdef CONFIG_STM32F7_LTDC_DITHER
+ true,
+#else
+ false,
+#endif
+ STM32_LTDC_DITHER_RED,
+ STM32_LTDC_DITHER_GREEN,
+ STM32_LTDC_DITHER_BLUE);
+
+ /* Configure background color of the controller */
+
+ stm32_ltdc_bgcolor(STM32_LTDC_BACKCOLOR);
+}
+
+/****************************************************************************
+ * Name: stm32_lcd_enable
+ *
+ * Description:
+ * Disable the LCD peripheral
+ *
+ * Parameter:
+ * enable - Enable or disable
+ *
+ ****************************************************************************/
+
+static void stm32_lcd_enable(bool enable)
+{
+ uint32_t regval;
+
+ regval = getreg32(STM32_LTDC_GCR);
+ reginfo("get LTDC_GCR=%08x\n", regval);
+
+ if (enable == true)
+ {
+ regval |= LTDC_GCR_LTDCEN;
+ }
+ else
+ {
+ regval &= ~LTDC_GCR_LTDCEN;
+ }
+
+ reginfo("set LTDC_GCR=%08x\n", regval);
+ putreg32(regval, STM32_LTDC_GCR);
+ reginfo("configured LTDC_GCR=%08x\n", getreg32(STM32_LTDC_GCR));
+}
+
+/****************************************************************************
+ * Configure layer register
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_ltdc_lclutenable
+ *
+ * Description:
+ * Disable or enable the layer clut support
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * enable - Enable or disable
+ *
+ ****************************************************************************/
+
+#ifdef STM32_LAYER_CLUT_SIZE
+static void stm32_ltdc_lclutenable(FAR struct stm32_layer_s *layer, bool enable)
+{
+ uint32_t regval;
+
+ regval = getreg32(stm32_cr_layer_t[layer->state.lid]);
+ reginfo("get LTDC_L%dCR=%08x\n", layer->state.lid + 1, regval);
+
+ /* Disable the clut support during update the color table */
+
+ if (enable == true)
+ {
+ regval |= LTDC_LxCR_CLUTEN;
+ }
+ else
+ {
+ regval &= ~LTDC_LxCR_CLUTEN;
+ }
+
+ reginfo("set LTDC_L%dCR=%08x\n", layer->state.lid + 1, regval);
+ putreg32(regval, stm32_cr_layer_t[layer->state.lid]);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_ltdc_lsetopac
+ *
+ * Description:
+ * Helper to set the layer to opac
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static inline void stm32_ltdc_lsetopac(FAR struct stm32_layer_s *layer)
+{
+ layer->opac = 0xff;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lunsetopac
+ *
+ * Description:
+ * Helper to set the layer opacity to the alpha value
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static inline void stm32_ltdc_lunsetopac(FAR struct stm32_layer_s *layer)
+{
+ layer->opac = 0;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lgetopac
+ *
+ * Description:
+ * Helper to get the configured layer opacity
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static inline uint8_t stm32_ltdc_lgetopac(FAR struct stm32_layer_s *layer)
+{
+ return layer->opac | layer->state.alpha;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lvalidate
+ *
+ * Description:
+ * Helper to check if the layer is an valid ltdc layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ * Return:
+ * true - layer valid
+ * false - layer invalid
+ *
+ ****************************************************************************/
+
+static inline bool stm32_ltdc_lvalidate(FAR const struct stm32_layer_s *layer)
+{
+#ifdef CONFIG_STM32F7_LTDC_L2
+ return layer == &LAYER_L1 || layer == &LAYER_L2;
+#else
+ return layer == &LAYER_L1;
+#endif
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lvalidatearea
+ *
+ * Description:
+ * Check if layer coordinates out of valid area.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * xpos - top left x position of the active area
+ * ypos - top left y position of the active area
+ * xres - width of the active area
+ * yres - height of teh active area
+ * srcxpos - Top left x position from where data visible in the active area
+ * srcypos - Top left y position from where data visible in the active area
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+static int stm32_ltdc_lvalidatearea(FAR struct stm32_layer_s *layer,
+ fb_coord_t xpos, fb_coord_t ypos,
+ fb_coord_t xres, fb_coord_t yres,
+ fb_coord_t srcxpos, fb_coord_t srcypos)
+{
+ FAR const struct fb_videoinfo_s *vinfo = &layer->state.vinfo;
+
+ if ((xpos > vinfo->xres - 1) ||
+ (ypos > vinfo->yres -1) ||
+ (xres > vinfo->xres - xpos) ||
+ (yres > vinfo->yres - ypos) ||
+ (srcxpos > xpos + xres - 1) ||
+ (srcypos > ypos + yres - 1))
+
+ {
+ lcderr("ERROR: layer coordinates out of valid area: xpos = %d > %d, \
+ ypos = %d > %d, width = %d > %d, height = %d > %d, \
+ srcxpos = %d > %d, srcypos = %d > %d",
+ xpos, vinfo->xres - 1,
+ ypos, vinfo->yres - 1,
+ xres, vinfo->xres - xpos,
+ yres, vinfo->yres - ypos,
+ srcxpos, xpos + xres - 1,
+ srcypos, ypos + yres - 1);
+
+ lcderr(" Returning EINVAL\n");
+ return -EINVAL;
+ }
+
+ return OK;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_ltdc_lupdate
+ *
+ * Description:
+ * Updates shadow register content depending on the layer operation flag.
+ * This made changes for the given layer visible after the next shadow
+ * register reload.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_lupdate(FAR struct stm32_layer_s *layer)
+{
+ if (layer->operation & LTDC_LAYER_SETAREA)
+ {
+ /* Updates the layer horizontal and vertical position register */
+
+ stm32_ltdc_larea(layer);
+ }
+
+ if (layer->operation & LTDC_LAYER_SETALPHAVALUE)
+ {
+ /* Updates the constant alpha register */
+
+ stm32_ltdc_lalpha(layer);
+ }
+
+ if (layer->operation & LTDC_LAYER_SETBLENDMODE)
+ {
+ /* Update blendfactor 1 and 2 register */
+
+ stm32_ltdc_lblendmode(layer, layer->bf1, layer->bf2);
+ }
+
+ if (layer->operation & LTDC_LAYER_SETCOLORKEY)
+ {
+ /* Update layer colorkey register */
+
+ stm32_ltdc_lcolorkey(layer);
+ }
+
+ if (layer->operation & LTDC_LAYER_SETCOLOR)
+ {
+ /* Update layer color register */
+
+ stm32_ltdc_lcolor(layer, layer->state.color);
+ }
+
+ if (layer->operation & LTDC_LAYER_SETENABLE)
+ {
+ /* Enable the layer */
+
+ stm32_ltdc_lenable(layer);
+ }
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_larea
+ *
+ * Description:
+ * Change the active area of the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_larea(struct stm32_layer_s *layer)
+{
+ uint32_t lxpos;
+ uint32_t lypos;
+ uint32_t whpcr;
+ uint32_t wvpcr;
+ FAR struct stm32_ltdc_s *priv = &layer->state;
+ FAR struct ltdc_area_s *area = &priv->area;
+
+ reginfo("xpos = %d, ypos = %d, xres = %d, yres = %d\n",
+ area->xpos, area->ypos, area->xres, area->yres);
+
+ lxpos = area->xpos + (STM32_LTDC_LxWHPCR_WHSTPOS + 1);
+ lypos = area->ypos + (STM32_LTDC_LxWVPCR_WVSTPOS + 1);
+
+ /* Accumulate horizontal position */
+
+ whpcr = LTDC_LxWHPCR_WHSTPOS(lxpos);
+ whpcr |= LTDC_LxWHPCR_WHSPPOS(lxpos + area->xres - 1);
+
+ /* Accumulate vertical position */
+
+ wvpcr = LTDC_LxWVPCR_WVSTPOS(lypos);
+ wvpcr |= LTDC_LxWVPCR_WVSPPOS(lypos + area->yres - 1);
+
+ /* Configure LxWHPCR / LxWVPCR register */
+
+ reginfo("set LTDC_L%dWHPCR=%08x\n", priv->lid + 1, whpcr);
+ putreg32(whpcr, stm32_whpcr_layer_t[priv->lid]);
+ reginfo("set LTDC_L%dWVPCR=%08x\n", priv->lid + 1, wvpcr);
+ putreg32(wvpcr, stm32_wvpcr_layer_t[priv->lid]);
+
+ /* Configure framebuffer */
+
+ stm32_ltdc_lframebuffer(layer);
+
+ /* Clear area operation flag */
+
+ layer->operation &= ~LTDC_LAYER_SETAREA;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lpixelformat
+ *
+ * Description:
+ * Set the layer pixel format.
+ * Note! This changes have no effect until the shadow register reload has
+ * been done.
+ *
+ * Parameter:
+ * Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_lpixelformat(FAR struct stm32_layer_s *layer)
+{
+ /* Configure PFCR register */
+
+ reginfo("set LTDC_L%dPFCR=%08x\n", layer->state.lid + 1,
+ stm32_fmt_layer_t[layer->state.lid]);
+ putreg32(stm32_fmt_layer_t[layer->state.lid],
+ stm32_pfcr_layer_t[layer->state.lid]);
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_framebuffer
+ *
+ * Description:
+ * Change layer framebuffer offset.
+ * Note! This changes have no effect until the shadow register reload has
+ * been done.
+ *
+ * Parameter:
+ * Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static inline void stm32_ltdc_lframebuffer(FAR struct stm32_layer_s *layer)
+{
+ uint32_t offset;
+ uint32_t cfblr;
+ FAR struct stm32_ltdc_s *priv = &layer->state;
+ FAR struct ltdc_area_s *area = &priv->area;
+ FAR const struct fb_planeinfo_s *pinfo = &priv->pinfo;
+
+ /* Configure LxCFBAR register */
+
+ /* Calculate offset position in the framebuffer */
+
+ offset = priv->xpos * STM32_LTDC_Lx_BYPP(pinfo->bpp) +
+ pinfo->stride * priv->ypos;
+
+ reginfo("set LTDC_L%dCFBAR=%08x\n", priv->lid + 1, pinfo->fbmem + offset);
+ putreg32((uint32_t)pinfo->fbmem + offset, stm32_cfbar_layer_t[priv->lid]);
+
+ /* Configure LxCFBLR register */
+
+ /* Calculate line length */
+
+ cfblr = LTDC_LxCFBLR_CFBP(pinfo->stride) |
+ LTDC_LxCFBLR_CFBLL(area->xres * STM32_LTDC_Lx_BYPP(pinfo->bpp) + 3);
+
+ reginfo("set LTDC_L%dCFBLR=%08x\n", priv->lid + 1, cfblr);
+ putreg32(cfblr, stm32_cfblr_layer_t[priv->lid]);
+
+ /* Configure LxCFBLNR register */
+
+ reginfo("set LTDC_L%dCFBLNR=%08x\n", priv->lid + 1, area->yres);
+ putreg32(area->yres, stm32_cfblnr_layer_t[priv->lid]);
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lalpha
+ *
+ * Description:
+ * Change the layer alpha value and clear the alpha operation flag.
+ * Note! This changes have no effect until the shadow register reload has
+ * been done.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_lalpha(FAR struct stm32_layer_s *layer)
+{
+ uint8_t opac = stm32_ltdc_lgetopac(layer);
+ reginfo("set LTDC_L%dCACR=%02x\n", layer->state.lid + 1, opac);
+ putreg32(opac, stm32_cacr_layer_t[layer->state.lid]);
+
+ /* Clear the constant alpha operation flag */
+
+ layer->operation &= ~LTDC_LAYER_SETALPHAVALUE;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_blendfactor
+ *
+ * Description:
+ * Change layer blend factors used for blend operation and clear the
+ * blendmode operation flag.
+ * Note! This changes have no effect until the shadow register reload has
+ * been done.
+ *
+ * Parameter:
+ * layer - Reference to the laxer control structure
+ * bf1 - Value of blend factor 1
+ * bf2 - Value of blend factor 2
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_lblendmode(FAR struct stm32_layer_s *layer,
+ uint8_t bf1, uint8_t bf2)
+{
+ reginfo("set LTDC_L%dBFCR=%08x\n", layer->state.lid + 1,
+ (LTDC_LxBFCR_BF1(bf1) | LTDC_LxBFCR_BF2(bf2)));
+ putreg32((LTDC_LxBFCR_BF1(bf1) | LTDC_LxBFCR_BF2(bf2)),
+ stm32_bfcr_layer_t[layer->state.lid]);
+
+ /* Clear the blendmode operation flag */
+
+ layer->operation &= ~LTDC_LAYER_SETBLENDMODE;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lcolor
+ *
+ * Description:
+ * Change layer default color and clear the color operation flag.
+ * Note! This changes have no effect until the shadow register reload has
+ * been done.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_lcolor(FAR struct stm32_layer_s *layer, uint32_t argb)
+{
+ reginfo("set LTDC_L%dDCCR=%08x\n", layer->state.lid + 1, argb);
+ putreg32(argb, stm32_dccr_layer_t[layer->state.lid]);
+
+ /* Clear the color operation flag */
+
+ layer->operation &= ~LTDC_LAYER_SETCOLOR;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lcolorkey
+ *
+ * Description:
+ * Change layer colorkey and clear the colorkey operation flag.
+ * Note! This changes have no effect until the shadow register reload has
+ * been done.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_lcolorkey(FAR struct stm32_layer_s *layer)
+{
+ uint32_t regval;
+
+ regval = getreg32(stm32_cr_layer_t[layer->state.lid]);
+
+ if (layer->operation & LTDC_LAYER_ENABLECOLORKEY)
+ {
+ /* Set colorkey */
+
+ reginfo("set LTDC_L%dCKCR=%08x\n",
+ layer->state.lid + 1, layer->state.colorkey);
+ putreg32(layer->state.colorkey, stm32_ckcr_layer_t[layer->state.lid]);
+
+ /* Enable colorkey */
+
+ regval |= LTDC_LxCR_COLKEN;
+ }
+ else
+ {
+ /* Disable colorkey */
+
+ regval &= ~LTDC_LxCR_COLKEN;
+ }
+
+ reginfo("set LTDC_L%dCR=%08x\n", layer->state.lid + 1, regval);
+ putreg32(regval, stm32_cr_layer_t[layer->state.lid]);
+
+ /* Clear the colorkey operation flag */
+
+ layer->operation &= ~LTDC_LAYER_SETCOLORKEY;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_lclut
+ *
+ * Description:
+ * Update the clut layer register during blank period.
+ * Note! The clut register are no shadow register.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+#ifdef STM32_LAYER_CLUT_SIZE
+static void stm32_ltdc_lclut(FAR struct stm32_layer_s *layer,
+ FAR const struct fb_cmap_s *cmap)
+{
+ int n;
+ uint32_t regval;
+ uint32_t *clut;
+ irqstate_t flags;
+
+ /* Disable clut during register update */
+
+ stm32_ltdc_lclutenable(layer, false);
+
+ /* Set the clut memory address */
+
+ clut = layer->state.clut;
+
+ /* Reload shadow control register.
+ * This never changed any layer setting as long the layer register not up to
+ * date. This is what stm32_update does.
+ */
+
+ stm32_ltdc_reload(LTDC_SRCR_IMR, false);
+
+ flags = enter_critical_section();
+
+ /* Update the clut registers */
+
+ for (n = cmap->first; n < cmap->len && n < STM32_LTDC_NCLUT; n++)
+ {
+ /* Update the layer clut entry */
+#ifndef CONFIG_FB_TRANSPARENCY
+ uint8_t *clut888 = (uint8_t *)clut;
+ uint16_t offset = 3 * n;
+
+ clut888[offset] = cmap->blue[n];
+ clut888[offset + 1] = cmap->green[n];
+ clut888[offset + 2] = cmap->red[n];
+
+ regval = (uint32_t)LTDC_CLUT_BLUE(clut888[offset]) |
+ (uint32_t)LTDC_CLUT_GREEN(clut888[offset + 1]) |
+ (uint32_t)LTDC_CLUT_RED(clut888[offset + 2]) |
+ (uint32_t)LTDC_CLUT_ADD(n);
+#else
+ clut[n] = (uint32_t)LTDC_CLUT_ALPHA(cmap->transp[n]) |
+ (uint32_t)LTDC_CLUT_RED(cmap->red[n]) |
+ (uint32_t)LTDC_CLUT_GREEN(cmap->green[n]) |
+ (uint32_t)LTDC_CLUT_BLUE(cmap->blue[n]);
+ regval = (uint32_t)LTDC_CLUT_ADD(n) | (clut[n] & LTDC_CLUT_RGB888_MASK);
+#endif
+
+
+ reginfo("set LTDC_L%dCLUTWR = %08x, cmap->first = %d, cmap->len = %d\n",
+ layer->state.lid + 1, regval, cmap->first, cmap->len);
+ putreg32(regval, stm32_clutwr_layer_t[layer->state.lid]);
+ }
+
+ leave_critical_section(flags);
+
+ /* Enable clut */
+
+ stm32_ltdc_lclutenable(layer, true);
+
+ /* Reload shadow control register */
+
+ stm32_ltdc_reload(LTDC_SRCR_IMR, false);
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_ltdc_lenable
+ *
+ * Description:
+ * Disable or enable specific layer.
+ * Note! This changes have no effect until the shadow register reload has
+ * been done.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_lenable(FAR struct stm32_layer_s *layer)
+{
+ uint32_t regval;
+
+ /* Enable or disable layer */
+
+ regval = getreg32(stm32_cr_layer_t[layer->state.lid]);
+
+ if (layer->operation & LTDC_LAYER_ENABLE)
+ {
+ regval |= LTDC_LxCR_LEN;
+ }
+ else
+ {
+ regval &= ~LTDC_LxCR_LEN;
+ }
+
+ reginfo("set LTDC_L%dCR=%08x\n", layer->state.lid + 1, regval);
+ putreg32(regval, stm32_cr_layer_t[layer->state.lid]);
+
+ /* Clear the enable operation flag */
+
+ layer->operation &= ~LTDC_LAYER_SETENABLE;
+}
+
+/****************************************************************************
+ * Name stm32_ltdc_lclear
+ *
+ * Description:
+ * Clear the whole layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * color - The color to clear
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_lclear(FAR struct stm32_layer_s *layer,
+ nxgl_mxpixel_t color)
+{
+ FAR struct stm32_ltdc_s *priv = &layer->state;
+
+#if STM32_LTDC_L1_BPP == 8 || STM32_LTDC_L2_BPP == 8
+ if (priv->pinfo.bpp == 8)
+ {
+ uint8_t *dest = (uint8_t *)priv->pinfo.fbmem;
+ int i;
+
+ lcdinfo("Clearing display: BPP=%d color=%04x framebuffer=%08x size=%d\n",
+ priv->pinfo.bpp, color, dest, priv->pinfo.fblen);
+
+ for (i = 0; i < priv->pinfo.fblen; i += sizeof(uint8_t))
+ {
+ *dest++ = (uint8_t)color;
+ }
+
+ return;
+ }
+#endif
+
+#if STM32_LTDC_L1_BPP == 16 || STM32_LTDC_L2_BPP == 16
+ if (priv->pinfo.bpp == 16)
+ {
+ uint16_t *dest = (uint16_t *)priv->pinfo.fbmem;
+ int i;
+
+ lcdinfo("Clearing display: BPP=%d color=%04x framebuffer=%08x size=%d\n",
+ priv->pinfo.bpp, color, dest, priv->pinfo.fblen);
+
+ for (i = 0; i < priv->pinfo.fblen; i += sizeof(uint16_t))
+ {
+ *dest++ = (uint16_t)color;
+ }
+
+ return;
+ }
+#endif
+
+#if STM32_LTDC_L1_BPP == 24 || STM32_LTDC_L2_BPP == 24
+ if (priv->pinfo.bpp == 24)
+ {
+ uint8_t *dest = (uint8_t *)priv->pinfo.fbmem;
+ uint8_t r;
+ uint8_t g;
+ uint8_t b;
+ int i;
+
+ lcdinfo("Clearing display: BPP=%d color=%04x framebuffer=%08x size=%d\n",
+ priv->pinfo.bpp, color, dest, priv->pinfo.fblen);
+
+ r = (uint8_t) color;
+ g = (uint8_t) (color >> 8);
+ b = (uint8_t) (color >> 16);
+
+ for (i = 0; i < priv->pinfo.fblen; i += 3*sizeof(uint8_t))
+ {
+ *dest++ = r;
+ *dest++ = g;
+ *dest++ = b;
+ }
+
+ return;
+ }
+#endif
+
+#if STM32_LTDC_L1_BPP == 32 || STM32_LTDC_L2_BPP == 32
+ if (priv->pinfo.bpp == 32)
+ {
+ uint32_t *dest = (uint32_t *)priv->pinfo.fbmem;
+ int i;
+
+ lcdinfo("Clearing display: BPP=%d color=%04x framebuffer=%08x size=%d\n",
+ priv->pinfo.bpp, color, dest, priv->pinfo.fblen);
+
+ for (i = 0; i < priv->pinfo.fblen; i += sizeof(uint32_t))
+ {
+ *dest++ = (uint32_t)color;
+ }
+ }
+#endif
+}
+
+/****************************************************************************
+ * Name: stm32_ltdc_linit
+ *
+ * Description:
+ * Initialize layer to their default states.
+ *
+ * Initialize:
+ * - Reset layer
+ * - layer fram
+ * - Reset layerebuffers
+ * - layer position
+ * - layer pixelformat
+ * - layer color
+ * - layer colorkey
+ * - layer alpha
+ * - layer blendmode
+ * - layer dma2d interface binding
+ *
+ * Parameter
+ * layer - Reference to the layer control structure
+ *
+ ****************************************************************************/
+
+static void stm32_ltdc_linit(int lid)
+{
+ /* Reset layer to their default state */
+
+ FAR struct stm32_layer_s *layer = &LAYER(lid);
+ FAR struct stm32_ltdc_s *state = &layer->state;
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+ FAR struct ltdc_layer_s *ltdc = &layer->ltdc;
+
+ /* Initialize the ltdc interface */
+
+ ltdc->getlid = stm32_getlid;
+ ltdc->getvideoinfo = stm32_lgetvideoinfo;
+ ltdc->getplaneinfo = stm32_lgetplaneinfo;
+# ifdef STM32_LAYER_CLUT_SIZE
+ ltdc->setclut = stm32_setclut;
+ ltdc->getclut = stm32_getclut;
+#endif
+ ltdc->setcolor = stm32_setcolor;
+ ltdc->getcolor = stm32_getcolor;
+ ltdc->setcolorkey = stm32_setcolorkey;
+ ltdc->getcolorkey = stm32_getcolorkey;
+ ltdc->setalpha = stm32_setalpha;
+ ltdc->getalpha = stm32_getalpha;
+ ltdc->setblendmode = stm32_setblendmode;
+ ltdc->getblendmode = stm32_getblendmode;
+ ltdc->setarea = stm32_setarea;
+ ltdc->getarea = stm32_getarea;
+ ltdc->update = stm32_update;
+#ifdef CONFIG_STM32F7_DMA2D
+ ltdc->blit = stm32_blit;
+ ltdc->blend = stm32_blend;
+ ltdc->fillarea = stm32_fillarea;
+#endif
+#endif
+
+ /* Initialize the layer state */
+
+ state->area.xpos = 0;
+ state->area.ypos = 0;
+ state->area.xres = STM32_LTDC_WIDTH;
+ state->area.yres = STM32_LTDC_HEIGHT;
+ state->xpos = 0;
+ state->ypos = 0;
+ state->color = 0;
+ state->colorkey = 0;
+ state->alpha = 0xff;
+ state->blendmode = LTDC_BLEND_NONE;
+ state->lock = &g_lock;
+
+ /* Initialize driver internals */
+
+ layer->opac = 0xff;
+ layer->bf1 = LTDC_BF1_CONST_ALPHA;
+ layer->bf2 = LTDC_BF2_CONST_ALPHA;
+ layer->operation = LTDC_LAYER_INIT;
+
+ /* Clear the layer framebuffer */
+
+ stm32_ltdc_lclear(layer, 0);
+
+ /* Set Pixel input format */
+
+ stm32_ltdc_lpixelformat(layer);
+
+ /* Set position, color, colorkey, blendmode, alpha */
+
+ stm32_ltdc_lupdate(layer);
+
+#ifdef STM32_LAYER_CLUT_SIZE
+ /* Disable clut by default */
+
+ if (layer->state.vinfo.fmt == FB_FMT_RGB8)
+ {
+ stm32_ltdc_lclutenable(layer, false);
+ }
+#endif
+
+#if defined(CONFIG_STM32F7_DMA2D) && defined(CONFIG_STM32F7_LTDC_INTERFACE)
+ /* Bind the dma2d interface */
+
+ layer->dma2d = stm32_dma2dinitltdc(state);
+ DEBUGASSERT(layer->dma2d);
+#endif
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: stm32_getvideoinfo
+ *
+ * Description:
+ * Get the videoinfo for the framebuffer
+ *
+ * Parameter:
+ * vtable - The framebuffer driver object
+ * vinfo - the videoinfo object
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_getvideoinfo(struct fb_vtable_s *vtable,
+ struct fb_videoinfo_s *vinfo)
+{
+ lcdinfo("vtable=%p vinfo=%p\n", vtable, vinfo);
+ if (vtable)
+ {
+ FAR struct ltdc_layer_s *ltdc;
+#ifdef CONFIG_STM32F7_LTDC_L2
+ ltdc = (FAR struct ltdc_layer_s *)&LAYER_L2;
+#else
+ ltdc = (FAR struct ltdc_layer_s *)&LAYER_L1;
+#endif
+ return stm32_lgetvideoinfo(ltdc, vinfo);
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getplaneinfo
+ *
+ * Description:
+ * Get the planeinfo for the framebuffer
+ *
+ * Parameter:
+ * vtable - The framebuffer driver object
+ * pinfo - the planeinfo object
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_getplaneinfo(struct fb_vtable_s *vtable, int planeno,
+ struct fb_planeinfo_s *pinfo)
+{
+ lcdinfo("vtable=%p planeno=%d pinfo=%p\n", vtable, planeno, pinfo);
+ if (vtable)
+ {
+ FAR struct ltdc_layer_s *ltdc;
+#ifdef CONFIG_STM32F7_LTDC_L2
+ ltdc = (FAR struct ltdc_layer_s *)&LAYER_L2;
+#else
+ ltdc = (FAR struct ltdc_layer_s *)&LAYER_L1;
+#endif
+ return stm32_lgetplaneinfo(ltdc, planeno, pinfo);
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getcmap
+ *
+ * Description:
+ * Get a range of CLUT values for the LCD
+ *
+ * Parameter:
+ * vtable - The framebuffer driver object
+ * cmap - the color table
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+#ifdef STM32_LAYER_CLUT_SIZE
+static int stm32_getcmap(struct fb_vtable_s *vtable,
+ struct fb_cmap_s *cmap)
+{
+#ifdef CONFIG_STM32F7_LTDC_L2
+ return stm32_getclut((FAR struct ltdc_layer_s *)&LAYER_L2, cmap);
+#else
+ return stm32_getclut((FAR struct ltdc_layer_s *)&LAYER_L1, cmap);
+#endif
+}
+
+/****************************************************************************
+ * Name: stm32_putcmap
+ *
+ * Description:
+ * Set a range of the CLUT values for the LCD
+ *
+ * Parameter:
+ * vtable - The framebuffer driver object
+ * cmap - the color table
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_putcmap(struct fb_vtable_s *vtable,
+ const struct fb_cmap_s *cmap)
+{
+#ifdef CONFIG_STM32F7_LTDC_L2
+ return stm32_setclut((FAR struct ltdc_layer_s *)&LAYER_L2, cmap);
+#else
+ return stm32_setclut((FAR struct ltdc_layer_s *)&LAYER_L1, cmap);
+#endif
+}
+#endif /* STM32_LAYER_CLUT_SIZE */
+
+/****************************************************************************
+ * Name: stm32_lgetvideoinfo
+ *
+ * Description:
+ * Get video information about the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * vinfo - Reference to the video info structure
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_lgetvideoinfo(struct ltdc_layer_s *layer,
+ struct fb_videoinfo_s *vinfo)
+{
+ lcdinfo("layer=%p vinfo=%p\n", layer, vinfo);
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ memcpy(vinfo, &priv->state.vinfo, sizeof(struct fb_videoinfo_s));
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_lgetplaneinfo
+ *
+ * Description:
+ * Get plane information about the layer
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * planeno - Number of the plane
+ * pinfo - Reference to the plane info structure
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_lgetplaneinfo(struct ltdc_layer_s *layer, int planeno,
+ struct fb_planeinfo_s *pinfo)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer=%p planeno=%d pinfo=%p\n", layer, planeno, pinfo);
+ if (stm32_ltdc_lvalidate(priv) && planeno == 0)
+ {
+ memcpy(pinfo, &priv->state.pinfo, sizeof(struct fb_planeinfo_s));
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_setclut
+ *
+ * Description:
+ * Configure layer clut (color lookup table).
+ * Non clut is defined during initializing.
+ * Clut is active during next vertical blank period. Do not need an update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * cmap - color lookup table with up the 256 entries
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+#ifdef STM32_LAYER_CLUT_SIZE
+static int stm32_setclut(struct ltdc_layer_s *layer,
+ const struct fb_cmap_s *cmap)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+ int ret;
+
+ lcdinfo("layer=%p cmap=%p\n", layer, cmap);
+
+ if (stm32_ltdc_lvalidate(priv) && cmap)
+ {
+ sem_wait(priv->state.lock);
+
+ if (priv->state.vinfo.fmt != FB_FMT_RGB8)
+ {
+ lcderr("ERROR: CLUT is not supported for the pixel format: %d\n",
+ priv->state.vinfo.fmt);
+ ret = -EINVAL;
+ }
+ else if (cmap->first >= STM32_LTDC_NCLUT)
+ {
+ lcderr("ERROR: only %d color table entries supported\n",
+ STM32_LTDC_NCLUT);
+ ret = -EINVAL;
+ }
+ else
+ {
+ /* Update layer clut and clut register */
+
+ stm32_ltdc_lclut(priv, cmap);
+
+ ret = OK;
+ }
+
+ sem_post(priv->state.lock);
+
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getclut
+ *
+ * Description:
+ * Get configured layer clut (color lookup table).
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * cmap - Reference to valid color lookup table accept up the 256 color
+ * entries
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_getclut(struct ltdc_layer_s *layer,
+ struct fb_cmap_s *cmap)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+ int ret;
+
+ lcdinfo("layer=%p cmap=%p\n", layer, cmap);
+
+ if (priv == &LAYER_L1 || priv == &LAYER_L2)
+ {
+ sem_wait(priv->state.lock);
+#ifdef CONFIG_STM32F7_DMA2D
+ /* Note! We share the same color lookup table with the dma2d driver and
+ * the getclut implementation works in the same way.
+ * To prevent redundant code we simply call the getclut function of the
+ * dma2d interface.
+ */
+
+ ret = priv->dma2d->getclut(priv->dma2d, cmap);
+#else
+ if (priv->state.vinfo.fmt != FB_FMT_RGB8)
+ {
+ lcderr("ERROR: CLUT is not supported for the pixel format: %d\n",
+ priv->state.vinfo.fmt);
+ ret = -EINVAL;
+ }
+ else if (cmap->first >= STM32_LTDC_NCLUT)
+ {
+ lcderr("ERROR: only %d color table entries supported\n",
+ STM32_LTDC_NCLUT);
+ ret = -EINVAL;
+ }
+ else
+ {
+ /* Copy from the layer clut */
+
+ uint32_t *clut;
+ int n;
+
+ clut = priv->state.clut;
+
+ for (n = cmap->first; n < cmap->len && n < STM32_LTDC_NCLUT; n++)
+ {
+# ifndef CONFIG_FB_TRANSPARENCY
+ uint8_t *clut888 = (uint8_t *)clut;
+ uint16_t offset = 3 * n;
+
+ cmap->blue[n] = clut888[offset];
+ cmap->green[n] = clut888[offset + 1];
+ cmap->red[n] = clut888[offset + 2];
+
+ reginfo("n=%d, red=%02x, green=%02x, blue=%02x\n", n,
+ clut888[offset], clut888[offset + 1],
+ clut888[offset + 2]);
+# else
+ cmap->transp[n] = (uint8_t)LTDC_CMAP_ALPHA(clut[n]);
+ cmap->red[n] = (uint8_t)LTDC_CMAP_RED(clut[n]);
+ cmap->green[n] = (uint8_t)LTDC_CMAP_GREEN(clut[n]);
+ cmap->blue[n] = (uint8_t)LTDC_CMAP_BLUE(clut[n]);
+
+ reginfo("n=%d, alpha=%02x, red=%02x, green=%02x, blue=%02x\n", n,
+ DMA2D_CMAP_ALPHA(clut[n]), DMA2D_CMAP_RED(clut[n]),
+ DMA2D_CMAP_GREEN(clut[n]), DMA2D_CMAP_BLUE(clut[n]));
+# endif
+ }
+
+ ret = OK;
+ }
+#endif
+ sem_post(priv->state.lock);
+
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+#endif /* STM32_LAYER_CLUT_SIZE */
+
+#ifdef CONFIG_STM32F7_LTDC_INTERFACE
+/****************************************************************************
+ * Name: getlid
+ *
+ * Description:
+ * Get a specific layer identifier.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * lid - Reference to store the layer id
+ * flag - Operation flag describe the layer identifier
+ * e.g. get the current active or inactive layer.
+ * See LTDC_LAYER_* for possible values
+ *
+ * Return:
+ * OK - On success
+ * Null if invalid flag
+ *
+ ****************************************************************************/
+
+static int stm32_getlid(FAR struct ltdc_layer_s *layer, int *lid,
+ uint32_t flag)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("flag = %08x\n", flag);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ int ret = OK;
+
+ sem_wait(priv->state.lock);
+
+ switch (flag)
+ {
+ case LTDC_LAYER_OWN:
+ *lid = priv->state.lid;
+ break;
+#ifdef CONFIG_STM32F7_LTDC_L2
+ case LTDC_LAYER_ACTIVE:
+ *lid = g_lactive;
+ break;
+ case LTDC_LAYER_INACTIVE:
+ *lid = !g_lactive;
+ break;
+ case LTDC_LAYER_TOP:
+ *lid = LTDC_LAYER_L2;
+ break;
+ case LTDC_LAYER_BOTTOM:
+ *lid = LTDC_LAYER_L1;
+ break;
+#else
+ case LTDC_LAYER_ACTIVE:
+ case LTDC_LAYER_INACTIVE:
+ case LTDC_LAYER_TOP:
+ case LTDC_LAYER_BOTTOM:
+ *lid = LTDC_LAYER_L1;
+ break;
+#endif
+#ifdef CONFIG_STM32F7_DMA2D
+ case LTDC_LAYER_DMA2D:
+ ret = priv->dma2d->getlid(priv->dma2d, lid);
+ break;
+#endif
+ default:
+ ret = EINVAL;
+ lcderr("ERROR: Returning EINVAL\n");
+ break;
+ }
+
+ sem_post(priv->state.lock);
+
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_setcolor
+ *
+ * Description:
+ * Configure layer default color value for the non active layer area.
+ * Default value during initializing: 0x00000000
+ * Color is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * argb - ARGB8888 color value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_setcolor(FAR struct ltdc_layer_s *layer, uint32_t argb)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, argb = %08x\n", layer, argb);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ sem_wait(priv->state.lock);
+ priv->state.color = argb;
+ priv->operation |= LTDC_LAYER_SETCOLOR;
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getcolor
+ *
+ * Description:
+ * Get configured layer color for the non active layer area.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * argb - Reference to store the ARGB8888 color value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+*******************************************************************************/
+
+static int stm32_getcolor(FAR struct ltdc_layer_s *layer, uint32_t *argb)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, argb = %p\n", layer, argb);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ sem_wait(priv->state.lock);
+ *argb = priv->state.color;
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_setcolorkey
+ *
+ * Description:
+ * Configure layer default color key (chromakey) value for transparency.
+ * Layer default value during initializing: 0x00000000
+ * Colorkey is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * rgb - RGB888 color value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_setcolorkey(FAR struct ltdc_layer_s *layer, uint32_t rgb)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, argb = %08x\n", layer, rgb);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ sem_wait(priv->state.lock);
+ priv->state.colorkey = rgb;
+ priv->operation |= LTDC_LAYER_SETCOLORKEY;
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getcolorkey
+ *
+ * Description:
+ * Get the configured layer color key (chromakey) for transparency.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * rgb - Reference to store the RGB888 color key
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_getcolorkey(FAR struct ltdc_layer_s *layer, uint32_t *rgb)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, argb = %p\n", layer, rgb);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ sem_wait(priv->state.lock);
+ *rgb = priv->state.colorkey;
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: setalpha
+ *
+ * Description:
+ * Configure layer alpha value factor into blend operation.
+ * During the layer blend operation the source alpha value is multiplied
+ * with this alpha value. If the source color format doesn't support alpha
+ * channel (e.g. non ARGB8888) this alpha value will be used as constant
+ * alpha value for blend operation.
+ * Default alpha value during initializing: 0xff
+ * Alpha is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * alpha - Alpha value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_setalpha(FAR struct ltdc_layer_s *layer, uint8_t alpha)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, alpha = %02x\n", layer, alpha);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ sem_wait(priv->state.lock);
+ priv->state.alpha = alpha;
+ priv->operation |= LTDC_LAYER_SETALPHAVALUE;
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getalpha
+ *
+ * Description:
+ * Get configured layer alpha value factor for blend operation.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * alpha - Reference to store the alpha value
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_getalpha(FAR struct ltdc_layer_s *layer, uint8_t *alpha)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, alpha = %p\n", layer, alpha);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ sem_wait(priv->state.lock);
+ *alpha = priv->state.alpha;
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: setblendmode
+ *
+ * Description:
+ * Configure blend mode of the layer.
+ * Default mode during initializing: LTDC_BLEND_NONE
+ * Blendmode is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - Blend mode (see LTDC_BLEND_*)
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ * Procedure information:
+ * LTDC_BLEND_NONE:
+ * Informs the driver to disable all blend operation for the given layer.
+ * That means the layer is opaque. Note this has no effect on the
+ * colorkey settings.
+ *
+ * LTDC_BLEND_ALPHA:
+ * Informs the driver to enable alpha blending for the given layer.
+ *
+ * LTDC_BLEND_COLORKEY:
+ * Informs the driver to enable colorkeying for the given layer.
+ *
+ * LTDC_BLEND_SRCPIXELALPHA:
+ * Informs the driver to use the pixel alpha value of the layer instead
+ * the constant alpha value. This is only useful for ARGB8888
+ * color format.
+ *
+ * LTDC_BLEND_DESTPIXELALPHA:
+ * Informs the driver to use the pixel alpha value of the subjacent layer
+ * instead the constant alpha value. This is only useful for ARGB8888
+ * color format.
+ *
+ ****************************************************************************/
+
+static int stm32_setblendmode(FAR struct ltdc_layer_s *layer, uint32_t mode)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+ uint32_t blendmode = mode;
+
+ lcdinfo("layer = %p, mode = %08x\n", layer, mode);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ int ret = OK;
+
+ sem_wait(priv->state.lock);
+
+ /* Disable colorkeying by default */
+
+ priv->operation &= ~LTDC_LAYER_ENABLECOLORKEY;
+
+ if (blendmode & (LTDC_BLEND_ALPHA | LTDC_BLEND_PIXELALPHA |
+ LTDC_BLEND_ALPHAINV | LTDC_BLEND_PIXELALPHAINV))
+ {
+ /* Enable any alpha blending */
+
+ stm32_ltdc_lunsetopac(priv);
+ }
+ else
+ {
+ /* Disable any alpha blending */
+
+ stm32_ltdc_lsetopac(priv);
+ }
+
+ if (blendmode & LTDC_BLEND_ALPHA || blendmode == LTDC_BLEND_NONE)
+ {
+ /* alpha blending introduce LTDC_BLEND_ALPHAINV */
+
+ priv->bf1 = LTDC_BF1_CONST_ALPHA;
+ priv->bf2 = LTDC_BF2_CONST_ALPHA;
+ blendmode &= ~LTDC_BLEND_ALPHA;
+ }
+
+ if (blendmode & LTDC_BLEND_PIXELALPHA)
+ {
+ /* pixel alpha blending introduce LTDC_BLEND_PIXELALPHAINV */
+
+ priv->bf1 = LTDC_BF1_PIXEL_ALPHA;
+ priv->bf2 = LTDC_BF2_PIXEL_ALPHA;
+ blendmode &= ~LTDC_BLEND_PIXELALPHA;
+ }
+
+ if (blendmode & LTDC_BLEND_ALPHAINV)
+ {
+ /* alpha blending of source input */
+
+ priv->bf2 = LTDC_BF2_CONST_ALPHA;
+ blendmode &= ~LTDC_BLEND_ALPHAINV;
+ }
+
+ if (blendmode & LTDC_BLEND_PIXELALPHAINV)
+ {
+ /* pixel alpha blending of source input */
+
+ priv->bf2 = LTDC_BF2_PIXEL_ALPHA;
+ blendmode &= ~LTDC_BLEND_PIXELALPHAINV;
+ }
+
+ if (mode & LTDC_BLEND_COLORKEY)
+ {
+ /* Enable colorkeying */
+
+ priv->operation |= LTDC_LAYER_ENABLECOLORKEY;
+ blendmode &= ~LTDC_BLEND_COLORKEY;
+ }
+ if (blendmode)
+ {
+ lcderr("ERROR: Unknown blendmode %02x\n", blendmode);
+ ret = -EINVAL;
+ }
+
+ if (ret == OK)
+ {
+ priv->state.blendmode = mode;
+ priv->operation |= (LTDC_LAYER_SETBLENDMODE |
+ LTDC_LAYER_SETALPHAVALUE |
+ LTDC_LAYER_SETCOLORKEY);
+ }
+
+ sem_post(priv->state.lock);
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getblendmode
+ *
+ * Description:
+ * Get configured blend mode of the layer.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - Reference to store the blend mode
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ ****************************************************************************/
+
+static int stm32_getblendmode(FAR struct ltdc_layer_s *layer, uint32_t *mode)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, mode = %p\n", layer, mode);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ sem_wait(priv->state.lock);
+ *mode = priv->state.blendmode;
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_setarea
+ *
+ * Description:
+ * Configure visible layer area and the reference position of the first
+ * pixel of the whole layer which is the first visible top left pixel in
+ * the active area.
+ * Area is active after next update.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * area - Reference to the valid area structure for the new active area
+ * srcxpos - x position of the visible pixel of the whole layer
+ * srcypos - y position of the visible pixel of the whole layer
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ * Procedure Information:
+ * If the srcxpos and srcypos unequal the xpos and ypos of the area
+ * structure this acts like moving the visible area to another position on
+ * the screen during the next update operation.
+ *
+ ****************************************************************************/
+
+static int stm32_setarea(FAR struct ltdc_layer_s *layer,
+ FAR const struct ltdc_area_s *area,
+ fb_coord_t srcxpos,
+ fb_coord_t srcypos)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, area = %p, srcxpos = %d, srcypos = %d\n",
+ layer, area, srcxpos, srcypos);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ int ret;
+
+ sem_wait(priv->state.lock);
+
+ ret = stm32_ltdc_lvalidatearea(priv, area->xpos, area->ypos, area->xres,
+ area->yres, srcxpos, srcypos);
+
+ if (ret == OK)
+ {
+ priv->state.xpos = srcxpos;
+ priv->state.ypos = srcypos;
+ priv->state.area.xpos = area->xpos;
+ priv->state.area.ypos = area->ypos;
+ priv->state.area.xres = area->xres;
+ priv->state.area.yres = area->yres;
+ priv->operation |= LTDC_LAYER_SETAREA;
+ }
+
+ sem_post(priv->state.lock);
+
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_getarea
+ *
+ * Description:
+ * Get configured visible layer area.
+ *
+ * Parameter:
+ * layer - Reference to the layer control structure
+ * area - Reference to the area structure to store the active area
+ * srcxpos - Reference to store the referenced x position of the whole layer
+ * srcypos - Reference to store the reterenced y position of the whole layer
+ *
+ * Return:
+ * On success - OK
+ * On error - -EINVAL
+ *
+ ****************************************************************************/
+
+static int stm32_getarea(FAR struct ltdc_layer_s *layer,
+ FAR struct ltdc_area_s *area,
+ fb_coord_t *srcxpos, fb_coord_t *srcypos)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, area = %p, srcxpos = %p, srcypos = %p\n",
+ layer, area, srcxpos, srcypos);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ sem_wait(priv->state.lock);
+ *srcxpos = priv->state.xpos;
+ *srcypos = priv->state.ypos;
+ memcpy(area, &priv->state.area, sizeof(struct ltdc_area_s));
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_update
+ *
+ * Description:
+ * Update current layer settings and make changes visible.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * mode - operation mode
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid
+ * -ECANCELED - Operation cancelled, something goes wrong
+ *
+ * Procedure information:
+ * LTDC_UPDATE_SIM:
+ * Informs the driver to update both layers simultaneously. Otherwise update
+ * the given layer only.
+ *
+ * LTDC_UPDATE_FLIP:
+ * Informs the driver to perform a flip operation.
+ * This only effects the ltdc layer 1 and 2 and can be useful for double
+ * buffering. Each flip operation changed the active layer to the inactive
+ * and vice versa. In the context of the ltdc that means, the inactive layer
+ * is complete disabled. So the subjacent layer is the background layer
+ * (background color). To reactivate both layer and their current settings
+ * perform an update without LTDC_UPDATE_FLIP flag.
+ *
+ * LTDC_UPDATE_ACTIVATE:
+ * Informs the driver that the given layer should be the active layer when
+ * the operation is complete.
+ *
+ * LTDC_SYNC_VBLANK:
+ * Informs the driver to update the layer upon vertical blank. Otherwise
+ * immediately.
+ *
+ ****************************************************************************/
+
+static int stm32_update(FAR struct ltdc_layer_s *layer, uint32_t mode)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+#ifdef CONFIG_STM32F7_LTDC_L2
+ FAR struct stm32_layer_s *active = &LAYER(g_lactive);
+ FAR struct stm32_layer_s *inactive = &LAYER(!g_lactive);
+#endif
+
+ lcdinfo("layer = %p, mode = %08x\n", layer, mode);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ /* Reload immediately by default */
+
+ bool waitvblank = false;
+ uint8_t reload = LTDC_SRCR_IMR;
+
+ sem_wait(priv->state.lock);
+
+ if (mode & LTDC_SYNC_VBLANK)
+ {
+ reload = LTDC_SRCR_VBR;
+ }
+
+ if (mode & LTDC_SYNC_WAIT)
+ {
+ waitvblank = true;
+ }
+
+ /* Ensures that last register reload operation has been completed */
+
+ if (stm32_ltdc_waitforirq() != OK)
+ {
+ lcderr("ERROR: Returning ECANCELED\n");
+ return -ECANCELED;
+ }
+
+ /* Update the given layer */
+
+ stm32_ltdc_lupdate(priv);
+
+#ifdef CONFIG_STM32F7_LTDC_L2
+ /* The following operation only useful if layer 2 is supported.
+ * Otherwise ignore it.
+ */
+
+ if (mode & LTDC_UPDATE_SIM)
+ {
+ /* Also update the flip layer */
+
+ stm32_ltdc_lupdate(&LAYER(!priv->state.lid));
+ }
+
+ if (mode & LTDC_UPDATE_ACTIVATE)
+ {
+ /* Set the given layer to the next active layer */
+
+ g_lactive = priv->state.lid;
+
+ /* Also change the current active layer for flip operation */
+
+ active = &LAYER(!g_lactive);
+ }
+
+ if (mode & LTDC_UPDATE_FLIP)
+ {
+ /* Reset if manipulated by ACTIVATE flag */
+
+ inactive = &LAYER(!active->state.lid);
+
+ /* Set blendfactor for current active layer to there reset value */
+
+ stm32_ltdc_lblendmode(active, STM32_LTDC_BF1_RESET,
+ STM32_LTDC_BF2_RESET);
+
+ /* Set blendfactor for current inactive layer */
+
+ stm32_ltdc_lblendmode(inactive, inactive->bf1, inactive->bf2);
+
+ /* Disable the active layer */
+
+ active->operation &= ~LTDC_LAYER_ENABLE;
+
+ stm32_ltdc_lenable(active);
+
+ /* Enable the inactive layer */
+
+ inactive->operation |= LTDC_LAYER_ENABLE;
+
+ stm32_ltdc_lenable(inactive);
+
+ /* Ensure that both layer active and the manipulated layer
+ * settings restored during the next update (non flip) operation
+ */
+
+ active->operation |= (LTDC_LAYER_SETBLENDMODE |
+ LTDC_LAYER_ENABLE |
+ LTDC_LAYER_SETCOLOR |
+ LTDC_LAYER_SETENABLE);
+
+ /* Change layer activity */
+
+ g_lactive = inactive->state.lid;
+ }
+#endif
+
+ /* Make the changes visible */
+
+ stm32_ltdc_reload(reload, waitvblank);
+
+ sem_post(priv->state.lock);
+
+ return OK;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+#ifdef CONFIG_STM32F7_DMA2D
+/****************************************************************************
+ * Name: stm32_blit
+ *
+ * Description:
+ * Copy selected area from a source layer to selected position of the
+ * destination layer.
+ *
+ * Parameter:
+ * dest - Reference to the destination layer
+ * destxpos - Selected x position of the destination layer
+ * destypos - Selected y position of the destination layer
+ * src - Reference to the source layer
+ * srcarea - Reference to the selected area of the source layer
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * source area outside the visible area of the destination layer.
+ * (The visible area usually represents the display size)
+ *
+ ****************************************************************************/
+
+static int stm32_blit(FAR struct ltdc_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *src,
+ FAR const struct ltdc_area_s *srcarea)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)dest;
+
+ lcdinfo("dest = %p, destxpos = %d, destypos = %d, src = %p, srcarea = %p\n",
+ dest, destxpos, destypos, src, srcarea);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ int ret;
+
+ sem_wait(priv->state.lock);
+ ret = priv->dma2d->blit(priv->dma2d, destxpos, destypos, src, srcarea);
+ sem_post(priv->state.lock);
+
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: stm32_blend
+ *
+ * Description:
+ * Blends the selected area from a foreground layer with selected position
+ * of the background layer. Copy the result to the destination layer. Note!
+ * The content of the foreground and background layer is not changed.
+ *
+ * Parameter:
+ * dest - Reference to the destination layer
+ * destxpos - Selected x position of the destination layer
+ * destypos - Selected y position of the destination layer
+ * fore - Reference to the foreground layer
+ * forexpos - Selected x position of the foreground layer
+ * foreypos - Selected y position of the foreground layer
+ * back - Reference to the background layer
+ * backarea - Reference to the selected area of the background layer
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * source area outside the visible area of the destination layer.
+ * (The visible area usually represents the display size)
+ *
+ ****************************************************************************/
+
+static int stm32_blend(FAR struct ltdc_layer_s *dest,
+ fb_coord_t destxpos, fb_coord_t destypos,
+ FAR const struct dma2d_layer_s *fore,
+ fb_coord_t forexpos, fb_coord_t foreypos,
+ FAR const struct dma2d_layer_s *back,
+ FAR const struct ltdc_area_s *backarea)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)dest;
+
+ lcdinfo("dest=%p, destxpos=%d, destypos=%d, "
+ "fore=%p, forexpos=%d foreypos=%d, "
+ "back=%p, backarea=%p\n",
+ dest, destxpos, destypos, fore, forexpos, foreypos, back, backarea);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ int ret;
+
+ sem_wait(priv->state.lock);
+ ret = priv->dma2d->blend(priv->dma2d, destxpos, destypos,
+ fore, forexpos, foreypos, back, backarea);
+ sem_post(priv->state.lock);
+
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+
+/****************************************************************************
+ * Name: fillarea
+ *
+ * Description:
+ * Fill the selected area of the whole layer with a specific color.
+ *
+ * Parameter:
+ * layer - Reference to the layer structure
+ * area - Reference to the valid area structure select the area
+ * color - Color to fill the selected area. Color must be formatted
+ * according to the layer pixel format.
+ *
+ * Return:
+ * OK - On success
+ * -EINVAL - If one of the parameter invalid or if the size of the selected
+ * area outside the visible area of the layer.
+ *
+ ****************************************************************************/
+
+static int stm32_fillarea(FAR struct ltdc_layer_s *layer,
+ FAR const struct ltdc_area_s *area,
+ uint32_t color)
+{
+ FAR struct stm32_layer_s *priv = (FAR struct stm32_layer_s *)layer;
+
+ lcdinfo("layer = %p, area = %p, color = %08x\n", layer, area, color);
+
+ if (stm32_ltdc_lvalidate(priv))
+ {
+ int ret;
+
+ sem_wait(priv->state.lock);
+ ret = priv->dma2d->fillarea(priv->dma2d, area, color);
+ sem_post(priv->state.lock);
+
+ return ret;
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ return -EINVAL;
+}
+#endif
+
+/****************************************************************************
+ * Name: stm32_ltdcgetlayer
+ *
+ * Description:
+ * This is a non-standard framebuffer interface.
+ * Get the specific layer object by the layer id to enable layer hardware
+ * support.
+ *
+ * Parameter:
+ * lid - Layer identifier
+ *
+ * Return:
+ * Reference to the layer control structure on success or Null if lid
+ * is invalid.
+ *
+ ****************************************************************************/
+
+FAR struct ltdc_layer_s *stm32_ltdcgetlayer(int lid)
+{
+ lcdinfo("lid: %d\n", lid);
+
+ if (lid == LTDC_LAYER_L1 || lid == LTDC_LAYER_L2)
+ {
+ return (FAR struct ltdc_layer_s *) &LAYER(lid);
+ }
+
+ lcderr("ERROR: Returning EINVAL\n");
+ errno = EINVAL;
+ return NULL;
+}
+#endif /* CONFIG_STM32F7_LTDC_INTERFACE */
+
+/****************************************************************************
+ * Name: stm32_ltdcinitialize
+ *
+ * Description:
+ * Initialize the ltdc controller
+ *
+ * Return:
+ * OK
+ *
+ ****************************************************************************/
+
+int stm32_ltdcinitialize(void)
+{
+#ifdef CONFIG_STM32F7_DMA2D
+ int ret;
+#endif
+
+ lcdinfo("Initialize LTDC driver\n");
+
+ if (g_initialized == true)
+ {
+ return OK;
+ }
+
+ /* Disable the LCD */
+
+ stm32_lcd_enable(false);
+
+ lcdinfo("Configuring the LCD controller\n");
+
+ /* Configure LCD periphery */
+
+ lcdinfo("Configure lcd periphery\n");
+ stm32_ltdc_periphconfig();
+
+ /* Configure global ltdc register */
+
+ lcdinfo("Configure global register\n");
+ stm32_global_configure();
+
+#ifdef CONFIG_STM32F7_DMA2D
+ /* Initialize the dma2d controller */
+
+ ret = up_dma2dinitialize();
+
+ if (ret != OK)
+ {
+ return ret;
+ }
+#endif
+
+ /* Initialize ltdc layer */
+
+ lcdinfo("Initialize ltdc layer\n");
+ stm32_ltdc_linit(LTDC_LAYER_L1);
+#ifdef CONFIG_STM32F7_LTDC_L2
+ stm32_ltdc_linit(LTDC_LAYER_L2);
+#endif
+
+ /* Display layer 1 and 2 */
+
+ stm32_ltdc_lenable(&LAYER_L1);
+#ifdef CONFIG_STM32F7_LTDC_L2
+ stm32_ltdc_lenable(&LAYER_L2);
+#endif
+
+ /* Enable the backlight */
+
+#ifdef CONFIG_STM32F7_LCD_BACKLIGHT
+ stm32_backlight(true);
+#endif
+
+ /* Reload shadow register */
+
+ lcdinfo("Reload shadow register\n");
+ stm32_ltdc_reload(LTDC_SRCR_IMR, false);
+
+ /* Turn the LCD on */
+
+ lcdinfo("Enabling the display\n");
+ stm32_lcd_enable(true);
+
+ /* Set initialized state */
+
+ g_initialized = true;
+ return OK;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdcgetvplane
+ *
+ * Description:
+ * Return a a reference to the framebuffer object for the specified video
+ * plane.
+ *
+ * Input parameters:
+ * None
+ *
+ * Returned value:
+ * Reference to the framebuffer object (NULL on failure)
+ *
+ ****************************************************************************/
+
+struct fb_vtable_s *stm32_ltdcgetvplane(int vplane)
+{
+ lcdinfo("vplane: %d\n", vplane);
+
+ if (vplane == 0)
+ {
+ return (struct fb_vtable_s *)&g_vtable;
+ }
+
+ return NULL;
+}
+
+/****************************************************************************
+ * Name: stm32_ltdcuninitialize
+ *
+ * Description:
+ * Uninitialize the framebuffer driver. Bad things will happen if you
+ * call this without first calling fb_initialize()!
+ *
+ ****************************************************************************/
+
+void stm32_ltdcuninitialize(void)
+{
+ /* Disable all ltdc interrupts */
+
+ stm32_ltdc_irqctrl(0, LTDC_IER_RRIE | LTDC_IER_TERRIE |
+ LTDC_IER_FUIE | LTDC_IER_LIE);
+
+ up_disable_irq(g_interrupt.irq);
+ irq_detach(g_interrupt.irq);
+
+ /* Disable the LCD controller */
+
+ stm32_lcd_enable(false);
+
+ /* Set initialized state */
+
+ g_initialized = false;
+}
+
+/****************************************************************************
+ * Name: stm32_lcdclear
+ *
+ * Description:
+ * This is a non-standard LCD interface just for the STM32 LTDC. Clearing the
+ * display in the normal way by writing a sequences of runs that covers the
+ * entire display can be slow. Here the display is cleared by simply setting
+ * all video memory to the specified color.
+ *
+ * Parameter:
+ * color - The color the clear the whole framebuffer
+ *
+ ****************************************************************************/
+
+void stm32_lcdclear(nxgl_mxpixel_t color)
+{
+#ifdef CONFIG_STM32F7_LTDC_L2
+ stm32_ltdc_lclear(&LAYER(LTDC_LAYER_L2), color);
+#endif
+ stm32_ltdc_lclear(&LAYER(LTDC_LAYER_L1), color);
+}
+
+/****************************************************************************
+ * Name: stm32_lcd_backlight
+ *
+ * Description:
+ * Provide this interface to turn the backlight on and off.
+ *
+ * Parameter:
+ * blon - Enable or disable the lcd backlight
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_STM32F7_LCD_BACKLIGHT
+void stm32_backlight(bool blon)
+{
+ /* Set default backlight level CONFIG_STM32F7_LTDC_DEFBACKLIGHT */
+
+ lcderr("ERROR: Not supported\n");
+}
+#endif
diff --git a/arch/arm/src/stm32f7/stm32_ltdc.h b/arch/arm/src/stm32f7/stm32_ltdc.h
new file mode 100755
index 00000000000..c0e46986363
--- /dev/null
+++ b/arch/arm/src/stm32f7/stm32_ltdc.h
@@ -0,0 +1,157 @@
+/************************************************************************************
+ * arch/arm/src/stm32/stm32_ltdc.h
+ *
+ * Copyright (C) 2013-2014 Ken Pettit. All rights reserved.
+ * Authors: Ken Pettit
+ * Marco Krahl
+ *
+ * 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 __ARCH_ARM_SRC_STM32F7_STM32_LTDC_H
+#define __ARCH_ARM_SRC_STM32F7_STM32_LTDC_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#include
+
+#ifdef CONFIG_STM32F7_LTDC
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Types
+ ************************************************************************************/
+
+/* Common layer state structure for the LTDC and DMA2D controller */
+
+struct stm32_ltdc_s
+{
+ /* Fixed settings */
+
+ int lid; /* Layer identifier */
+ struct fb_videoinfo_s vinfo; /* Layer videoinfo */
+ struct fb_planeinfo_s pinfo; /* Layer planeinfo */
+
+ /* Positioning */
+
+ struct ltdc_area_s area; /* Active layer area */
+ fb_coord_t xpos; /* Reference x position */
+ fb_coord_t ypos; /* Reference y position */
+
+ /* Coloring */
+
+ uint32_t color; /* Layer color definition */
+#ifdef CONFIG_FB_CMAP
+ uint32_t *clut; /* 32-bit aligned clut color table */
+#endif
+
+ /* Blending */
+
+ uint8_t alpha; /* Layer constant alpha value */
+ uint32_t colorkey; /* Layer colorkey */
+ uint32_t blendmode; /* Layer blend factor */
+
+ /* Operation */
+
+ sem_t *lock; /* Ensure mutually exclusive access */
+};
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+/* The STM32 LTDC driver uses the common framebuffer interfaces declared in
+ * include/nuttx/video/fb.h.
+ */
+
+int stm32_ltdcinitialize(void);
+FAR struct fb_vtable_s *stm32_ltdcgetvplane(int vplane);
+void stm32_ltdcuninitialize(void);
+
+/************************************************************************************
+ * Name: stm32_ltdcgetlayer
+ *
+ * Description:
+ * Get the ltdc layer structure to perform hardware layer operation
+ *
+ * Parameter:
+ * lid - Layer identifier
+ *
+ * Return:
+ * Reference to the layer control structure on success or Null if parameter
+ * invalid.
+ *
+ ************************************************************************************/
+
+FAR struct ltdc_layer_s *stm32_ltdcgetlayer(int lid);
+
+/************************************************************************************
+ * Name: stm32_lcdclear
+ *
+ * Description:
+ * This is a non-standard LCD interface just for the STM32 LTDC. Clearing the
+ * display in the normal way by writing a sequences of runs that covers the
+ * entire display can be slow. Here the display is cleared by simply setting
+ * all video memory to the specified color.
+ *
+ ************************************************************************************/
+
+void stm32_lcdclear(nxgl_mxpixel_t color);
+
+/************************************************************************************
+ * Name: stm32_lcd_backlight
+ *
+ * Description:
+ * If CONFIG_STM32F7_LCD_BACKLIGHT is defined, then the board-specific logic must
+ * provide this interface to turn the backlight on and off.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_STM32F7_LCD_BACKLIGHT
+void stm32_backlight(bool blon);
+#endif
+
+#endif /* CONFIG_STM32F7_LTDC */
+#endif /* __ARCH_ARM_SRC_STM32F7_STM32_LTDC_H */
diff --git a/arch/arm/src/stm32f7/stm32f76xx77xx_rcc.c b/arch/arm/src/stm32f7/stm32f76xx77xx_rcc.c
index 5a08806eb3a..f43aa27b0b1 100644
--- a/arch/arm/src/stm32f7/stm32f76xx77xx_rcc.c
+++ b/arch/arm/src/stm32f7/stm32f76xx77xx_rcc.c
@@ -909,7 +909,7 @@ static void stm32_stdclockconfig(void)
| RCC_DCKCFGR2_CK48MSEL_MASK
| RCC_DCKCFGR2_SDMMCSEL_MASK
| RCC_DCKCFGR2_SDMMC2SEL_MASK
- | RCC_DCKCFGR2_DSISELL_MASK);
+ | RCC_DCKCFGR2_DSISEL_MASK);
regval |= ( STM32_RCC_DCKCFGR2_USART1SRC
| STM32_RCC_DCKCFGR2_USART2SRC
diff --git a/configs/Kconfig b/configs/Kconfig
old mode 100644
new mode 100755
index c7f8704765d..0257f18af2c
--- a/configs/Kconfig
+++ b/configs/Kconfig
@@ -1160,6 +1160,17 @@ config ARCH_BOARD_STM32F746G_DISCO
MCU. The STM32F746NGH6 is a 216MHz Cortex-M7 operation with 1024Kb Flash
memory and 320Kb SRAM.
+config ARCH_BOARD_STM32F769I_DISCO
+ bool "STMicro STM32F769I-Discovery board"
+ depends on ARCH_CHIP_STM32F769NI
+ select ARCH_HAVE_LEDS
+ select ARCH_HAVE_BUTTONS
+ select ARCH_HAVE_IRQBUTTONS
+ ---help---
+ STMicro STM32F769I-DISCO development board featuring the STM32F769NIH6
+ MCU. The STM32F769NIH6 is a 216MHz Cortex-M7 with 1024Kb Flash
+ memory and 320Kb SRAM.
+
config ARCH_BOARD_STM32F746_WS
bool "Waveshare STM32F746 board"
depends on ARCH_CHIP_STM32F746IG
@@ -1621,6 +1632,7 @@ config ARCH_BOARD
default "stm32f411e-disco" if ARCH_BOARD_STM32F411E_DISCO
default "stm32f429i-disco" if ARCH_BOARD_STM32F429I_DISCO
default "stm32f746g-disco" if ARCH_BOARD_STM32F746G_DISCO
+ default "stm32f769i-disco" if ARCH_BOARD_STM32F769I_DISCO
default "stm32f746-ws" if ARCH_BOARD_STM32F746_WS
default "b-l475e-iot01a" if ARCH_BOARD_B_L475E_IOT01A
default "stm32l476vg-disco" if ARCH_BOARD_STM32L476VG_DISCO
@@ -2014,6 +2026,9 @@ endif
if ARCH_BOARD_STM32F746G_DISCO
source "configs/stm32f746g-disco/Kconfig"
endif
+if ARCH_BOARD_STM32F769I_DISCO
+source "configs/stm32f769i-disco/Kconfig"
+endif
if ARCH_BOARD_B_L475E_IOT01A
source "configs/b-l475e-iot01a/Kconfig"
endif
diff --git a/configs/README.txt b/configs/README.txt
index c17dfb63568..2caf70874e0 100644
--- a/configs/README.txt
+++ b/configs/README.txt
@@ -685,6 +685,11 @@ configs/stm32l476-mdk
The STM32L476ME is a Cortex-M4 optimised for low-power operation
at up to 80MHz operation with 1024Kb Flash memory and 96+32Kb SRAM.
+configs/stm32f769i-disco
+ NuttX configurations for the STMicro STM32F769I-DISCO development board
+ featuring the STM32F769NIH6 MCU. The STM32F769NIH6 is a 216MHz Cortex-M7
+ operating with 2048K Flash memory and 512Kb SRAM.
+
configs/stm32l476vg-disco
STMicro STM32L476VG_DISCO development board featuring the STM32L476VG
MCU. The STM32L476VG is a Cortex-M4 optimised for low-power operation
diff --git a/configs/nucleo-144/include/board.h b/configs/nucleo-144/include/board.h
index 1027e514ec4..ac06c1fca97 100644
--- a/configs/nucleo-144/include/board.h
+++ b/configs/nucleo-144/include/board.h
@@ -170,7 +170,6 @@
#define STM32_RCC_DCKCFGR2_CK48MSRC RCC_DCKCFGR2_CK48MSEL_PLL
#define STM32_RCC_DCKCFGR2_SDMMCSRC RCC_DCKCFGR2_SDMMCSEL_48MHZ
#define STM32_RCC_DCKCFGR2_SDMMC2SRC RCC_DCKCFGR2_SDMMC2SEL_48MHZ
-#define STM32_RCC_DCKCFGR2_DSISRC RCC_DCKCFGR2_DSISEL_48MHZ
/* Several prescalers allow the configuration of the two AHB buses, the
diff --git a/configs/stm32f746-ws/include/board.h b/configs/stm32f746-ws/include/board.h
index b58542d120e..d8c80f0677c 100644
--- a/configs/stm32f746-ws/include/board.h
+++ b/configs/stm32f746-ws/include/board.h
@@ -167,7 +167,6 @@
#define STM32_RCC_DCKCFGR2_CK48MSRC RCC_DCKCFGR2_CK48MSEL_PLLSAI
#define STM32_RCC_DCKCFGR2_SDMMCSRC RCC_DCKCFGR2_SDMMCSEL_48MHZ
#define STM32_RCC_DCKCFGR2_SDMMC2SRC RCC_DCKCFGR2_SDMMC2SEL_48MHZ
-#define STM32_RCC_DCKCFGR2_DSISRC RCC_DCKCFGR2_DSISEL_48MHZ
/* Several prescalers allow the configuration of the two AHB buses, the
* high-speed APB (APB2) and the low-speed APB (APB1) domains. The maximum
diff --git a/configs/stm32f746g-disco/README.txt b/configs/stm32f746g-disco/README.txt
index 651d5aca936..29af88a71d2 100644
--- a/configs/stm32f746g-disco/README.txt
+++ b/configs/stm32f746g-disco/README.txt
@@ -340,11 +340,11 @@ STM32F746G-DISCO-specific Configuration Options
CONFIG_STM32F7_DMA2 DMA2
CONFIG_STM32F7_ETHMAC Ethernet MAC
CONFIG_STM32F7_DMA2D Chrom-ART (DMA2D)
- CONFIG_STM32F7_USBOTGHS USB OTG HS
+ CONFIG_STM32F7_OTGHS USB OTG HS
AHB2
----
- CONFIG_STM32F7_USBOTGFS USB OTG FS
+ CONFIG_STM32F7_OTGFS USB OTG FS
CONFIG_STM32F7_DCMI DCMI
CONFIG_STM32F7_CRYP CRYP
CONFIG_STM32F7_HASH HASH
diff --git a/configs/stm32f746g-disco/include/board.h b/configs/stm32f746g-disco/include/board.h
index 94823714990..0964e6b90f0 100644
--- a/configs/stm32f746g-disco/include/board.h
+++ b/configs/stm32f746g-disco/include/board.h
@@ -103,7 +103,7 @@
* 2 <= PLLQ <= 15
*/
-#if defined(CONFIG_STM32F7_USBOTHFS)
+#if defined(CONFIG_STM32F7_OTGFS)
/* Highest SYSCLK with USB OTG FS clock = 48 MHz
*
* PLL_VCO = (25,000,000 / 25) * 384 = 384 MHz
@@ -199,7 +199,6 @@
#define STM32_RCC_DCKCFGR2_CK48MSRC RCC_DCKCFGR2_CK48MSEL_PLLSAI
#define STM32_RCC_DCKCFGR2_SDMMCSRC RCC_DCKCFGR2_SDMMCSEL_48MHZ
#define STM32_RCC_DCKCFGR2_SDMMC2SRC RCC_DCKCFGR2_SDMMC2SEL_48MHZ
-#define STM32_RCC_DCKCFGR2_DSISRC RCC_DCKCFGR2_DSISEL_48MHZ
/* Several prescalers allow the configuration of the two AHB buses, the
* high-speed APB (APB2) and the low-speed APB (APB1) domains. The maximum
diff --git a/configs/stm32f769i-disco/Kconfig b/configs/stm32f769i-disco/Kconfig
new file mode 100644
index 00000000000..ff5c8e1a003
--- /dev/null
+++ b/configs/stm32f769i-disco/Kconfig
@@ -0,0 +1,8 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+if ARCH_BOARD_STM32F769I_DISCO
+
+endif # ARCH_BOARD_STM32F769I_DISCO
diff --git a/configs/stm32f769i-disco/README.txt b/configs/stm32f769i-disco/README.txt
new file mode 100644
index 00000000000..e3921dab2fa
--- /dev/null
+++ b/configs/stm32f769i-disco/README.txt
@@ -0,0 +1,127 @@
+README
+======
+
+This README discusses issues unique to NuttX configurations for the
+STMicro STM32F769I-DISCO development board featuring the STM32F769NIH6
+MCU. The STM32F769NIH6 is a 216MHz Cortex-M7 operating with 2048K Flash
+memory and 512Kb SRAM. The board features:
+
+ - On-board ST-LINK/V2 for programming and debugging,
+ - Mbed-enabled (mbed.org)
+ - 4-inch 800x472 color LCD-TFT with capacitive touch screen
+ - SAI audio codec
+ - Audio line in and line out jack
+ - Two ST MEMS microphones
+ - SPDIF RCA input connector
+ - Two pushbuttons (user and reset)
+ - 512-Mbit Quad-SPI Flash memory
+ - 128-Mbit SDRAM
+ - Connector for microSD card
+ - RF-EEPROM daughterboard connector
+ - USB OTG HS with Micro-AB connectors
+ - Ethernet connector compliant with IEEE-802.3-2002 and PoE
+
+Refer to the http://www.st.com website for further information about this
+board (search keyword: stm32f769i-disco)
+
+Contents
+========
+
+ - STATUS
+ - Development Environment
+ - LEDs and Buttons
+ - Serial Console
+ - Configurations
+
+STATUS
+======
+
+ 2017-07: The basic NSH configuration is functional using a serial
+ console on USART1, which is connected to the "virtual com port"
+ of the ST/LINK USB adapter.
+
+ 2017-07: STM32 F7 Ethernet appears to be functional, but has had
+ only light testing.
+
+ Work in progress: Use LCD over DSI interface, rest of board.
+
+Development Environment
+=======================
+
+ The Development environments for the STM32F769I-DISCO board are identical
+ to the environments for other STM32F boards. For full details on the
+ environment options and setup, see the README.txt file in the
+ config/stm32f769i-disco directory.
+
+LEDs and Buttons
+================
+
+ LEDs
+ ----
+ The STM32F769I-DISCO board has numerous LEDs but only one, LD3 located
+ near the reset button, that can be controlled by software.
+
+ LD3 is controlled by PI1 which is also the SPI2_SCK at the Arduino
+ interface. One end of LD3 is grounded so a high output on PI1 will
+ illuminate the LED.
+
+ This LED is not used by the board port unless CONFIG_ARCH_LEDS is defined.
+ In that case, the usage by the board port is defined in include/board.h
+ and src/stm32_leds.c. The LEDs are used to encode OS-related events as
+ follows:
+
+ SYMBOL Meaning LD3
+ ------------------- ----------------------- ------
+ LED_STARTED NuttX has been started OFF
+ LED_HEAPALLOCATE Heap has been allocated OFF
+ LED_IRQSENABLED Interrupts enabled OFF
+ LED_STACKCREATED Idle stack created ON
+ LED_INIRQ In an interrupt N/C
+ LED_SIGNAL In a signal handler N/C
+ LED_ASSERTION An assertion failed N/C
+ LED_PANIC The system has crashed FLASH
+
+ Thus is LD3 is statically on, NuttX has successfully booted and is,
+ apparently, running normally. If LD3 is flashing at approximately
+ 2Hz, then a fatal error has been detected and the system has halted.
+
+ Buttons
+ -------
+ Pushbutton B1, labelled "User", is connected to GPIO PI11. A high
+ value will be sensed when the button is depressed.
+
+Serial Console
+==============
+
+ Use the serial interface the ST/LINK provides to the USB host.
+
+Configurations
+==============
+
+ Common Configuration Information
+ --------------------------------
+ Each STM32F769I-DISCO configuration is maintained in a sub-directory and
+ can be selected as follow:
+
+ cd tools
+ ./configure.sh stm32f769i-disco/
+ cd -
+
+ Where is one of the sub-directories listed below.
+
+Configuration Directories
+-------------------------
+
+ nsh:
+ ---
+ Configures the NuttShell (NSH) located at apps/examples/nsh. The
+ Configuration enables the serial interfaces on UART1.
+ Otherwise nothing is enabled, so that config is a starting point
+ for initial testing.
+ Support for builtin applications is enabled, but in the base
+ configuration no builtin applications are selected.
+
+ nsh-ehternet:
+ ---
+ Same as above but a lot more hardware peripherals enabled,
+ in particular ethernet, as well as networking stuff.
diff --git a/configs/stm32f769i-disco/include/board.h b/configs/stm32f769i-disco/include/board.h
new file mode 100644
index 00000000000..6cdef6b7c1d
--- /dev/null
+++ b/configs/stm32f769i-disco/include/board.h
@@ -0,0 +1,519 @@
+/************************************************************************************
+ * configs/stm32f769i-disco/include/board.h
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 __CONFIG_STM32F769I_DISCO_INCLUDE_BOARD_H
+#define __CONFIG_STM32F769I_DISCO_INCLUDE_BOARD_H
+
+/************************************************************************************
+ * Included Files
+ ************************************************************************************/
+
+#include
+
+#ifndef __ASSEMBLY__
+# include
+#endif
+
+#include "stm32_rcc.h"
+#if defined(CONFIG_STM32F7_SDMMC1) || defined(CONFIG_STM32F7_SDMMC2)
+# include "stm32_sdmmc.h"
+#endif
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/* Clocking *************************************************************************/
+/* The STM32F7 Discovery board provides the following clock sources:
+ *
+ * X2: 25 MHz oscillator for STM32F769NIH6 microcontroller and Ethernet PHY.
+ * X1: 32.768 KHz crystal for STM32F769NIH6 embedded RTC
+ *
+ * So we have these clock source available within the STM32
+ *
+ * HSI: 16 MHz RC factory-trimmed
+ * LSI: 32 KHz RC
+ * HSE: On-board crystal frequency is 25MHz
+ * LSE: 32.768 kHz
+ */
+
+#define STM32_BOARD_XTAL 25000000ul
+
+#define STM32_HSI_FREQUENCY 16000000ul
+#define STM32_LSI_FREQUENCY 32000
+#define STM32_HSE_FREQUENCY STM32_BOARD_XTAL
+#define STM32_LSE_FREQUENCY 32768
+
+/* Main PLL Configuration.
+ *
+ * PLL source is HSE = 25,000,000
+ *
+ * PLL_VCO = (STM32_HSE_FREQUENCY / PLLM) * PLLN
+ * Subject to:
+ *
+ * 2 <= PLLM <= 63
+ * 192 <= PLLN <= 432
+ * 192 MHz <= PLL_VCO <= 432MHz
+ *
+ * SYSCLK = PLL_VCO / PLLP
+ * Subject to
+ *
+ * PLLP = {2, 4, 6, 8}
+ * SYSCLK <= 216 MHz
+ *
+ * USB OTG FS, SDMMC and RNG Clock = PLL_VCO / PLLQ
+ * Subject to
+ * The USB OTG FS requires a 48 MHz clock to work correctly. The SDMMC
+ * and the random number generator need a frequency lower than or equal
+ * to 48 MHz to work correctly.
+ *
+ * 2 <= PLLQ <= 15
+ */
+
+#if defined(CONFIG_STM32F7_OTGFS)
+/* USB OTG FS clock (= SDMMCCLK = RNGCLK) must be 48 MHz
+ *
+ * PLL_VCO = (25,000,000 / 25) * 384 = 384 MHz
+ * SYSCLK = 384 MHz / 2 = 192 MHz
+ * USB OTG FS, SDMMC and RNG Clock = 384 MHz / 8 = 48MHz
+ * DSI CLK = PLL_VCO / PLLR = 384 / 7 = 54,86 MHz
+ */
+
+#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(25)
+#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(384)
+#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_2
+#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(8)
+#define STM32_PLLCFG_PLLR RCC_PLLCFG_PLLR(7)
+
+#define STM32_VCO_FREQUENCY ((STM32_HSE_FREQUENCY / 25) * 384)
+#define STM32_SYSCLK_FREQUENCY (STM32_VCO_FREQUENCY / 2)
+#define STM32_OTGFS_FREQUENCY (STM32_VCO_FREQUENCY / 8)
+
+#elif defined(CONFIG_STM32F7_SDMMC1) || defined(CONFIG_STM32F7_SDMMC2) || defined(CONFIG_STM32F7_RNG)
+/* SDMMCCLK (= USB OTG FS clock = RNGCLK) should be <= 48MHz
+ *
+ * PLL_VCO = (25,000,000 / 25) * 432 = 432 MHz
+ * SYSCLK = 432 MHz / 2 = 216 MHz
+ * USB OTG FS, SDMMC and RNG Clock = 432 MHz / 10 = 43.2 MHz
+ * DSI CLK = PLL_VCO / PLLR = 432 / 8 = 54 MHz
+ */
+
+#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(25)
+#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(432)
+#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_2
+#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(10)
+#define STM32_PLLCFG_PLLR RCC_PLLCFG_PLLR(8)
+
+#define STM32_VCO_FREQUENCY ((STM32_HSE_FREQUENCY / 25) * 432)
+#define STM32_SYSCLK_FREQUENCY (STM32_VCO_FREQUENCY / 2)
+#define STM32_OTGFS_FREQUENCY (STM32_VCO_FREQUENCY / 10)
+
+#else
+/* No restrictions by OTGFS
+ *
+ * PLL_VCO = (25,000,000 / 25) * 432 = 432 MHz
+ * SYSCLK = 432 MHz / 2 = 216 MHz
+ * USB OTG FS, SDMMC and RNG Clock = 432 MHz / 10 = 43.2 MHz
+ * DSI CLK = PLL_VCO / PLLR = 432 / 8 = 54 MHz
+ */
+
+#define STM32_PLLCFG_PLLM RCC_PLLCFG_PLLM(25)
+#define STM32_PLLCFG_PLLN RCC_PLLCFG_PLLN(432)
+#define STM32_PLLCFG_PLLP RCC_PLLCFG_PLLP_2
+#define STM32_PLLCFG_PLLQ RCC_PLLCFG_PLLQ(10)
+#define STM32_PLLCFG_PLLR RCC_PLLCFG_PLLR(8)
+
+#define STM32_VCO_FREQUENCY ((STM32_HSE_FREQUENCY / 25) * 432)
+#define STM32_SYSCLK_FREQUENCY (STM32_VCO_FREQUENCY / 2)
+#define STM32_OTGFS_FREQUENCY (STM32_VCO_FREQUENCY / 10)
+#endif
+
+/* Configure factors for PLLSAI clock */
+
+#define STM32_RCC_PLLSAICFGR_PLLSAIN RCC_PLLSAICFGR_PLLSAIN(192)
+#define STM32_RCC_PLLSAICFGR_PLLSAIP RCC_PLLSAICFGR_PLLSAIP(2)
+#define STM32_RCC_PLLSAICFGR_PLLSAIQ RCC_PLLSAICFGR_PLLSAIQ(2)
+#define STM32_RCC_PLLSAICFGR_PLLSAIR RCC_PLLSAICFGR_PLLSAIR(2)
+
+/* Configure Dedicated Clock Configuration Register */
+
+#define STM32_RCC_DCKCFGR1_PLLI2SDIVQ RCC_DCKCFGR1_PLLI2SDIVQ(1)
+#define STM32_RCC_DCKCFGR1_PLLSAIDIVQ RCC_DCKCFGR1_PLLSAIDIVQ(1)
+#define STM32_RCC_DCKCFGR1_PLLSAIDIVR RCC_DCKCFGR1_PLLSAIDIVR(0)
+#define STM32_RCC_DCKCFGR1_SAI1SRC RCC_DCKCFGR1_SAI1SEL(0)
+#define STM32_RCC_DCKCFGR1_SAI2SRC RCC_DCKCFGR1_SAI2SEL(0)
+#define STM32_RCC_DCKCFGR1_TIMPRESRC 0
+#define STM32_RCC_DCKCFGR1_DFSDM1SRC 0
+#define STM32_RCC_DCKCFGR1_ADFSDM1SRC 0
+
+
+
+/* Configure factors for PLLI2S clock */
+
+#define STM32_RCC_PLLI2SCFGR_PLLI2SN RCC_PLLI2SCFGR_PLLI2SN(192)
+#define STM32_RCC_PLLI2SCFGR_PLLI2SP RCC_PLLI2SCFGR_PLLI2SP(2)
+#define STM32_RCC_PLLI2SCFGR_PLLI2SQ RCC_PLLI2SCFGR_PLLI2SQ(2)
+#define STM32_RCC_PLLI2SCFGR_PLLI2SR RCC_PLLI2SCFGR_PLLI2SR(2)
+
+/* Configure Dedicated Clock Configuration Register 2 */
+
+#define STM32_RCC_DCKCFGR2_USART1SRC RCC_DCKCFGR2_USART1SEL_APB
+#define STM32_RCC_DCKCFGR2_USART2SRC RCC_DCKCFGR2_USART2SEL_APB
+#define STM32_RCC_DCKCFGR2_UART4SRC RCC_DCKCFGR2_UART4SEL_APB
+#define STM32_RCC_DCKCFGR2_UART5SRC RCC_DCKCFGR2_UART5SEL_APB
+#define STM32_RCC_DCKCFGR2_USART6SRC RCC_DCKCFGR2_USART6SEL_APB
+#define STM32_RCC_DCKCFGR2_UART7SRC RCC_DCKCFGR2_UART7SEL_APB
+#define STM32_RCC_DCKCFGR2_UART8SRC RCC_DCKCFGR2_UART8SEL_APB
+#define STM32_RCC_DCKCFGR2_I2C1SRC RCC_DCKCFGR2_I2C1SEL_HSI
+#define STM32_RCC_DCKCFGR2_I2C2SRC RCC_DCKCFGR2_I2C2SEL_HSI
+#define STM32_RCC_DCKCFGR2_I2C3SRC RCC_DCKCFGR2_I2C3SEL_HSI
+#define STM32_RCC_DCKCFGR2_I2C4SRC RCC_DCKCFGR2_I2C4SEL_HSI
+#define STM32_RCC_DCKCFGR2_LPTIM1SRC RCC_DCKCFGR2_LPTIM1SEL_APB
+#define STM32_RCC_DCKCFGR2_CECSRC RCC_DCKCFGR2_CECSEL_HSI
+#define STM32_RCC_DCKCFGR2_CK48MSRC RCC_DCKCFGR2_CK48MSEL_PLLSAI
+#define STM32_RCC_DCKCFGR2_SDMMCSRC RCC_DCKCFGR2_SDMMCSEL_48MHZ
+#define STM32_RCC_DCKCFGR2_SDMMC2SRC RCC_DCKCFGR2_SDMMC2SEL_48MHZ
+#define STM32_RCC_DCKCFGR2_DSISRC RCC_DCKCFGR2_DSISEL_PHY
+
+/* Several prescalers allow the configuration of the two AHB buses, the
+ * high-speed APB (APB2) and the low-speed APB (APB1) domains. The maximum
+ * frequency of the two AHB buses is 216 MHz while the maximum frequency of
+ * the high-speed APB domains is 108 MHz. The maximum allowed frequency of
+ * the low-speed APB domain is 54 MHz.
+ */
+
+/* AHB clock (HCLK) is SYSCLK (216 MHz) */
+
+#define STM32_RCC_CFGR_HPRE RCC_CFGR_HPRE_SYSCLK /* HCLK = SYSCLK / 1 */
+#define STM32_HCLK_FREQUENCY STM32_SYSCLK_FREQUENCY
+#define STM32_BOARD_HCLK STM32_HCLK_FREQUENCY /* same as above, to satisfy compiler */
+
+/* APB1 clock (PCLK1) is HCLK/4 (54 MHz) */
+
+#define STM32_RCC_CFGR_PPRE1 RCC_CFGR_PPRE1_HCLKd4 /* PCLK1 = HCLK / 4 */
+#define STM32_PCLK1_FREQUENCY (STM32_HCLK_FREQUENCY/4)
+
+/* Timers driven from APB1 will be twice PCLK1 */
+
+#define STM32_APB1_TIM2_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM3_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM4_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM5_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM6_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM7_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM12_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM13_CLKIN (2*STM32_PCLK1_FREQUENCY)
+#define STM32_APB1_TIM14_CLKIN (2*STM32_PCLK1_FREQUENCY)
+
+/* APB2 clock (PCLK2) is HCLK/2 (108MHz) */
+
+#define STM32_RCC_CFGR_PPRE2 RCC_CFGR_PPRE2_HCLKd2 /* PCLK2 = HCLK / 2 */
+#define STM32_PCLK2_FREQUENCY (STM32_HCLK_FREQUENCY/2)
+
+/* Timers driven from APB2 will be twice PCLK2 */
+
+#define STM32_APB2_TIM1_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM8_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM9_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM10_CLKIN (2*STM32_PCLK2_FREQUENCY)
+#define STM32_APB2_TIM11_CLKIN (2*STM32_PCLK2_FREQUENCY)
+
+/* FLASH wait states
+ *
+ * --------- ---------- -----------
+ * VDD MAX SYSCLK WAIT STATES
+ * --------- ---------- -----------
+ * 1.7-2.1 V 180 MHz 8
+ * 2.1-2.4 V 216 MHz 9
+ * 2.4-2.7 V 216 MHz 8
+ * 2.7-3.6 V 216 MHz 7
+ * --------- ---------- -----------
+ */
+
+#define BOARD_FLASH_WAITSTATES 7
+
+/* LED definitions ******************************************************************/
+/* The STM32F769I-DISCO board has numerous LEDs but only one, LD1 located near the
+ * reset button, that can be controlled by software (LD2 is a power indicator, LD3-6
+ * indicate USB status, LD7 is controlled by the ST-Link).
+ *
+ * LD1 is controlled by PI1 which is also the SPI2_SCK at the Arduino interface.
+ * One end of LD1 is grounded so a high output on PI1 will illuminate the LED.
+ *
+ * If CONFIG_ARCH_LEDS is not defined, then the user can control the LEDs in any way.
+ * The following definitions are used to access individual LEDs.
+ */
+
+/* LED index values for use with board_userled() */
+
+#define BOARD_LED1 0
+#define BOARD_NLEDS 1
+
+#define BOARD_LD1 BOARD_LED1
+
+/* LED bits for use with board_userled_all() */
+
+#define BOARD_LED1_BIT (1 << BOARD_LED1)
+
+/* If CONFIG_ARCH_LEDS is defined, the usage by the board port is defined in
+ * include/board.h and src/stm32_leds.c. The LEDs are used to encode OS-related
+ * events as follows:
+ *
+ * SYMBOL Meaning LD1
+ * ------------------- ----------------------- ------
+ * LED_STARTED NuttX has been started OFF
+ * LED_HEAPALLOCATE Heap has been allocated OFF
+ * LED_IRQSENABLED Interrupts enabled OFF
+ * LED_STACKCREATED Idle stack created ON
+ * LED_INIRQ In an interrupt N/C
+ * LED_SIGNAL In a signal handler N/C
+ * LED_ASSERTION An assertion failed N/C
+ * LED_PANIC The system has crashed FLASH
+ *
+ * Thus is LD1 is statically on, NuttX has successfully booted and is,
+ * apparently, running normally. If LD1 is flashing at approximately
+ * 2Hz, then a fatal error has been detected and the system has halted.
+ */
+
+#define LED_STARTED 0 /* LD1=OFF */
+#define LED_HEAPALLOCATE 0 /* LD1=OFF */
+#define LED_IRQSENABLED 0 /* LD1=OFF */
+#define LED_STACKCREATED 1 /* LD1=ON */
+#define LED_INIRQ 2 /* LD1=no change */
+#define LED_SIGNAL 2 /* LD1=no change */
+#define LED_ASSERTION 2 /* LD1=no change */
+#define LED_PANIC 3 /* LD1=flashing */
+
+/* Button definitions ***************************************************************/
+/* The STM32F7 Discovery supports one button: Pushbutton B1, labelled "User", is
+ * connected to GPIO PA0. A high value will be sensed when the button is depressed.
+ */
+
+#define BUTTON_USER 0
+#define NUM_BUTTONS 1
+#define BUTTON_USER_BIT (1 << BUTTON_USER)
+
+/* Alternate function pin selections ************************************************/
+
+/* USART6:
+ *
+ * These configurations assume that you are using a standard Arduio RS-232 shield
+ * with the serial interface with RX on pin D0 and TX on pin D1:
+ *
+ * -------- ---------------
+ * STM32F7
+ * ARDUINO FUNCTION GPIO
+ * -- ----- --------- -----
+ * DO RX USART6_RX PC7
+ * D1 TX USART6_TX PC6
+ * -- ----- --------- -----
+ */
+
+#define GPIO_USART6_RX GPIO_USART6_RX_1
+#define GPIO_USART6_TX GPIO_USART6_TX_1
+
+/* USART1:
+ * USART1 is connected to the "Virtual Com Port" lines
+ * of the ST-LINK controller.
+ *
+ * -------- ---------------
+ * STM32F7
+ * SIGNAME FUNCTION GPIO
+ * -- ----- --------- -----
+ * VCP_RX USART1_RX PA10
+ * VCP_TX USART1_TX PA9
+ * -- ----- --------- -----
+ */
+
+#define GPIO_USART1_RX GPIO_USART1_RX_1
+#define GPIO_USART1_TX GPIO_USART1_TX_1
+
+/* The STM32 F7 connects to a SMSC LAN8742A PHY using these pins:
+ *
+ * STM32 F7 BOARD LAN8742A
+ * GPIO SIGNAL PIN NAME
+ * -------- ------------ -------------
+ * PG11 RMII_TX_EN TXEN
+ * PG13 RMII_TXD0 TXD0
+ * PG14 RMII_TXD1 TXD1
+ * PC4 RMII_RXD0 RXD0/MODE0
+ * PC5 RMII_RXD1 RXD1/MODE1
+ * PD5 RMII_RXER RXER/PHYAD0
+ * PA7 RMII_CRS_DV CRS_DV/MODE2
+ * PC1 RMII_MDC MDC
+ * PA2 RMII_MDIO MDIO
+ * N/A NRST nRST
+ * PA1 RMII_REF_CLK nINT/REFCLK0
+ * N/A OSC_25M XTAL1/CLKIN
+ *
+ * The PHY address is 0, since RMII_RXER/PHYAD0 features a pull down.
+ * After reset, RMII_RXER/PHYAD0 switches to the RXER function,
+ * receive errors can be detected using GPIO pin PD5
+ */
+
+#define GPIO_ETH_RMII_TX_EN GPIO_ETH_RMII_TX_EN_2
+#define GPIO_ETH_RMII_TXD0 GPIO_ETH_RMII_TXD0_2
+#define GPIO_ETH_RMII_TXD1 GPIO_ETH_RMII_TXD1_2
+
+/* I2C Mapping
+ * I2C #4 is connected to the LCD daughter board
+ * and the WM8994 audio codec.
+ *
+ * I2C4_SCL - PD12
+ * I2C4_SDA - PB7
+ */
+#define GPIO_I2C4_SCL GPIO_I2C4_SCL_1
+#define GPIO_I2C4_SDA GPIO_I2C4_SDA_5
+
+/* SDMMC */
+
+/* Stream selections are arbitrary for now but might become important in the future
+ * if we set aside more DMA channels/streams.
+ *
+ * SDIO DMA
+ * DMAMAP_SDMMC1_1 = Channel 4, Stream 3
+ * DMAMAP_SDMMC1_2 = Channel 4, Stream 6
+ *
+ * DMAMAP_SDMMC2_1 = Channel 11, Stream 0
+ * DMAMAP_SDMMC2_2 = Channel 11, Stream 5
+ */
+
+// #define DMAMAP_SDMMC1 DMAMAP_SDMMC1_1
+#define DMAMAP_SDMMC2 DMAMAP_SDMMC2_1
+
+/* SDIO dividers. Note that slower clocking is required when DMA is disabled
+ * in order to avoid RX overrun/TX underrun errors due to delayed responses
+ * to service FIFOs in interrupt driven mode. These values have not been
+ * tuned!!!
+ *
+ * SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(118+2)=400 KHz
+ */
+
+#define STM32_SDMMC_INIT_CLKDIV (118 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+
+/* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz
+ * DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz
+ */
+
+#ifdef CONFIG_SDIO_DMA
+# define STM32_SDMMC_MMCXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#else
+# define STM32_SDMMC_MMCXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#endif
+
+/* DMA ON: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(1+2)=16 MHz
+ * DMA OFF: SDIOCLK=48MHz, SDIO_CK=SDIOCLK/(2+2)=12 MHz
+ */
+
+#ifdef CONFIG_SDIO_DMA
+# define STM32_SDMMC_SDXFR_CLKDIV (1 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#else
+# define STM32_SDMMC_SDXFR_CLKDIV (2 << STM32_SDMMC_CLKCR_CLKDIV_SHIFT)
+#endif
+
+/* SDMMC2 Pin mapping
+ *
+ * D0 - PG9
+ * D1 - PG10
+ * D2 - PB3
+ * D3 - PB4
+ */
+#define GPIO_SDMMC2_D0 GPIO_SDMMC2_D0_2
+#define GPIO_SDMMC2_D1 GPIO_SDMMC2_D1_2
+#define GPIO_SDMMC2_D2 GPIO_SDMMC2_D2_1
+#define GPIO_SDMMC2_D3 GPIO_SDMMC2_D3_1
+
+/* LCD DISPLAY
+ * (work in progress as of 2017 07 19)
+ */
+#define BOARD_LTDC_WIDTH 800
+#define BOARD_LTDC_HEIGHT 472
+
+#define BOARD_LTDC_HSYNC 10
+#define BOARD_LTDC_HFP 10
+#define BOARD_LTDC_HBP 20
+#define BOARD_LTDC_VSYNC 2
+#define BOARD_LTDC_VFP 4
+#define BOARD_LTDC_VBP 2
+
+#define BOARD_LTDC_GCR_PCPOL 0
+#define BOARD_LTDC_GCR_DEPOL 0
+#define BOARD_LTDC_GCR_VSPOL 0
+#define BOARD_LTDC_GCR_HSPOL 0
+
+// #define BOARD_LTDC_OUTPUT_BPP 16
+
+//#define BOARD_LTDC_GCR_DEN
+//#define BOARD_LTDC_GCR_DBW
+//#define BOARD_LTDC_GCR_DGW
+//#define BOARD_LTDC_GCR_DRW
+
+/************************************************************************************
+ * Public Data
+ ************************************************************************************/
+#ifndef __ASSEMBLY__
+
+#undef EXTERN
+#if defined(__cplusplus)
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/************************************************************************************
+ * Public Function Prototypes
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_boardinitialize
+ *
+ * Description:
+ * All STM32 architectures must provide the following entry point. This entry point
+ * is called early in the initialization -- after all memory has been configured
+ * and mapped but before any devices have been initialized.
+ *
+ ************************************************************************************/
+
+void stm32_boardinitialize(void);
+
+#undef EXTERN
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __CONFIG_STM32F769I_DISCO_INCLUDE_BOARD_H */
diff --git a/configs/stm32f769i-disco/kernel/.gitignore b/configs/stm32f769i-disco/kernel/.gitignore
new file mode 100644
index 00000000000..7bacd5aee3e
--- /dev/null
+++ b/configs/stm32f769i-disco/kernel/.gitignore
@@ -0,0 +1,2 @@
+/nuttx_user.elf
+
diff --git a/configs/stm32f769i-disco/kernel/Makefile b/configs/stm32f769i-disco/kernel/Makefile
new file mode 100644
index 00000000000..6608ded637d
--- /dev/null
+++ b/configs/stm32f769i-disco/kernel/Makefile
@@ -0,0 +1,122 @@
+############################################################################
+# configs/stm32f769i-disco/kernel/Makefile
+#
+# Copyright (C) 2015 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt
+#
+# 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.
+#
+############################################################################
+
+-include $(TOPDIR)/Make.defs
+
+# This is the directory for the board-specific header files
+
+BOARD_INCLUDE = $(TOPDIR)$(DELIM)configs$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)include
+
+# The entry point name (if none is provided in the .config file)
+
+CONFIG_USER_ENTRYPOINT ?= user_start
+ENTRYPT = $(patsubst "%",%,$(CONFIG_USER_ENTRYPOINT))
+
+# Get the paths to the libraries and the links script path in format that
+# is appropriate for the host OS
+
+ifeq ($(WINTOOL),y)
+ # Windows-native toolchains
+ USER_LIBPATHS = ${shell for path in $(USERLIBS); do dir=`dirname $(TOPDIR)$(DELIM)$$path`;echo "-L\"`cygpath -w $$dir`\"";done}
+ USER_LDSCRIPT = -T "${shell cygpath -w $(TOPDIR)$(DELIM)configs$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)scripts$(DELIM)memory.ld}"
+ USER_LDSCRIPT += -T "${shell cygpath -w $(TOPDIR)$(DELIM)configs$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)scripts$(DELIM)user-space.ld}"
+ USER_HEXFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.hex}"
+ USER_SRECFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.srec}"
+ USER_BINFILE += "${shell cygpath -w $(TOPDIR)$(DELIM)nuttx_user.bin}"
+else
+ # Linux/Cygwin-native toolchain
+ USER_LIBPATHS = $(addprefix -L$(TOPDIR)$(DELIM),$(dir $(USERLIBS)))
+ USER_LDSCRIPT = -T$(TOPDIR)$(DELIM)configs$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)scripts$(DELIM)memory.ld
+ USER_LDSCRIPT += -T$(TOPDIR)$(DELIM)configs$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)scripts$(DELIM)user-space.ld
+ USER_HEXFILE += "$(TOPDIR)$(DELIM)nuttx_user.hex"
+ USER_SRECFILE += "$(TOPDIR)$(DELIM)nuttx_user.srec"
+ USER_BINFILE += "$(TOPDIR)$(DELIM)nuttx_user.bin"
+endif
+
+USER_LDFLAGS = --undefined=$(ENTRYPT) --entry=$(ENTRYPT) $(USER_LDSCRIPT)
+USER_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(USERLIBS))))
+USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}"
+
+# Source files
+
+CSRCS = stm32_userspace.c
+COBJS = $(CSRCS:.c=$(OBJEXT))
+OBJS = $(COBJS)
+
+# Targets:
+
+all: $(TOPDIR)$(DELIM)nuttx_user.elf $(TOPDIR)$(DELIM)User.map
+.PHONY: nuttx_user.elf depend clean distclean
+
+$(COBJS): %$(OBJEXT): %.c
+ $(call COMPILE, $<, $@)
+
+# Create the nuttx_user.elf file containing all of the user-mode code
+
+nuttx_user.elf: $(OBJS)
+ $(Q) $(LD) -o $@ $(USER_LDFLAGS) $(USER_LIBPATHS) $(OBJS) --start-group $(USER_LDLIBS) --end-group $(USER_LIBGCC)
+
+$(TOPDIR)$(DELIM)nuttx_user.elf: nuttx_user.elf
+ @echo "LD: nuttx_user.elf"
+ $(Q) cp -a nuttx_user.elf $(TOPDIR)$(DELIM)nuttx_user.elf
+ifeq ($(CONFIG_INTELHEX_BINARY),y)
+ @echo "CP: nuttx_user.hex"
+ $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O ihex nuttx_user.elf $(USER_HEXFILE)
+endif
+ifeq ($(CONFIG_MOTOROLA_SREC),y)
+ @echo "CP: nuttx_user.srec"
+ $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O srec nuttx_user.elf $(USER_SRECFILE)
+endif
+ifeq ($(CONFIG_RAW_BINARY),y)
+ @echo "CP: nuttx_user.bin"
+ $(Q) $(OBJCOPY) $(OBJCOPYARGS) -O binary nuttx_user.elf $(USER_BINFILE)
+endif
+
+$(TOPDIR)$(DELIM)User.map: nuttx_user.elf
+ @echo "MK: User.map"
+ $(Q) $(NM) nuttx_user.elf >$(TOPDIR)$(DELIM)User.map
+ $(Q) $(CROSSDEV)size nuttx_user.elf
+
+.depend:
+
+depend: .depend
+
+clean:
+ $(call DELFILE, nuttx_user.elf)
+ $(call DELFILE, "$(TOPDIR)$(DELIM)nuttx_user.*")
+ $(call DELFILE, "$(TOPDIR)$(DELIM)User.map")
+ $(call CLEAN)
+
+distclean: clean
diff --git a/configs/stm32f769i-disco/kernel/stm32_userspace.c b/configs/stm32f769i-disco/kernel/stm32_userspace.c
new file mode 100644
index 00000000000..d0fd835c82a
--- /dev/null
+++ b/configs/stm32f769i-disco/kernel/stm32_userspace.c
@@ -0,0 +1,133 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/kernel/stm32_userspace.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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
+
+#if defined(CONFIG_BUILD_PROTECTED) && !defined(__KERNEL__)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+
+#ifndef CONFIG_NUTTX_USERSPACE
+# error "CONFIG_NUTTX_USERSPACE not defined"
+#endif
+
+#if CONFIG_NUTTX_USERSPACE != 0x08020000
+# error "CONFIG_NUTTX_USERSPACE must be 0x08020000 to match memory.ld"
+#endif
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/* These 'addresses' of these values are setup by the linker script. They are
+ * not actual uint32_t storage locations! They are only used meaningfully in the
+ * following way:
+ *
+ * - The linker script defines, for example, the symbol_sdata.
+ * - The declaration extern uint32_t _sdata; makes C happy. C will believe
+ * that the value _sdata is the address of a uint32_t variable _data (it is
+ * not!).
+ * - We can recover the linker value then by simply taking the address of
+ * of _data. like: uint32_t *pdata = &_sdata;
+ */
+
+extern uint32_t _stext; /* Start of .text */
+extern uint32_t _etext; /* End_1 of .text + .rodata */
+extern const uint32_t _eronly; /* End+1 of read only section (.text + .rodata) */
+extern uint32_t _sdata; /* Start of .data */
+extern uint32_t _edata; /* End+1 of .data */
+extern uint32_t _sbss; /* Start of .bss */
+extern uint32_t _ebss; /* End+1 of .bss */
+
+/* This is the user space entry point */
+
+int CONFIG_USER_ENTRYPOINT(int argc, char *argv[]);
+
+const struct userspace_s userspace __attribute__ ((section (".userspace"))) =
+{
+ /* General memory map */
+
+ .us_entrypoint = (main_t)CONFIG_USER_ENTRYPOINT,
+ .us_textstart = (uintptr_t)&_stext,
+ .us_textend = (uintptr_t)&_etext,
+ .us_datasource = (uintptr_t)&_eronly,
+ .us_datastart = (uintptr_t)&_sdata,
+ .us_dataend = (uintptr_t)&_edata,
+ .us_bssstart = (uintptr_t)&_sbss,
+ .us_bssend = (uintptr_t)&_ebss,
+
+ /* Memory manager heap structure */
+
+ .us_heap = &g_mmheap,
+
+ /* Task/thread startup routines */
+
+ .task_startup = task_startup,
+#ifndef CONFIG_DISABLE_PTHREAD
+ .pthread_startup = pthread_startup,
+#endif
+
+ /* Signal handler trampoline */
+
+#ifndef CONFIG_DISABLE_SIGNALS
+ .signal_handler = up_signal_handler,
+#endif
+
+ /* User-space work queue support (declared in include/nuttx/wqueue.h) */
+
+#ifdef CONFIG_LIB_USRWORK
+ .work_usrstart = work_usrstart,
+#endif
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+#endif /* CONFIG_BUILD_PROTECTED && !__KERNEL__ */
diff --git a/configs/stm32f769i-disco/nsh-ethernet/defconfig b/configs/stm32f769i-disco/nsh-ethernet/defconfig
new file mode 100644
index 00000000000..1b3383624fa
--- /dev/null
+++ b/configs/stm32f769i-disco/nsh-ethernet/defconfig
@@ -0,0 +1,91 @@
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="stm32f769i-disco"
+CONFIG_ARCH_BOARD_STM32F769I_DISCO=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP_STM32F769NI=y
+CONFIG_ARCH_CHIP_STM32F7=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
+CONFIG_ARMV7M_DCACHE=y
+CONFIG_ARMV7M_DTCM=y
+CONFIG_ARMV7M_ICACHE=y
+CONFIG_ARMV7M_LAZYFPU=y
+CONFIG_BOARD_LOOPSPERMSEC=43103
+CONFIG_BUILTIN=y
+CONFIG_DISABLE_POLL=y
+CONFIG_ETH0_PHY_LAN8742A=y
+CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
+CONFIG_EXAMPLES_NSH=y
+CONFIG_FS_PROCFS_REGISTER=y
+CONFIG_FS_PROCFS=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_HAVE_CXX=y
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MAX_TASKS=16
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_MMCSD=y
+CONFIG_MM_REGIONS=3
+CONFIG_NET_ARP_IPIN=y
+CONFIG_NET_ARP_SEND=y
+CONFIG_NET_BROADCAST=y
+CONFIG_NETDB_DNSCLIENT=y
+CONFIG_NET_ETH_MTU=1500
+CONFIG_NET_HOSTNAME="stntest"
+CONFIG_NET_ICMP_PING=y
+CONFIG_NET_ICMP=y
+CONFIG_NET_RXAVAIL=y
+CONFIG_NET_SOCKOPTS=y
+CONFIG_NET_SOLINGER=y
+CONFIG_NET_STATISTICS=y
+CONFIG_NET_TCP=y
+CONFIG_NET_UDP_CHECKSUMS=y
+CONFIG_NET_UDP=y
+CONFIG_NET=y
+CONFIG_NFILE_DESCRIPTORS=8
+CONFIG_NFILE_STREAMS=8
+CONFIG_NSH_BUILTIN_APPS=y
+CONFIG_NSH_DISABLE_IFUPDOWN=y
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_MOTD=y
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PREALLOC_WDOGS=4
+CONFIG_RAM_SIZE=376832
+CONFIG_RAM_START=0x20020000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_HPWORK=y
+CONFIG_SCHED_LPWORK=y
+CONFIG_SCHED_WAITPID=y
+CONFIG_SDCLONE_DISABLE=y
+# CONFIG_SPI_CALLBACK is not set
+CONFIG_SPI=y
+CONFIG_START_DAY=14
+CONFIG_STM32F7_BKPSRAM=y
+CONFIG_STM32F7_CEC=y
+CONFIG_STM32F7_DMA1=y
+CONFIG_STM32F7_DMA2=y
+CONFIG_STM32F7_ETHMAC=y
+CONFIG_STM32F7_I2C4=y
+CONFIG_STM32F7_OTGHS=y
+CONFIG_STM32F7_PHYADDR=0
+CONFIG_STM32F7_PHYSR_100FD=0x18
+CONFIG_STM32F7_PHYSR_100HD=0x8
+CONFIG_STM32F7_PHYSR_10FD=0x14
+CONFIG_STM32F7_PHYSR_10HD=0x4
+CONFIG_STM32F7_PHYSR=31
+CONFIG_STM32F7_PHYSR_ALTCONFIG=y
+CONFIG_STM32F7_PHYSR_ALTMODE=0x1C
+CONFIG_STM32F7_QUADSPI=y
+CONFIG_STM32F7_RNG=y
+CONFIG_STM32F7_SDMMC2=y
+CONFIG_STM32F7_SDMMC_DMA=y
+CONFIG_STM32F7_USART1=y
+CONFIG_STM32F7_USART6=y
+CONFIG_SYSTEM_DHCPC_RENEW=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_USART1_SERIAL_CONSOLE=y
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_WDOG_INTRESERVE=0
diff --git a/configs/stm32f769i-disco/nsh/defconfig b/configs/stm32f769i-disco/nsh/defconfig
new file mode 100644
index 00000000000..8d5cc7fdfb4
--- /dev/null
+++ b/configs/stm32f769i-disco/nsh/defconfig
@@ -0,0 +1,47 @@
+CONFIG_ARCH="arm"
+CONFIG_ARCH_BOARD="stm32f769i-disco"
+CONFIG_ARCH_BOARD_STM32F769I_DISCO=y
+CONFIG_ARCH_BUTTONS=y
+CONFIG_ARCH_CHIP_STM32F769NI=y
+CONFIG_ARCH_CHIP_STM32F7=y
+CONFIG_ARCH_STACKDUMP=y
+CONFIG_ARMV7M_DCACHE_WRITETHROUGH=y
+CONFIG_ARMV7M_DCACHE=y
+CONFIG_ARMV7M_DTCM=y
+CONFIG_ARMV7M_ICACHE=y
+CONFIG_ARMV7M_LAZYFPU=y
+CONFIG_BOARD_LOOPSPERMSEC=43103
+CONFIG_BUILTIN=y
+CONFIG_DISABLE_POLL=y
+CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y
+CONFIG_EXAMPLES_NSH=y
+CONFIG_HAVE_CXXINITIALIZE=y
+CONFIG_HAVE_CXX=y
+CONFIG_INTELHEX_BINARY=y
+CONFIG_MAX_TASKS=16
+CONFIG_MAX_WDOGPARMS=2
+CONFIG_MM_REGIONS=3
+CONFIG_NFILE_DESCRIPTORS=8
+CONFIG_NFILE_STREAMS=8
+CONFIG_NSH_BUILTIN_APPS=y
+# CONFIG_NSH_DISABLE_IFCONFIG is not set
+# CONFIG_NSH_DISABLE_PS is not set
+CONFIG_NSH_FILEIOSIZE=512
+CONFIG_NSH_LINELEN=64
+CONFIG_NSH_READLINE=y
+CONFIG_PREALLOC_MQ_MSGS=4
+CONFIG_PREALLOC_TIMERS=4
+CONFIG_PREALLOC_WDOGS=4
+CONFIG_RAM_SIZE=245760
+CONFIG_RAM_START=0x20010000
+CONFIG_RAW_BINARY=y
+CONFIG_RR_INTERVAL=200
+CONFIG_SCHED_WAITPID=y
+CONFIG_SDCLONE_DISABLE=y
+CONFIG_SPI=y
+CONFIG_START_DAY=14
+CONFIG_STM32F7_USART1=y
+CONFIG_TASK_NAME_SIZE=0
+CONFIG_USART1_SERIAL_CONSOLE=y
+CONFIG_USER_ENTRYPOINT="nsh_main"
+CONFIG_WDOG_INTRESERVE=0
diff --git a/configs/stm32f769i-disco/scripts/Make.defs b/configs/stm32f769i-disco/scripts/Make.defs
new file mode 100644
index 00000000000..f08aad516ab
--- /dev/null
+++ b/configs/stm32f769i-disco/scripts/Make.defs
@@ -0,0 +1,113 @@
+############################################################################
+# configs/stm32f769i-disco/scripts/Make.defs
+#
+# Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt
+#
+# 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.
+#
+############################################################################
+
+include ${TOPDIR}/.config
+include ${TOPDIR}/tools/Config.mk
+include ${TOPDIR}/arch/arm/src/armv7-m/Toolchain.defs
+
+LDSCRIPT = flash.ld
+
+ifeq ($(WINTOOL),y)
+ # Windows-native toolchains
+ DIRLINK = $(TOPDIR)/tools/copydir.sh
+ DIRUNLINK = $(TOPDIR)/tools/unlink.sh
+ MKDEP = $(TOPDIR)/tools/mkwindeps.sh
+ ARCHINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}"
+ ARCHXXINCLUDES = -I. -isystem "${shell cygpath -w $(TOPDIR)/include}" -isystem "${shell cygpath -w $(TOPDIR)/include/cxx}"
+ ARCHSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)}"
+else
+ # Linux/Cygwin-native toolchain
+ MKDEP = $(TOPDIR)/tools/mkdeps$(HOSTEXEEXT)
+ ARCHINCLUDES = -I. -isystem $(TOPDIR)/include
+ ARCHXXINCLUDES = -I. -isystem $(TOPDIR)/include -isystem $(TOPDIR)/include/cxx
+ ARCHSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/scripts/$(LDSCRIPT)
+endif
+
+CC = $(CROSSDEV)gcc
+CXX = $(CROSSDEV)g++
+CPP = $(CROSSDEV)gcc -E
+LD = $(CROSSDEV)ld
+AR = $(ARCROSSDEV)ar rcs
+NM = $(ARCROSSDEV)nm
+OBJCOPY = $(CROSSDEV)objcopy
+OBJDUMP = $(CROSSDEV)objdump
+
+ARCHCCVERSION = ${shell $(CC) -v 2>&1 | sed -n '/^gcc version/p' | sed -e 's/^gcc version \([0-9\.]\)/\1/g' -e 's/[-\ ].*//g' -e '1q'}
+ARCHCCMAJOR = ${shell echo $(ARCHCCVERSION) | cut -d'.' -f1}
+
+ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
+ ARCHOPTIMIZATION = -g
+endif
+
+ifneq ($(CONFIG_DEBUG_NOOPT),y)
+ ARCHOPTIMIZATION += $(MAXOPTIMIZATION) -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
+endif
+
+ARCHCFLAGS = -fno-builtin
+ARCHCXXFLAGS = -fno-builtin -fno-exceptions -fcheck-new -fno-rtti
+ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
+ARCHWARNINGSXX = -Wall -Wshadow -Wundef
+ARCHDEFINES =
+ARCHPICFLAGS = -fpic -msingle-pic-base -mpic-register=r10
+
+CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
+CXXFLAGS = $(ARCHCXXFLAGS) $(ARCHWARNINGSXX) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES) -pipe
+CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
+CPPFLAGS = $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
+AFLAGS = $(CFLAGS) -D__ASSEMBLY__
+
+NXFLATLDFLAGS1 = -r -d -warn-common
+NXFLATLDFLAGS2 = $(NXFLATLDFLAGS1) -T$(TOPDIR)/binfmt/libnxflat/gnu-nxflat-pcrel.ld -no-check-sections
+LDNXFLATFLAGS = -e main -s 2048
+
+ASMEXT = .S
+OBJEXT = .o
+LIBEXT = .a
+EXEEXT =
+
+ifneq ($(CROSSDEV),arm-nuttx-elf-)
+ LDFLAGS += -nostartfiles -nodefaultlibs
+endif
+ifeq ($(CONFIG_DEBUG_SYMBOLS),y)
+ LDFLAGS += -g
+endif
+
+
+HOSTCC = gcc
+HOSTINCLUDES = -I.
+HOSTCFLAGS = -Wall -Wstrict-prototypes -Wshadow -Wundef -g -pipe
+HOSTLDFLAGS =
+
diff --git a/configs/stm32f769i-disco/scripts/flash.ld b/configs/stm32f769i-disco/scripts/flash.ld
new file mode 100644
index 00000000000..1cdb04b8d77
--- /dev/null
+++ b/configs/stm32f769i-disco/scripts/flash.ld
@@ -0,0 +1,147 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/scripts/flash.ld
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * Modified 11/4/2013 for STM32F429 support
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* The STM32F769NIH6 has 2048Kb of main FLASH memory. This FLASH memory can
+ * be accessed from either the AXIM interface at address 0x0800:0000 or from
+ * the ITCM interface at address 0x0020:0000.
+ *
+ * Additional information, including the option bytes, is available at at
+ * FLASH at address 0x1ff0:0000.
+ *
+ * In the STM32F769NIH6, two different boot spaces can be selected through
+ * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and
+ * BOOT_ADD1 option bytes:
+ *
+ * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0].
+ * ST programmed value: Flash on ITCM at 0x0020:0000
+ * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0].
+ * ST programmed value: System bootloader at 0x0010:0000
+ *
+ * NuttX does not modify these option bytes. On the unmodified STM32F769I
+ * DISCO board, the BOOT0 pin is at ground so by default, the STM32 will boot
+ * to address 0x0020:0000 in ITCM FLASH.
+ *
+ * The STM32F769NIH6 also has 512Kb of data SRAM (in addition to ITCM SRAM).
+ * SRAM is split up into three blocks:
+ *
+ * 1) 128Kb of DTCM SRM beginning at address 0x2000:0000
+ * 2) 368Kb of SRAM1 beginning at address 0x2002:0000
+ * 3) 16Kb of SRAM2 beginning at address 0x2007:c000
+ *
+ * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
+ * where the code expects to begin execution by jumping to the entry point in
+ * the 0x0800:0000 address range.
+ */
+
+MEMORY
+{
+ itcm (rwx) : ORIGIN = 0x00200000, LENGTH = 2048K
+ flash (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
+ dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
+ sram1 (rwx) : ORIGIN = 0x20020000, LENGTH = 368K
+ sram2 (rwx) : ORIGIN = 0x2007c000, LENGTH = 16K
+}
+
+OUTPUT_ARCH(arm)
+EXTERN(_vectors)
+ENTRY(_stext)
+SECTIONS
+{
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > flash
+
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > flash
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > flash
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > flash
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ _edata = ABSOLUTE(.);
+ } > sram1 AT > flash
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ _ebss = ABSOLUTE(.);
+ } > sram1
+
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/configs/stm32f769i-disco/scripts/kernel-space.ld b/configs/stm32f769i-disco/scripts/kernel-space.ld
new file mode 100644
index 00000000000..16688ac7549
--- /dev/null
+++ b/configs/stm32f769i-disco/scripts/kernel-space.ld
@@ -0,0 +1,109 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/scripts/kernel-space.ld
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* NOTE: This depends on the memory.ld script having been included prior to
+ * this script.
+ */
+
+OUTPUT_ARCH(arm)
+ENTRY(_stext)
+SECTIONS
+{
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.vectors)
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > kflash
+
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > kflash
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > kflash
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > kflash
+
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ _edata = ABSOLUTE(.);
+ } > ksram AT > kflash
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ _ebss = ABSOLUTE(.);
+ } > ksram
+
+ /* Stabs debugging sections */
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/configs/stm32f769i-disco/scripts/memory.ld b/configs/stm32f769i-disco/scripts/memory.ld
new file mode 100644
index 00000000000..748620b1a8e
--- /dev/null
+++ b/configs/stm32f769i-disco/scripts/memory.ld
@@ -0,0 +1,129 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/scripts/memory.ld
+ *
+ * Copyright (C) 2013 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* The STM32F769NIH6 has 2048Kb of main FLASH memory. This FLASH memory can
+ * be accessed from either the AXIM interface at address 0x0800:0000 or from
+ * the ITCM interface at address 0x0020:0000.
+ *
+ * Additional information, including the option bytes, is available at at
+ * FLASH at address 0x1ff0:0000.
+ *
+ * In the STM32F769NIH6, two different boot spaces can be selected through
+ * the BOOT pin and the boot base address programmed in the BOOT_ADD0 and
+ * BOOT_ADD1 option bytes:
+ *
+ * 1) BOOT=0: Boot address defined by user option byte BOOT_ADD0[15:0].
+ * ST programmed value: Flash on ITCM at 0x0020:0000
+ * 2) BOOT=1: Boot address defined by user option byte BOOT_ADD1[15:0].
+ * ST programmed value: System bootloader at 0x0010:0000
+ *
+ * NuttX does not modify these option bytes. On the unmodified STM32F769I
+ * DISCO board, the BOOT0 pin is at ground so by default, the STM32 will boot
+ * to address 0x0020:0000 in ITCM FLASH.
+ *
+ * The STM32F769NIH6 also has 512Kb of data SRAM (in addition to ITCM SRAM).
+ * SRAM is split up into three blocks:
+ *
+ * 1) 128Kb of DTCM SRM beginning at address 0x2000:0000
+ * 2) 368Kb of SRAM1 beginning at address 0x2002:0000
+ * 3) 16Kb of SRAM2 beginning at address 0x2007:c000
+ *
+ * When booting from FLASH, FLASH memory is aliased to address 0x0000:0000
+ * where the code expects to begin execution by jumping to the entry point in
+ * the 0x0800:0000 address range.
+ *
+ * For MPU support, the kernel-mode NuttX section is assumed to be 128Kb of
+ * FLASH and 4Kb of SRAM. That is an excessive amount for the kernel which
+ * should fit into 64KB and, of course, can be optimized as needed (See
+ * also configs/stm32f769i-disco/scripts/kernel-space.ld). Allowing the
+ * additional does permit addition debug instrumentation to be added to the
+ * kernel space without overflowing the partition.
+ *
+ * Alignment of the user space FLASH partition is also a critical factor:
+ * The user space FLASH partition will be spanned with a single region of
+ * size 2**n bytes. The alignment of the user-space region must be the same.
+ * As a consequence, as the user-space increases in size, the alignment
+ * requirement also increases.
+ *
+ * This alignment requirement means that the largest user space FLASH region
+ * you can have will be 512KB at it would have to be positioned at
+ * 0x08800000. If you change this address, don't forget to change the
+ * CONFIG_NUTTX_USERSPACE configuration setting to match and to modify
+ * the check in kernel/userspace.c.
+ *
+ * For the same reasons, the maximum size of the SRAM mapping is limited to
+ * 4KB. Both of these alignment limitations could be reduced by using
+ * multiple regions to map the FLASH/SDRAM range or perhaps with some
+ * clever use of subregions.
+ *
+ * A detailed memory map for the 112KB SRAM region is as follows:
+ *
+ * 0x20001 0000: Kernel .data region. Typical size: 0.1KB
+ * ------- ---- Kernel .bss region. Typical size: 1.8KB
+ * 0x20001 0800: Kernel IDLE thread stack (approximate). Size is
+ * determined by CONFIG_IDLETHREAD_STACKSIZE and
+ * adjustments for alignment. Typical is 1KB.
+ * ------- ---- Padded to 4KB
+ * 0x20001 1000: User .data region. Size is variable.
+ * ------- ---- User .bss region Size is variable.
+ * 0x20001 2000: Beginning of kernel heap. Size determined by
+ * CONFIG_MM_KERNEL_HEAPSIZE.
+ * ------- ---- Beginning of user heap. Can vary with other settings.
+ * 0x20004 c000: End+1 of SRAM1
+ */
+
+MEMORY
+{
+ /* ITCM boot address */
+
+ itcm (rwx) : ORIGIN = 0x00200000, LENGTH = 2048K
+
+ /* 2048KB FLASH */
+
+ kflash (rx) : ORIGIN = 0x08000000, LENGTH = 128K
+ uflash (rx) : ORIGIN = 0x08020000, LENGTH = 128K
+ xflash (rx) : ORIGIN = 0x08040000, LENGTH = 1792K
+
+ /* 368KB of contiguous SRAM1 */
+
+ ksram (rwx) : ORIGIN = 0x20010000, LENGTH = 4K
+ usram (rwx) : ORIGIN = 0x20011000, LENGTH = 4K
+ xsram (rwx) : ORIGIN = 0x20012000, LENGTH = 368K - 8K
+
+ /* DTCM SRAM */
+
+ dtcm (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
+ sram2 (rwx) : ORIGIN = 0x2007c000, LENGTH = 16K
+}
diff --git a/configs/stm32f769i-disco/scripts/user-space.ld b/configs/stm32f769i-disco/scripts/user-space.ld
new file mode 100644
index 00000000000..a021e84a567
--- /dev/null
+++ b/configs/stm32f769i-disco/scripts/user-space.ld
@@ -0,0 +1,111 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/scripts/user-space.ld
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+/* NOTE: This depends on the memory.ld script having been included prior to
+ * this script.
+ */
+
+OUTPUT_ARCH(arm)
+SECTIONS
+{
+ .userspace : {
+ *(.userspace)
+ } > uflash
+
+ .text : {
+ _stext = ABSOLUTE(.);
+ *(.text .text.*)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.rodata .rodata.*)
+ *(.gnu.linkonce.t.*)
+ *(.glue_7)
+ *(.glue_7t)
+ *(.got)
+ *(.gcc_except_table)
+ *(.gnu.linkonce.r.*)
+ _etext = ABSOLUTE(.);
+ } > uflash
+
+ .init_section : {
+ _sinit = ABSOLUTE(.);
+ *(.init_array .init_array.*)
+ _einit = ABSOLUTE(.);
+ } > uflash
+
+ .ARM.extab : {
+ *(.ARM.extab*)
+ } > uflash
+
+ __exidx_start = ABSOLUTE(.);
+ .ARM.exidx : {
+ *(.ARM.exidx*)
+ } > uflash
+
+ __exidx_end = ABSOLUTE(.);
+
+ _eronly = ABSOLUTE(.);
+
+ .data : {
+ _sdata = ABSOLUTE(.);
+ *(.data .data.*)
+ *(.gnu.linkonce.d.*)
+ CONSTRUCTORS
+ _edata = ABSOLUTE(.);
+ } > usram AT > uflash
+
+ .bss : {
+ _sbss = ABSOLUTE(.);
+ *(.bss .bss.*)
+ *(.gnu.linkonce.b.*)
+ *(COMMON)
+ _ebss = ABSOLUTE(.);
+ } > usram
+
+ /* Stabs debugging sections */
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+ .debug_abbrev 0 : { *(.debug_abbrev) }
+ .debug_info 0 : { *(.debug_info) }
+ .debug_line 0 : { *(.debug_line) }
+ .debug_pubnames 0 : { *(.debug_pubnames) }
+ .debug_aranges 0 : { *(.debug_aranges) }
+}
diff --git a/configs/stm32f769i-disco/src/.gitignore b/configs/stm32f769i-disco/src/.gitignore
new file mode 100644
index 00000000000..726d936e1e3
--- /dev/null
+++ b/configs/stm32f769i-disco/src/.gitignore
@@ -0,0 +1,2 @@
+/.depend
+/Make.dep
diff --git a/configs/stm32f769i-disco/src/Makefile b/configs/stm32f769i-disco/src/Makefile
new file mode 100644
index 00000000000..15a80a56169
--- /dev/null
+++ b/configs/stm32f769i-disco/src/Makefile
@@ -0,0 +1,63 @@
+############################################################################
+# configs/stm32f769i-disco/src/Makefile
+#
+# Copyright (C) 2015 Gregory Nutt. All rights reserved.
+# Author: Gregory Nutt
+#
+# 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.
+#
+############################################################################
+
+-include $(TOPDIR)/Make.defs
+
+ASRCS =
+CSRCS = stm32_boot.c stm32_spi.c
+
+ifeq ($(CONFIG_ARCH_LEDS),y)
+CSRCS += stm32_autoleds.c
+else
+CSRCS += stm32_userleds.c
+endif
+
+ifeq ($(CONFIG_ARCH_BUTTONS),y)
+CSRCS += stm32_buttons.c
+endif
+
+ifeq ($(CONFIG_LIB_BOARDCTL),y)
+CSRCS += stm32_appinitialize.c
+endif
+
+ifeq ($(CONFIG_ARCH_FPU),y)
+CSRCS += stm32_ostest.c
+endif
+
+ifeq ($(CONFIG_SPORADIC_INSTRUMENTATION),y)
+CSRCS += stm32_sporadic.c
+endif
+
+include $(TOPDIR)/configs/Board.mk
diff --git a/configs/stm32f769i-disco/src/stm32_appinitialize.c b/configs/stm32f769i-disco/src/stm32_appinitialize.c
new file mode 100644
index 00000000000..17d40799b39
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32_appinitialize.c
@@ -0,0 +1,98 @@
+/****************************************************************************
+ * config/stm32f769i-disco/src/stm32_appinitialize.c
+ *
+ * Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 "stm32_ccm.h"
+#include "stm32f769i-disco.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_app_initialize
+ *
+ * Description:
+ * Perform application specific initialization. This function is never
+ * called directly from application code, but only indirectly via the
+ * (non-standard) boardctl() interface using the command BOARDIOC_INIT.
+ *
+ * Input Parameters:
+ * arg - The boardctl() argument is passed to the board_app_initialize()
+ * implementation without modification. The argument has no
+ * meaning to NuttX; the meaning of the argument is a contract
+ * between the board-specific initalization logic and the
+ * matching application logic. The value cold be such things as a
+ * mode enumeration value, a set of DIP switch switch settings, a
+ * pointer to configuration data read from a file or serial FLASH,
+ * or whatever you would like to do with it. Every implementation
+ * should accept zero/NULL as a default configuration.
+ *
+ * Returned Value:
+ * Zero (OK) is returned on success; a negated errno value is returned on
+ * any failure to indicate the nature of the failure.
+ *
+ ****************************************************************************/
+
+int board_app_initialize(uintptr_t arg)
+{
+#ifdef CONFIG_FS_PROCFS
+ int ret;
+
+#ifdef CONFIG_STM32_CCM_PROCFS
+ /* Register the CCM procfs entry. This must be done before the procfs is
+ * mounted.
+ */
+
+ (void)ccm_procfs_register();
+#endif
+
+ /* Mount the procfs file system */
+
+ ret = mount(NULL, SAMV71_PROCFS_MOUNTPOINT, "procfs", 0, NULL);
+ if (ret < 0)
+ {
+ SYSLOG("ERROR: Failed to mount procfs at %s: %d\n",
+ SAMV71_PROCFS_MOUNTPOINT, ret);
+ }
+#endif
+
+ return OK;
+}
diff --git a/configs/stm32f769i-disco/src/stm32_autoleds.c b/configs/stm32f769i-disco/src/stm32_autoleds.c
new file mode 100644
index 00000000000..22e7c186150
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32_autoleds.c
@@ -0,0 +1,128 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/src/stm32_autoleds.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 "stm32_gpio.h"
+#include "stm32f769i-disco.h"
+
+#ifdef CONFIG_ARCH_LEDS
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_autoled_initialize
+ ****************************************************************************/
+
+void board_autoled_initialize(void)
+{
+ /* Configure the LD1 GPIO for output. Initial state is OFF */
+
+ stm32_configgpio(GPIO_LD3);
+}
+
+/****************************************************************************
+ * Name: board_autoled_on
+ ****************************************************************************/
+
+void board_autoled_on(int led)
+{
+ bool ledstate = false;
+
+ switch (led)
+ {
+ case 0: /* LED_STARTED: NuttX has been started STATUS LED=OFF */
+ /* LED_HEAPALLOCATE: Heap has been allocated STATUS LED=OFF */
+ /* LED_IRQSENABLED: Interrupts enabled STATUS LED=OFF */
+ break; /* Leave ledstate == true to turn OFF */
+
+ default:
+ case 2: /* LED_INIRQ: In an interrupt STATUS LED=N/C */
+ /* LED_SIGNAL: In a signal handler STATUS LED=N/C */
+ /* LED_ASSERTION: An assertion failed STATUS LED=N/C */
+ return; /* Return to leave STATUS LED unchanged */
+
+ case 3: /* LED_PANIC: The system has crashed STATUS LED=FLASH */
+ case 1: /* LED_STACKCREATED: Idle stack created STATUS LED=ON */
+ ledstate = true; /* Set ledstate == false to turn ON */
+ break;
+ }
+
+ stm32_gpiowrite(GPIO_LD3, ledstate);
+}
+
+/****************************************************************************
+ * Name: board_autoled_off
+ ****************************************************************************/
+
+void board_autoled_off(int led)
+{
+ switch (led)
+ {
+ /* These should not happen and are ignored */
+
+ default:
+ case 0: /* LED_STARTED: NuttX has been started STATUS LED=OFF */
+ /* LED_HEAPALLOCATE: Heap has been allocated STATUS LED=OFF */
+ /* LED_IRQSENABLED: Interrupts enabled STATUS LED=OFF */
+ case 1: /* LED_STACKCREATED: Idle stack created STATUS LED=ON */
+
+ /* These result in no-change */
+
+ case 2: /* LED_INIRQ: In an interrupt STATUS LED=N/C */
+ /* LED_SIGNAL: In a signal handler STATUS LED=N/C */
+ /* LED_ASSERTION: An assertion failed STATUS LED=N/C */
+ return; /* Return to leave STATUS LED unchanged */
+
+ /* Turn STATUS LED off set driving the output high */
+
+ case 3: /* LED_PANIC: The system has crashed STATUS LED=FLASH */
+ stm32_gpiowrite(GPIO_LD3, false);
+ break;
+ }
+}
+
+#endif /* CONFIG_ARCH_LEDS */
diff --git a/configs/stm32f769i-disco/src/stm32_boot.c b/configs/stm32f769i-disco/src/stm32_boot.c
new file mode 100644
index 00000000000..d0f95192133
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32_boot.c
@@ -0,0 +1,127 @@
+/************************************************************************************
+ * configs/stm32f769i-disco/src/stm32_boot.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 "up_arch.h"
+#include "stm32f769i-disco.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Private Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_boardinitialize
+ *
+ * Description:
+ * All STM32 architectures must provide the following entry point. This entry point
+ * is called early in the initialization -- after all memory has been configured
+ * and mapped but before any devices have been initialized.
+ *
+ ************************************************************************************/
+
+void stm32_boardinitialize(void)
+{
+#if defined(CONFIG_STM32F7_SPI1) || defined(CONFIG_STM32F7_SPI2) || \
+ defined(CONFIG_STM32F7_SPI3) || defined(CONFIG_STM32F7_SPI4) || \
+ defined(CONFIG_STM32F7_SPI5)
+ /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak function
+ * stm32_spidev_initialize() has been brought into the link.
+ */
+
+ if (stm32_spidev_initialize)
+ {
+ stm32_spidev_initialize();
+ }
+#endif
+
+#ifdef CONFIG_SPORADIC_INSTRUMENTATION
+ /* This configuration has been used for evaluating the NuttX sporadic scheduler.
+ * The following caqll initializes the sporadic scheduler monitor.
+ */
+
+ arch_sporadic_initialize();
+#endif
+
+#ifdef CONFIG_ARCH_LEDS
+ /* Configure on-board LEDs if LED support has been selected. */
+
+ board_autoled_initialize();
+#endif
+}
+
+/************************************************************************************
+ * Name: board_initialize
+ *
+ * Description:
+ * If CONFIG_BOARD_INITIALIZE is selected, then an additional initialization call
+ * will be performed in the boot-up sequence to a function called
+ * board_initialize(). board_initialize() will be called immediately after
+ * up_initialize() is called and just before the initial application is started.
+ * This additional initialization phase may be used, for example, to initialize
+ * board-specific device drivers.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_BOARD_INITIALIZE
+void board_initialize(void)
+{
+#if defined(CONFIG_NSH_LIBRARY) && !defined(CONFIG_LIB_BOARDCTL)
+ /* Perform NSH initialization here instead of from the NSH. This
+ * alternative NSH initialization is necessary when NSH is ran in user-space
+ * but the initialization function must run in kernel space.
+ */
+
+ (void)board_app_initialize(0);
+#endif
+}
+#endif
diff --git a/configs/stm32f769i-disco/src/stm32_buttons.c b/configs/stm32f769i-disco/src/stm32_buttons.c
new file mode 100644
index 00000000000..9103f42cba6
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32_buttons.c
@@ -0,0 +1,110 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/src/stm32_buttons.c
+ *
+ * Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 "stm32_gpio.h"
+#include "stm32f769i-disco.h"
+
+#ifdef CONFIG_ARCH_BUTTONS
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_button_initialize
+ *
+ * Description:
+ * board_button_initialize() must be called to initialize button resources.
+ * After that, board_buttons() may be called to collect the current state
+ * of all buttons or board_button_irq() may be called to register button
+ * interrupt handlers.
+ *
+ ****************************************************************************/
+
+void board_button_initialize(void)
+{
+ stm32_configgpio(GPIO_BTN_USER);
+}
+
+/****************************************************************************
+ * Name: board_buttons
+ ****************************************************************************/
+
+uint32_t board_buttons(void)
+{
+ return stm32_gpioread(GPIO_BTN_USER) ? 1 : 0;
+}
+
+/************************************************************************************
+ * Button support.
+ *
+ * Description:
+ * board_button_initialize() must be called to initialize button resources. After
+ * that, board_buttons() may be called to collect the current state of all
+ * buttons or board_button_irq() may be called to register button interrupt
+ * handlers.
+ *
+ * After board_button_initialize() has been called, board_buttons() may be called to
+ * collect the state of all buttons. board_buttons() returns an 32-bit bit set
+ * with each bit associated with a button. See the BUTTON_*_BIT
+ * definitions in board.h for the meaning of each bit.
+ *
+ * board_button_irq() may be called to register an interrupt handler that will
+ * be called when a button is depressed or released. The ID value is a
+ * button enumeration value that uniquely identifies a button resource. See the
+ * BUTTON_* definitions in board.h for the meaning of enumeration
+ * value.
+ *
+ ************************************************************************************/
+
+#ifdef CONFIG_ARCH_IRQBUTTONS
+int board_button_irq(int id, xcpt_t irqhandler, FAR void *arg)
+{
+#warning Missing logic
+ return -ENOSYS;
+}
+#endif
+#endif /* CONFIG_ARCH_BUTTONS */
diff --git a/configs/stm32f769i-disco/src/stm32_ostest.c b/configs/stm32f769i-disco/src/stm32_ostest.c
new file mode 100644
index 00000000000..1ca75cdfbf3
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32_ostest.c
@@ -0,0 +1,114 @@
+/************************************************************************************
+ * configs/stm32f769i-disco/src/stm32_ostest.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 "up_arch.h"
+#include "up_internal.h"
+#include "stm32f769i-disco.h"
+
+/************************************************************************************
+ * Pre-processor Definitions
+ ************************************************************************************/
+/* Configuration ********************************************************************/
+
+#undef HAVE_FPU
+#if defined(CONFIG_ARCH_FPU) && !defined(CONFIG_EXAMPLES_OSTEST_FPUTESTDISABLE) && \
+ defined(CONFIG_EXAMPLES_OSTEST_FPUSIZE) && defined(CONFIG_SCHED_WAITPID) && \
+ !defined(CONFIG_DISABLE_SIGNALS)
+# define HAVE_FPU 1
+#endif
+
+#ifdef HAVE_FPU
+
+#if CONFIG_EXAMPLES_OSTEST_FPUSIZE != (4*SW_FPU_REGS)
+# error "CONFIG_EXAMPLES_OSTEST_FPUSIZE has the wrong size"
+#endif
+
+/************************************************************************************
+ * Private Data
+ ************************************************************************************/
+
+static uint32_t g_saveregs[XCPTCONTEXT_REGS];
+
+/************************************************************************************
+ * Private Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/* Given an array of size CONFIG_EXAMPLES_OSTEST_FPUSIZE, this function will return
+ * the current FPU registers.
+ */
+
+void arch_getfpu(FAR uint32_t *fpusave)
+{
+ irqstate_t flags;
+
+ /* Take a snapshot of the thread context right now */
+
+ flags = enter_critical_section();
+ up_saveusercontext(g_saveregs);
+
+ /* Return only the floating register values */
+
+ memcpy(fpusave, &g_saveregs[REG_S0], (4*SW_FPU_REGS));
+ leave_critical_section(flags);
+}
+
+/* Given two arrays of size CONFIG_EXAMPLES_OSTEST_FPUSIZE this function
+ * will compare them and return true if they are identical.
+ */
+
+bool arch_cmpfpu(FAR const uint32_t *fpusave1, FAR const uint32_t *fpusave2)
+{
+ return memcmp(fpusave1, fpusave2, (4*SW_FPU_REGS)) == 0;
+}
+
+#endif /* HAVE_FPU */
diff --git a/configs/stm32f769i-disco/src/stm32_spi.c b/configs/stm32f769i-disco/src/stm32_spi.c
new file mode 100644
index 00000000000..17fda9da1f3
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32_spi.c
@@ -0,0 +1,221 @@
+/************************************************************************************
+ * configs/stm32f769i-disco/src/stm32_spi.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ *
+ * 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 "up_arch.h"
+#include "chip.h"
+#include "stm32_spi.h"
+
+#include "stm32f769i-disco.h"
+
+#if defined(CONFIG_STM32F7_SPI1) || defined(CONFIG_STM32F7_SPI2) || \
+ defined(CONFIG_STM32F7_SPI3) || defined(CONFIG_STM32F7_SPI4) || \
+ defined(CONFIG_STM32F7_SPI5)
+
+/************************************************************************************
+ * Public Functions
+ ************************************************************************************/
+
+/************************************************************************************
+ * Name: stm32_spidev_initialize
+ *
+ * Description:
+ * Called to configure SPI chip select GPIO pins for the stm32f769i-disco board.
+ *
+ ************************************************************************************/
+
+void weak_function stm32_spidev_initialize(void)
+{
+}
+
+/****************************************************************************
+ * Name: stm32_spi1/2/3/4/5select and stm32_spi1/2/3/4/5status
+ *
+ * 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_STM32F7_SPI1
+void stm32_spi1select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
+}
+
+uint8_t stm32_spi1status(FAR struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_STM32F7_SPI2
+void stm32_spi2select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
+}
+
+uint8_t stm32_spi2status(FAR struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_STM32F7_SPI3
+void stm32_spi3select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
+}
+
+uint8_t stm32_spi3status(FAR struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_STM32F7_SPI4
+void stm32_spi4select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
+}
+
+uint8_t stm32_spi4status(FAR struct spi_dev_s *dev, uint32_t devid)
+{
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_STM32F7_SPI5
+void stm32_spi5select(FAR struct spi_dev_s *dev, uint32_t devid, bool selected)
+{
+ spiinfo("devid: %d CS: %s\n", (int)devid, selected ? "assert" : "de-assert");
+}
+
+uint8_t stm32_spi5status(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_STM32F7_SPI1
+int stm32_spi1cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_STM32F7_SPI2
+int stm32_spi2cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_STM32F7_SPI3
+int stm32_spi3cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_STM32F7_SPI4
+int stm32_spi4cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#ifdef CONFIG_STM32F7_SPI5
+int stm32_spi5cmddata(FAR struct spi_dev_s *dev, uint32_t devid, bool cmd)
+{
+ return -ENODEV;
+}
+#endif
+
+#endif /* CONFIG_SPI_CMDDATA */
+#endif /* CONFIG_STM32F7_SPI1 || ... CONFIG_STM32F7_SPI5 */
diff --git a/configs/stm32f769i-disco/src/stm32_sporadic.c b/configs/stm32f769i-disco/src/stm32_sporadic.c
new file mode 100644
index 00000000000..2960362f589
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32_sporadic.c
@@ -0,0 +1,93 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/src/stm32_sporadic.c
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 "stm32_gpio.h"
+#include "stm32f769i-disco.h"
+
+#ifdef CONFIG_SPORADIC_INSTRUMENTATION
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arch_sporadic_*
+ *
+ * Description:
+ * This configuration has been used for evaluating the NuttX sporadic
+ * scheduler. This only makes sense when uses with the sporadic test
+ * which is a part of apps/examples/ostest. If would make generate
+ * meaningful output in its current state if there were multiple sporadic
+ * threads
+ *
+ ****************************************************************************/
+
+void arch_sporadic_initialize(void)
+{
+ stm32_configgpio(GPIO_SCHED_HIGHPRI);
+ stm32_configgpio(GPIO_SCHED_RUNNING);
+}
+
+void arch_sporadic_start(FAR struct tcb_s *tcb)
+{
+ stm32_gpiowrite(GPIO_SCHED_HIGHPRI, true);
+}
+
+void arch_sporadic_lowpriority(FAR struct tcb_s *tcb)
+{
+ stm32_gpiowrite(GPIO_SCHED_HIGHPRI, false);
+}
+
+void arch_sporadic_suspend(FAR struct tcb_s *tcb)
+{
+ stm32_gpiowrite(GPIO_SCHED_RUNNING, false);
+}
+
+void arch_sporadic_resume(FAR struct tcb_s *tcb)
+{
+ stm32_gpiowrite(GPIO_SCHED_RUNNING, true);
+}
+
+#endif /* CONFIG_SPORADIC_INSTRUMENTATION */
\ No newline at end of file
diff --git a/configs/stm32f769i-disco/src/stm32_userleds.c b/configs/stm32f769i-disco/src/stm32_userleds.c
new file mode 100644
index 00000000000..c61f06ae660
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32_userleds.c
@@ -0,0 +1,104 @@
+/****************************************************************************
+ * configs/stm32f769i-disco/src/stm32_userleds.c
+ *
+ * Copyright (C) 2011, 2015 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt
+ *
+ * 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 "stm32_gpio.h"
+#include "stm32f769i-disco.h"
+
+#ifndef CONFIG_ARCH_LEDS
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: board_userled_initialize
+ *
+ * Description:
+ * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board
+ * LEDs. If CONFIG_ARCH_LEDS is not defined, then the
+ * board_userled_initialize() is available to initialize the LED from user
+ * application logic.
+ *
+ ****************************************************************************/
+
+void board_userled_initialize(void)
+{
+ stm32_configgpio(GPIO_LD3);
+}
+
+/****************************************************************************
+ * Name: board_userled
+ *
+ * Description:
+ * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board
+ * LEDs. If CONFIG_ARCH_LEDS is not defined, then the board_userled() is
+ * available to control the LED from user application logic.
+ *
+ ****************************************************************************/
+
+void board_userled(int led, bool ledon)
+{
+ if (led == BOARD_STATUS_LED)
+ {
+ stm32_gpiowrite(GPIO_LD3, !ledon);
+ }
+}
+
+/****************************************************************************
+ * Name: board_userled_all
+ *
+ * Description:
+ * If CONFIG_ARCH_LEDS is defined, then NuttX will control the on-board
+ * LEDs. If CONFIG_ARCH_LEDS is not defined, then the board_userled_all() is
+ * available to control the LED from user application logic. NOTE: since
+ * there is only a single LED on-board, this is function is not very useful.
+ *
+ ****************************************************************************/
+
+void board_userled_all(uint8_t ledset)
+{
+ stm32_gpiowrite(GPIO_LD3, (ledset & BOARD_STATUS_LED_BIT) != 0);
+}
+
+#endif /* !CONFIG_ARCH_LEDS */
diff --git a/configs/stm32f769i-disco/src/stm32f769i-disco.h b/configs/stm32f769i-disco/src/stm32f769i-disco.h
new file mode 100644
index 00000000000..7565fa27a5f
--- /dev/null
+++ b/configs/stm32f769i-disco/src/stm32f769i-disco.h
@@ -0,0 +1,125 @@
+/****************************************************************************************************
+ * configs/stm32f769i-disco/src/stm32f769i-disco.h
+ *
+ * Copyright (C) 2015 Gregory Nutt. All rights reserved.
+ * Authors: Gregory Nutt
+ *
+ * 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 __CONFIGS_STM32F769I_DISCO_SRC_STM32F769I_DISCO__H
+#define __CONFIGS_STM32F769I_DISCO_SRC_STM32F769I_DISCO__H
+
+/****************************************************************************************************
+ * Included Files
+ ****************************************************************************************************/
+
+#include
+#include
+#include
+
+/****************************************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************************************/
+/* procfs File System */
+
+#ifdef CONFIG_FS_PROCFS
+# ifdef CONFIG_NSH_PROC_MOUNTPOINT
+# define STM32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT
+# else
+# define STM32_PROCFS_MOUNTPOINT "/proc"
+# endif
+#endif
+
+/* STM32F769 Discovery GPIOs ***********************************************************************/
+/* The STM32F769I-DISCO has one user controllable LED: LD3.
+ *
+ * LD3 is controlled by PA12 which is also the SPI2_SCK at the Arduino interface.
+ * LD3 is on when PA12 is high.
+ */
+
+#define GPIO_LD3 (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | GPIO_OUTPUT_CLEAR | \
+ GPIO_PORTA | GPIO_PIN12)
+
+/* Pushbutton B1, labelled "User", is connected to GPIO PA0. A high value will be sensed when the
+ * button is depressed. Note that the EXTI interrupt is configured.
+ */
+
+#define GPIO_BTN_USER (GPIO_INPUT | GPIO_FLOAT | GPIO_EXTI | GPIO_PORTA | GPIO_PIN0)
+
+/* Sporadic scheduler instrumentation. This configuration has been used for evaluating the NuttX
+ * sporadic scheduler. In this evaluation, two GPIO outputs are used. One indicating the priority
+ * (high or low) of the sporadic thread and one indicating where the thread is running or not.
+ *
+ * There is nothing special about the pin selections:
+ *
+ * Arduino D2 PJ1 - Indicates priority1
+ * Arduino D4 PJ0 - Indicates that the thread is running
+ */
+
+#define GPIO_SCHED_HIGHPRI (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | GPIO_OUTPUT_CLEAR | \
+ GPIO_PORTJ | GPIO_PIN1)
+#define GPIO_SCHED_RUNNING (GPIO_OUTPUT | GPIO_PUSHPULL | GPIO_SPEED_50MHz | GPIO_OUTPUT_CLEAR | \
+ GPIO_PORTJ | GPIO_PIN0)
+
+/****************************************************************************************************
+ * Public data
+ ****************************************************************************************************/
+
+#ifndef __ASSEMBLY__
+
+/****************************************************************************************************
+ * Public Functions
+ ****************************************************************************************************/
+
+/****************************************************************************************************
+ * Name: stm32_spidev_initialize
+ *
+ * Description:
+ * Called to configure SPI chip select GPIO pins for the stm32f769i-disco board.
+ *
+ ****************************************************************************************************/
+
+void weak_function stm32_spidev_initialize(void);
+
+/****************************************************************************************************
+ * Name: arch_sporadic_initialize
+ *
+ * Description:
+ * This configuration has been used for evaluating the NuttX sporadic scheduler.
+ *
+ ****************************************************************************************************/
+
+#ifdef CONFIG_SPORADIC_INSTRUMENTATION
+void arch_sporadic_initialize(void);
+#endif
+
+#endif /* __ASSEMBLY__ */
+#endif /* __CONFIGS_STM32F769I_DISCO_SRC_STM32F769I_DISCO_H */
+
diff --git a/drivers/usbdev/cdcacm.c b/drivers/usbdev/cdcacm.c
index bf845f778b9..dca91d8b6bc 100644
--- a/drivers/usbdev/cdcacm.c
+++ b/drivers/usbdev/cdcacm.c
@@ -1358,10 +1358,10 @@ static int cdcacm_setup(FAR struct usbdevclass_driver_s *driver,
case USB_DESC_TYPE_CONFIG:
{
#ifdef CONFIG_USBDEV_DUALSPEED
- ret = cdcacm_mkcfgdesc(ctrlreq->buf, dev->speed,
- ctrl->req);
+ ret = cdcacm_mkcfgdesc(ctrlreq->buf, &priv->devdesc,
+ dev->speed, ctrl->req);
#else
- ret = cdcacm_mkcfgdesc(ctrlreq->buf, 0);
+ ret = cdcacm_mkcfgdesc(ctrlreq->buf, &priv->devdesc);
#endif
}
break;
@@ -2377,6 +2377,9 @@ int cdcacm_classobject(int minor, FAR struct usbdev_description_s *devdesc,
sq_init(&priv->reqlist);
priv->minor = minor;
+
+ /* Save the caller provided device description (composite only) */
+
memcpy(&priv->devdesc, devdesc,
sizeof(struct usbdev_description_s));
@@ -2487,10 +2490,16 @@ int cdcacm_initialize(int minor, FAR void **handle)
/* Endpoints.
*
- * Endpoint numbers must be provided by board-specific logic.
+ * Endpoint numbers must be provided by board-specific logic when
+ * CDC/ACM is used in a composite device.
*/
devdesc.nendpoints = CDCACM_NUM_EPS;
+#ifndef CONFIG_CDCACM_COMPOSITE
+ devdesc.epno[CDCACM_EP_INTIN_IDX] = CONFIG_CDCACM_EPINTIN;
+ devdesc.epno[CDCACM_EP_BULKIN_IDX] = CONFIG_CDCACM_EPBULKIN;
+ devdesc.epno[CDCACM_EP_BULKOUT_IDX] = CONFIG_CDCACM_EPBULKOUT;
+#endif
/* Get an instance of the serial driver class object */
diff --git a/drivers/usbdev/cdcacm_desc.c b/drivers/usbdev/cdcacm_desc.c
index 365480770a7..73ba17738fe 100644
--- a/drivers/usbdev/cdcacm_desc.c
+++ b/drivers/usbdev/cdcacm_desc.c
@@ -95,7 +95,6 @@ static const struct usb_devdesc_s g_devdesc =
};
#endif
-
#if !defined(CONFIG_CDCACM_COMPOSITE) && defined(CONFIG_USBDEV_DUALSPEED)
static const struct usb_qualdesc_s g_qualdesc =
{
@@ -114,10 +113,6 @@ static const struct usb_qualdesc_s g_qualdesc =
};
#endif
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
/****************************************************************************
* Public Functions
****************************************************************************/
@@ -249,89 +244,89 @@ int cdcacm_copy_epdesc(enum cdcacm_epdesc_e epid,
{
case CDCACM_EPINTIN: /* Interrupt IN endpoint */
{
- epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
- epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
- epdesc->addr = CDCACM_MKEPINTIN(devdesc); /* Endpoint address */
- epdesc->attr = CDCACM_EPINTIN_ATTR; /* Endpoint attributes */
+ epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
+ epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
+ epdesc->addr = CDCACM_MKEPINTIN(devdesc); /* Endpoint address */
+ epdesc->attr = CDCACM_EPINTIN_ATTR; /* Endpoint attributes */
#ifdef CONFIG_USBDEV_DUALSPEED
- if (hispeed)
- {
- /* Maximum packet size (high speed) */
+ if (hispeed)
+ {
+ /* Maximum packet size (high speed) */
- epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_HSSIZE);
- epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_HSSIZE);
- }
- else
+ epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_HSSIZE);
+ epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_HSSIZE);
+ }
+ else
#endif
- {
- /* Maximum packet size (full speed) */
+ {
+ /* Maximum packet size (full speed) */
- epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE);
- epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE);
- }
+ epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE);
+ epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPINTIN_FSSIZE);
+ }
- epdesc->interval = 10; /* Interval */
- }
- break;
+ epdesc->interval = 10; /* Interval */
+ }
+ break;
case CDCACM_EPBULKOUT: /* Bulk OUT endpoint */
- {
- epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
- epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
- epdesc->addr = CDCACM_MKEPBULKOUT(devdesc); /* Endpoint address */
- epdesc->attr = CDCACM_EPOUTBULK_ATTR; /* Endpoint attributes */
+ {
+ epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
+ epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
+ epdesc->addr = CDCACM_MKEPBULKOUT(devdesc); /* Endpoint address */
+ epdesc->attr = CDCACM_EPOUTBULK_ATTR; /* Endpoint attributes */
#ifdef CONFIG_USBDEV_DUALSPEED
- if (hispeed)
- {
- /* Maximum packet size (high speed) */
+ if (hispeed)
+ {
+ /* Maximum packet size (high speed) */
- epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKOUT_HSSIZE);
- epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKOUT_HSSIZE);
- }
- else
+ epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKOUT_HSSIZE);
+ epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKOUT_HSSIZE);
+ }
+ else
#endif
- {
- /* Maximum packet size (full speed) */
+ {
+ /* Maximum packet size (full speed) */
- epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKOUT_FSSIZE);
- epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKOUT_FSSIZE);
- }
+ epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKOUT_FSSIZE);
+ epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKOUT_FSSIZE);
+ }
- epdesc->interval = 1; /* Interval */
- }
- break;
+ epdesc->interval = 1; /* Interval */
+ }
+ break;
case CDCACM_EPBULKIN: /* Bulk IN endpoint */
- {
- epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
- epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
- epdesc->addr = CDCACM_MKEPBULKIN(devdesc); /* Endpoint address */
- epdesc->attr = CDCACM_EPINBULK_ATTR; /* Endpoint attributes */
+ {
+ epdesc->len = USB_SIZEOF_EPDESC; /* Descriptor length */
+ epdesc->type = USB_DESC_TYPE_ENDPOINT; /* Descriptor type */
+ epdesc->addr = CDCACM_MKEPBULKIN(devdesc); /* Endpoint address */
+ epdesc->attr = CDCACM_EPINBULK_ATTR; /* Endpoint attributes */
#ifdef CONFIG_USBDEV_DUALSPEED
- if (hispeed)
- {
- /* Maximum packet size (high speed) */
+ if (hispeed)
+ {
+ /* Maximum packet size (high speed) */
- epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKIN_HSSIZE);
- epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKIN_HSSIZE);
- }
- else
+ epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKIN_HSSIZE);
+ epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKIN_HSSIZE);
+ }
+ else
#endif
- {
- /* Maximum packet size (full speed) */
+ {
+ /* Maximum packet size (full speed) */
- epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKIN_FSSIZE);
- epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKIN_FSSIZE);
- }
+ epdesc->mxpacketsize[0] = LSBYTE(CONFIG_CDCACM_EPBULKIN_FSSIZE);
+ epdesc->mxpacketsize[1] = MSBYTE(CONFIG_CDCACM_EPBULKIN_FSSIZE);
+ }
- epdesc->interval = 1; /* Interval */
- }
- break;
+ epdesc->interval = 1; /* Interval */
+ }
+ break;
default:
- return 0;
+ return 0;
}
return sizeof(struct usb_epdesc_s);
@@ -368,7 +363,7 @@ int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf,
}
#endif
- /* fill in all descriptors directly to the buf */
+ /* Fill in all descriptors directly to the buf */
/* Configuration Descriptor. If the serial device is used in as part
* or a composite device, then the configuration descriptor is
@@ -479,7 +474,6 @@ int16_t cdcacm_mkcfgdesc(FAR uint8_t *buf,
length += sizeof(struct cdc_hdr_funcdesc_s);
-
/* ACM functional descriptor */
if (buf != NULL)
@@ -604,5 +598,3 @@ FAR const struct usb_qualdesc_s *cdcacm_getqualdesc(void)
return &g_qualdesc;
}
#endif
-
-
diff --git a/drivers/usbdev/composite_desc.c b/drivers/usbdev/composite_desc.c
index 3a86099fd93..a862e29c958 100644
--- a/drivers/usbdev/composite_desc.c
+++ b/drivers/usbdev/composite_desc.c
@@ -53,18 +53,6 @@
#ifdef CONFIG_USBDEV_COMPOSITE
-/****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
-
-/****************************************************************************
- * Private Types
- ****************************************************************************/
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
/****************************************************************************
* Private Data
****************************************************************************/
diff --git a/libc/math/lib_ceil.c b/libc/math/lib_ceil.c
index 329e20b24ff..28ebf44f2fc 100644
--- a/libc/math/lib_ceil.c
+++ b/libc/math/lib_ceil.c
@@ -41,8 +41,10 @@
#ifdef CONFIG_HAVE_DOUBLE
double ceil(double x)
{
+ double x1 = x;
+
modf(x, &x);
- if (x > 0.0)
+ if (x1 > 0.0 && fabs(x1 - x) > 0.0)
{
x += 1.0;
}
diff --git a/libc/math/lib_ceilf.c b/libc/math/lib_ceilf.c
index d9394bd8a17..e3af055202e 100644
--- a/libc/math/lib_ceilf.c
+++ b/libc/math/lib_ceilf.c
@@ -37,8 +37,10 @@
float ceilf(float x)
{
+ float x1 = x;
+
modff(x, &x);
- if (x > 0.0F)
+ if (x1 > 0.0F && fabsf(x1 - x) > 0.0F)
{
x += 1.0F;
}
diff --git a/libc/math/lib_ceill.c b/libc/math/lib_ceill.c
index 2e16ab73add..14c665b5a4c 100644
--- a/libc/math/lib_ceill.c
+++ b/libc/math/lib_ceill.c
@@ -41,8 +41,10 @@
#ifdef CONFIG_HAVE_LONG_DOUBLE
long double ceill(long double x)
{
+ long double x1 = x;
+
modfl(x, &x);
- if (x > 0.0)
+ if (x1 > 0.0 && fabsl(x1 - x) > 0.0)
{
x += 1.0;
}
diff --git a/libc/math/lib_modf.c b/libc/math/lib_modf.c
index 5782ebf010b..1c1b8ffcf54 100644
--- a/libc/math/lib_modf.c
+++ b/libc/math/lib_modf.c
@@ -46,7 +46,7 @@ double modf(double x, double *iptr)
}
else if (fabs(x) < 1.0)
{
- *iptr = 0.0;
+ *iptr = (x * 0.0);
return x;
}
else
diff --git a/libc/math/lib_modff.c b/libc/math/lib_modff.c
index 5c88ff83f28..c6fac3fc5cb 100644
--- a/libc/math/lib_modff.c
+++ b/libc/math/lib_modff.c
@@ -44,7 +44,7 @@ float modff(float x, float *iptr)
}
else if (fabsf(x) < 1.0F)
{
- *iptr = 0.0F;
+ *iptr = (x * 0.0F);
return x;
}
else
diff --git a/libc/math/lib_modfl.c b/libc/math/lib_modfl.c
index 67399845279..e55f4491718 100644
--- a/libc/math/lib_modfl.c
+++ b/libc/math/lib_modfl.c
@@ -49,7 +49,7 @@ long double modfl(long double x, long double *iptr)
}
else if (fabs(x) < 1.0)
{
- *iptr = 0.0;
+ *iptr = (x * 0.0);
return x;
}
else
diff --git a/net/socket/net_poll.c b/net/socket/net_poll.c
index 4365246f34a..80eaff4583b 100644
--- a/net/socket/net_poll.c
+++ b/net/socket/net_poll.c
@@ -100,9 +100,6 @@ int psock_poll(FAR struct socket *psock, FAR struct pollfd *fds, bool setup)
int net_poll(int sockfd, struct pollfd *fds, bool setup)
{
-#ifndef HAVE_NET_POLL
- return -ENOSYS;
-#else
FAR struct socket *psock;
DEBUGASSERT(fds != NULL);
@@ -120,7 +117,6 @@ int net_poll(int sockfd, struct pollfd *fds, bool setup)
/* Then let psock_poll() do the heavy lifting */
return psock_poll(psock, fds, setup);
-#endif /* HAVE_NET_POLL */
}
#endif /* CONFIG_NET && !CONFIG_DISABLE_POLL */
diff --git a/wireless/ieee802154/Kconfig b/wireless/ieee802154/Kconfig
index a940b71b022..c5381c7afd3 100644
--- a/wireless/ieee802154/Kconfig
+++ b/wireless/ieee802154/Kconfig
@@ -128,7 +128,7 @@ config IEEE802154_IND_IRQRESERVE
dynamically allocate the meta data structure with an additional cost
in performance.
- NOTE: Currently marked as experimental and with a default 0 zero
+ NOTE: Currently marked as experimental and with a default of zero
because there are no interrupt level allocations performed by the
current IEEE 802.15.4 MAC code.