From 542d79ef90862518ffcfb500679e293e5a89c864 Mon Sep 17 00:00:00 2001 From: TexZK Date: Wed, 24 Jun 2015 21:24:45 +0200 Subject: LTDC and DMA2D ported to ChibiOS/RT 3 + LTDC and DMA2D peripheral drivers + LTDC and DMA2D demo project --- .../ports/ARMCMx/compilers/GCC/ld/STM32F429xI.ld | 54 + os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c | 3125 ++++++++++++++++ os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h | 690 ++++ os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c | 3792 ++++++++++++++++++++ os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h | 770 ++++ os/hal/ports/STM32/STM32F4xx/platform.mk | 8 +- 6 files changed, 8437 insertions(+), 2 deletions(-) create mode 100644 os/common/ports/ARMCMx/compilers/GCC/ld/STM32F429xI.ld create mode 100644 os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c create mode 100644 os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h create mode 100644 os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c create mode 100644 os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h (limited to 'os') diff --git a/os/common/ports/ARMCMx/compilers/GCC/ld/STM32F429xI.ld b/os/common/ports/ARMCMx/compilers/GCC/ld/STM32F429xI.ld new file mode 100644 index 0000000..1fb424a --- /dev/null +++ b/os/common/ports/ARMCMx/compilers/GCC/ld/STM32F429xI.ld @@ -0,0 +1,54 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio. + + This file is part of ChibiOS. + + ChibiOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/* + * ST32F429xI memory setup. + * Note: Use of ram1, ram2 and ram3 is mutually exclusive with use of ram0. + */ +MEMORY +{ + flash : org = 0x08000000, len = 2M + ram0 : org = 0x20000000, len = 192k /* SRAM1 + SRAM2 + SRAM3 */ + ram1 : org = 0x20000000, len = 112k /* SRAM1 */ + ram2 : org = 0x2001C000, len = 16k /* SRAM2 */ + ram3 : org = 0x20020000, len = 64k /* SRAM3 */ + ram4 : org = 0x10000000, len = 64k /* CCM SRAM */ + ram5 : org = 0x40024000, len = 4k /* BCKP SRAM */ + ram6 : org = 0x00000000, len = 0 + ram7 : org = 0xD0000000, len = 8M /* SDRAM */ +} + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts*/ +REGION_ALIAS("MAIN_STACK_RAM", ram0); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram0); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for SDRAM segment.*/ +REGION_ALIAS("SDRAM_RAM", ram7); + +INCLUDE rules.ld diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c new file mode 100644 index 0000000..9bef3d2 --- /dev/null +++ b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c @@ -0,0 +1,3125 @@ +/* + Copyright (C) 2013-2015 Andrea Zoppi + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file stm32_dma2d.c + * @brief DMA2D/Chrom-ART driver. + */ + +#include "ch.h" +#include "hal.h" + +#include "stm32_dma2d.h" + +#if STM32_DMA2D_USE_DMA2D || defined(__DOXYGEN__) + +/* Ignore annoying warning messages for actually safe code.*/ +#if defined(__GNUC__) && !defined(__DOXYGEN__) +#pragma GCC diagnostic ignored "-Wtype-limits" +#endif + +/** + * @addtogroup dma2d + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief DMA2DD1 driver identifier.*/ +DMA2DDriver DMA2DD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief Bits per pixel lookup table. + */ +static const uint8_t dma2d_bpp[DMA2D_MAX_PIXFMT_ID + 1] = { + 32, /* DMA2D_FMT_ARGB8888 */ + 24, /* DMA2D_FMT_RGB888 */ + 16, /* DMA2D_FMT_RGB565 */ + 16, /* DMA2D_FMT_ARGB1555 */ + 16, /* DMA2D_FMT_ARGB4444 */ + 8, /* DMA2D_FMT_L8 */ + 8, /* DMA2D_FMT_AL44 */ + 16, /* DMA2D_FMT_AL88 */ + 4, /* DMA2D_FMT_L4 */ + 8, /* DMA2D_FMT_A8 */ + 4 /* DMA2D_FMT_A4 */ +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @name DMA2D interrupt handlers + * @{ + */ + +/** + * @brief DMA2D global interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(DMA2D_IRQHandler) { + + DMA2DDriver *const dma2dp = &DMA2DD1; + bool job_done = false; + thread_t *tp = NULL; + + OSAL_IRQ_PROLOGUE(); + + /* Handle Configuration Error ISR.*/ + if ((DMA2D->ISR & DMA2D_ISR_CEIF) && (DMA2D->CR & DMA2D_CR_CEIE)) { + if (dma2dp->config->cfgerr_isr != NULL) + dma2dp->config->cfgerr_isr(dma2dp); + job_done = true; + DMA2D->IFCR |= DMA2D_IFSR_CCEIF; + } + + /* Handle CLUT (Palette) Transfer Complete ISR.*/ + if ((DMA2D->ISR & DMA2D_ISR_CTCIF) && (DMA2D->CR & DMA2D_CR_CTCIE)) { + if (dma2dp->config->paltrfdone_isr != NULL) + dma2dp->config->paltrfdone_isr(dma2dp); + job_done = true; + DMA2D->IFCR |= DMA2D_IFSR_CCTCIF; + } + + /* Handle CLUT (Palette) Access Error ISR.*/ + if ((DMA2D->ISR & DMA2D_ISR_CAEIF) && (DMA2D->CR & DMA2D_CR_CAEIE)) { + if (dma2dp->config->palacserr_isr != NULL) + dma2dp->config->palacserr_isr(dma2dp); + job_done = true; + DMA2D->IFCR |= DMA2D_IFSR_CCAEIF; + } + + /* Handle Transfer Watermark ISR.*/ + if ((DMA2D->ISR & DMA2D_ISR_TWIF) && (DMA2D->CR & DMA2D_CR_TWIE)) { + if (dma2dp->config->trfwmark_isr != NULL) + dma2dp->config->trfwmark_isr(dma2dp); + DMA2D->IFCR |= DMA2D_IFSR_CTWIF; + } + + /* Handle Transfer Complete ISR.*/ + if ((DMA2D->ISR & DMA2D_ISR_TCIF) && (DMA2D->CR & DMA2D_CR_TCIE)) { + if (dma2dp->config->trfdone_isr != NULL) + dma2dp->config->trfdone_isr(dma2dp); + job_done = true; + DMA2D->IFCR |= DMA2D_IFSR_CTCIF; + } + + /* Handle Transfer Error ISR.*/ + if ((DMA2D->ISR & DMA2D_ISR_TEIF) && (DMA2D->CR & DMA2D_CR_TEIE)) { + if (dma2dp->config->trferr_isr != NULL) + dma2dp->config->trferr_isr(dma2dp); + job_done = true; + DMA2D->IFCR |= DMA2D_IFSR_CTEIF; + } + + if (job_done) { + osalSysLockFromISR(); + osalDbgAssert(dma2dp->state == DMA2D_ACTIVE, "invalid state"); + + #if DMA2D_USE_WAIT + /* Wake the waiting thread up.*/ + if (dma2dp->thread != NULL) { + tp = dma2dp->thread; + dma2dp->thread = NULL; + tp->p_u.rdymsg = MSG_OK; + chSchReadyI(tp); + } + #endif /* DMA2D_USE_WAIT */ + + dma2dp->state = DMA2D_READY; + osalSysUnlockFromISR(); + } + + OSAL_IRQ_EPILOGUE(); +} + +/** @} */ + +/** + * @name DMA2D driver-specific methods + * @{ + */ + +/** + * @brief DMA2D Driver initialization. + * @details Initializes the DMA2D subsystem and chosen drivers. Should be + * called at board initialization. + * + * @init + */ +void dma2dInit(void) { + + /* Reset the DMA2D hardware module.*/ + rccResetDMA2D(); + + /* Enable the DMA2D clock.*/ + rccEnableDMA2D(false); + + /* Driver struct initialization.*/ + dma2dObjectInit(&DMA2DD1); + DMA2DD1.state = DMA2D_STOP; +} + +/** + * @brief Initializes the standard part of a @p DMA2DDriver structure. + * + * @param[out] dma2dp pointer to the @p DMA2DDriver object + * + * @init + */ +void dma2dObjectInit(DMA2DDriver *dma2dp) { + + osalDbgCheck(dma2dp == &DMA2DD1); + + dma2dp->state = DMA2D_UNINIT; + dma2dp->config = NULL; +#if DMA2D_USE_WAIT + dma2dp->thread = NULL; +#endif /* DMA2D_USE_WAIT */ +#if (TRUE == DMA2D_USE_MUTUAL_EXCLUSION) +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxObjectInit(&dma2dp->lock); +#else + chSemObjectInit(&dma2dp->lock, 1); +#endif +#endif /* (TRUE == DMA2D_USE_MUTUAL_EXCLUSION) */ +} + +/** + * @brief Get the driver state. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @retun driver state + * + * @iclass + */ +dma2d_state_t dma2dGetStateI(DMA2DDriver *dma2dp) { + + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheckClassI(); + + return dma2dp->state; +} + +/** + * @brief Get the driver state. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @retun driver state + * + * @api + */ +dma2d_state_t dma2dGetState(DMA2DDriver *dma2dp) { + + dma2d_state_t state; + chSysLock(); + state = dma2dGetStateI(dma2dp); + chSysUnlock(); + return state; +} + +/** + * @brief Configures and activates the DMA2D peripheral. + * @pre DMA2D is stopped. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] configp pointer to the @p DMA2DConfig object + * + * @api + */ +void dma2dStart(DMA2DDriver *dma2dp, const DMA2DConfig *configp) { + + chSysLock(); + + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck(configp != NULL); + osalDbgAssert(dma2dp->state == DMA2D_STOP, "invalid state"); + + dma2dp->config = configp; + + /* Turn off the controller and its interrupts.*/ + DMA2D->CR = 0; + + /* Enable interrupts, except Line Watermark.*/ + nvicEnableVector(STM32_DMA2D_NUMBER, STM32_DMA2D_IRQ_PRIORITY); + + DMA2D->CR = DMA2D_CR_CEIE | DMA2D_CR_CTCIE | DMA2D_CR_CAEIE | + DMA2D_CR_TCIE | DMA2D_CR_TEIE; + + dma2dp->state = DMA2D_READY; + chSysUnlock(); +} + +/** + * @brief Deactivates the DMA2D peripheral. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dStop(DMA2DDriver *dma2dp) { + + chSysLock(); + + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "invalid state"); +#if DMA2D_USE_WAIT + osalDbgAssert(dma2dp->thread == NULL, "still waiting"); +#endif /* DMA2D_USE_WAIT */ + + dma2dp->state = DMA2D_STOP; + chSysUnlock(); +} + +#if DMA2D_USE_MUTUAL_EXCLUSION + +/** + * @brief Gains exclusive access to the DMA2D module. + * @details This function tries to gain ownership to the DMA2D module, if the + * module is already being used then the invoking thread is queued. + * @pre In order to use this function the option + * @p DMA2D_USE_MUTUAL_EXCLUSION must be enabled. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @sclass + */ +void dma2dAcquireBusS(DMA2DDriver *dma2dp) { + + osalDbgCheckClassS(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxLockS(&dma2dp->lock); +#else + chSemWaitS(&dma2dp->lock); +#endif +} + +/** + * @brief Gains exclusive access to the DMA2D module. + * @details This function tries to gain ownership to the DMA2D module, if the + * module is already being used then the invoking thread is queued. + * @pre In order to use this function the option + * @p DMA2D_USE_MUTUAL_EXCLUSION must be enabled. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dAcquireBus(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dAcquireBusS(dma2dp); + chSysUnlock(); +} + +/** + * @brief Releases exclusive access to the DMA2D module. + * @pre In order to use this function the option + * @p DMA2D_USE_MUTUAL_EXCLUSION must be enabled. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @sclass + */ +void dma2dReleaseBusS(DMA2DDriver *dma2dp) { + + osalDbgCheckClassS(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxUnlockS(&dma2dp->lock); +#else + chSemSignalI(&dma2dp->lock); +#endif +} + +/** + * @brief Releases exclusive access to the DMA2D module. + * @pre In order to use this function the option + * @p DMA2D_USE_MUTUAL_EXCLUSION must be enabled. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dReleaseBus(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dReleaseBusS(dma2dp); + chSysUnlock(); +} + +#endif /* DMA2D_USE_MUTUAL_EXCLUSION */ + +/** @} */ + +/** + * @name DMA2D global methods + * @{ + */ + +/** + * @brief Get watermark position. + * @details Gets the watermark line position. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return watermark line position + * + * @iclass + */ +uint16_t dma2dGetWatermarkPosI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (uint16_t)(DMA2D->LWR & DMA2D_LWR_LW); +} + +/** + * @brief Get watermark position. + * @details Gets the watermark line position. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return watermark line position + * + * @api + */ +uint16_t dma2dGetWatermarkPos(DMA2DDriver *dma2dp) { + + uint16_t line; + chSysLock(); + line = dma2dGetWatermarkPosI(dma2dp); + chSysUnlock(); + return line; +} + +/** + * @brief Set watermark position. + * @details Sets the watermark line position. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] line watermark line position + * + * @iclass + */ +void dma2dSetWatermarkPosI(DMA2DDriver *dma2dp, uint16_t line) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + (void)dma2dp; + + DMA2D->LWR = (DMA2D->LWR & ~DMA2D_LWR_LW) | + ((uint32_t)line & DMA2D_LWR_LW); +} + +/** + * @brief Set watermark position. + * @details Sets the watermark line position. + * @note The interrupt is invoked after the last pixel of the watermark line + * is written. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] line watermark line position + * + * @iclass + */ +void dma2dSetWatermarkPos(DMA2DDriver *dma2dp, uint16_t line) { + + chSysLock(); + dma2dSetWatermarkPosI(dma2dp, line); + chSysUnlock(); +} + +/** + * @brief Watermark interrupt enabled. + * @details Tells whether the watermark interrupt is enabled. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return enabled + * + * @iclass + */ +bool dma2dIsWatermarkEnabledI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (DMA2D->CR & DMA2D_CR_TWIE) != 0; +} + +/** + * @brief Watermark interrupt enabled. + * @details Tells whether the watermark interrupt is enabled. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return enabled + * + * @api + */ +bool dma2dIsWatermarkEnabled(DMA2DDriver *dma2dp) { + + bool enabled; + chSysLock(); + enabled = dma2dIsWatermarkEnabledI(dma2dp); + chSysUnlock(); + return enabled; +} + +/** + * @brief Enable watermark interrupt. + * @details Enables the watermark interrupt. The interrupt is invoked after the + * last pixel of the watermark line is written to the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @iclass + */ +void dma2dEnableWatermarkI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + DMA2D->CR |= DMA2D_CR_TWIE; +} + +/** + * @brief Enable watermark interrupt. + * @details Enables the watermark interrupt. The interrupt is invoked after the + * last pixel of the watermark line is written to the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dEnableWatermark(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dEnableWatermarkI(dma2dp); + chSysUnlock(); +} + +/** + * @brief Disable watermark interrupt. + * @details Disables the watermark interrupt. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @iclass + */ +void dma2dDisableWatermarkI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + DMA2D->CR &= ~DMA2D_CR_TWIE; +} + +/** + * @brief Disable watermark interrupt. + * @details Disables the watermark interrupt. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dDisableWatermark(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dDisableWatermarkI(dma2dp); + chSysUnlock(); +} + +/** + * @brief Get dead time cycles. + * @details Gets the minimum dead time DMA2D clock cycles between DMA2D + * transactions. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return dead time, in DMA2D clock cycles + * + * @iclass + */ +uint32_t dma2dGetDeadTimeI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (DMA2D->AMTCR & DMA2D_AMTCR_DT) >> 8; +} + +/** + * @brief Get dead time cycles. + * @details Gets the minimum dead time DMA2D clock cycles between DMA2D + * transactions. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return dead time, in DMA2D clock cycles + * + * @api + */ +uint32_t dma2dGetDeadTime(DMA2DDriver *dma2dp) { + + uint32_t cycles; + chSysLock(); + cycles = dma2dGetDeadTimeI(dma2dp); + chSysUnlock(); + return cycles; +} + +/** + * @brief Set dead time cycles. + * @details Sets the minimum dead time DMA2D clock cycles between DMA2D + * transactions. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] cycles dead time, in DMA2D clock cycles + * + * @iclass + */ +void dma2dSetDeadTimeI(DMA2DDriver *dma2dp, uint32_t cycles) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(cycles <= DMA2D_MAX_DEADTIME_CYCLES, "bounds"); + (void)dma2dp; + + DMA2D->AMTCR = (DMA2D->AMTCR & ~DMA2D_AMTCR_DT) | + ((cycles << 8) & DMA2D_AMTCR_DT); +} + +/** + * @brief Set dead time cycles. + * @details Sets the minimum dead time DMA2D clock cycles between DMA2D + * transactions. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] cycles dead time, in DMA2D clock cycles + * + * @api + */ +void dma2dSetDeadTime(DMA2DDriver *dma2dp, uint32_t cycles) { + + chSysLock(); + dma2dSetDeadTimeI(dma2dp, cycles); + chSysUnlock(); +} + +/** + * @brief Dead time enabled. + * @details Tells whether the dead time between DMA2D transactions is enabled. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return enabled + * + * @iclass + */ +bool dma2dIsDeadTimeEnabledI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (DMA2D->AMTCR & DMA2D_AMTCR_EN) != 0; +} + +/** + * @brief Dead time enabled. + * @details Tells whether the dead time between DMA2D transactions is enabled. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return enabled + * + * @api + */ +bool dma2dIsDeadTimeEnabled(DMA2DDriver *dma2dp) { + + bool enabled; + chSysLock(); + enabled = dma2dIsDeadTimeEnabledI(dma2dp); + chSysUnlock(); + return enabled; +} + +/** + * @brief Enable dead time. + * @details Enables the dead time between DMA2D transactions. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @iclass + */ +void dma2dEnableDeadTimeI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + DMA2D->AMTCR |= DMA2D_AMTCR_EN; +} + +/** + * @brief Enable dead time. + * @details Enables the dead time between DMA2D transactions. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dEnableDeadTime(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dEnableDeadTimeI(dma2dp); + chSysUnlock(); +} + +/** + * @brief Disable dead time. + * @details Disables the dead time between DMA2D transactions. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @iclass + */ +void dma2dDisableDeadTimeI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + DMA2D->AMTCR &= ~DMA2D_AMTCR_EN; +} + +/** + * @brief Disable dead time. + * @details Disables the dead time between DMA2D transactions. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dDisableDeadTime(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dDisableDeadTimeI(dma2dp); + chSysUnlock(); +} + +/** @} */ + +/** + * @name DMA2D job (transaction) methods + * @{ + */ + +/** + * @brief Get job mode. + * @details Gets the job mode. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return job mode + * + * @iclass + */ +dma2d_jobmode_t dma2dJobGetModeI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_jobmode_t)(DMA2D->CR & DMA2D_CR_MODE); +} + +/** + * @brief Get job mode. + * @details Gets the job mode. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return job mode + * + * @api + */ +dma2d_jobmode_t dma2dJobGetMode(DMA2DDriver *dma2dp) { + + dma2d_jobmode_t mode; + chSysLock(); + mode = dma2dJobGetModeI(dma2dp); + chSysUnlock(); + return mode; +} + +/** + * @brief Set job mode. + * @details Sets the job mode. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] mode job mode + * + * @iclass + */ +void dma2dJobSetModeI(DMA2DDriver *dma2dp, dma2d_jobmode_t mode) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert((mode & ~DMA2D_CR_MODE) == 0, "bounds"); + (void)dma2dp; + + DMA2D->CR = (DMA2D->CR & ~DMA2D_CR_MODE) | ((uint32_t)mode & DMA2D_CR_MODE); +} + +/** + * @brief Set job mode. + * @details Sets the job mode. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] mode job mode + * + * @api + */ +void dma2dJobSetMode(DMA2DDriver *dma2dp, dma2d_jobmode_t mode) { + + chSysLock(); + dma2dJobSetModeI(dma2dp, mode); + chSysUnlock(); +} + +/** + * @brief Get job size. + * @details Gets the job size. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] widthp pointer to the job width, in pixels + * @param[out] heightp pointer to the job height, in pixels + * + * @iclass + */ +void dma2dJobGetSizeI(DMA2DDriver *dma2dp, + uint16_t *widthp, uint16_t *heightp) { + + uint32_t r; + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck(widthp != NULL); + osalDbgCheck(heightp != NULL); + (void)dma2dp; + + r = DMA2D->NLR; + *widthp = (uint16_t)((r & DMA2D_NLR_PL) >> 16); + *heightp = (uint16_t)((r & DMA2D_NLR_NL) >> 0); +} + +/** + * @brief Get job size. + * @details Gets the job size. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] widthp pointer to the job width, in pixels + * @param[out] heightp pointer to the job height, in pixels + * + * @api + */ +void dma2dJobGetSize(DMA2DDriver *dma2dp, + uint16_t *widthp, uint16_t *heightp) { + + chSysLock(); + dma2dJobGetSizeI(dma2dp, widthp, heightp); + chSysUnlock(); +} + +/** + * @brief Set job size. + * @details Sets the job size. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] widthp job width, in pixels + * @param[in] heightp job height, in pixels + * + * @iclass + */ +void dma2dJobSetSizeI(DMA2DDriver *dma2dp, uint16_t width, uint16_t height) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert(width <= DMA2D_MAX_WIDTH, "bounds"); + osalDbgAssert(height <= DMA2D_MAX_HEIGHT, "bounds"); + (void)dma2dp; + + DMA2D->NLR = (((uint32_t)width << 16) & DMA2D_NLR_PL) | + (((uint32_t)height << 0) & DMA2D_NLR_NL); +} + +/** + * @brief Set job size. + * @details Sets the job size. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] widthp job width, in pixels + * @param[in] heightp job height, in pixels + * + * @api + */ +void dma2dJobSetSize(DMA2DDriver *dma2dp, uint16_t width, uint16_t height) { + + chSysLock(); + dma2dJobSetSizeI(dma2dp, width, height); + chSysUnlock(); +} + +/** + * @brief Job executing. + * @details Tells whether a job (transaction) is active or paused. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return executing + * + * @iclass + */ +bool dma2dJobIsExecutingI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + + return dma2dp->state > DMA2D_READY; +} + +/** + * @brief Job executing. + * @details Tells whether a job (transaction) is active or paused. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return executing + * + * @api + */ +bool dma2dJobIsExecuting(DMA2DDriver *dma2dp) { + + bool executing; + chSysLock(); + executing = dma2dJobIsExecutingI(dma2dp); + chSysUnlock(); + return executing; +} + +/** + * @brief Start job. + * @details The job is started, and the DMA2D is set to active. + * @note Should there be invalid parameters, the appropriate interrupt + * handler will be invoked, and the DMA2D set back to ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @iclass + */ +void dma2dJobStartI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + + dma2dp->state = DMA2D_ACTIVE; + DMA2D->CR |= DMA2D_CR_START; +} + +/** + * @brief Start job. + * @details The job is started, and the DMA2D is set to active. + * @note Should there be invalid parameters, the appropriate interrupt + * handler will be invoked, and the DMA2D set back to ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dJobStart(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dJobStartI(dma2dp); + chSysUnlock(); +} + +/** + * @brief Execute job. + * @details Starts the job and waits for its completion, synchronously. + * @note Should there be invalid parameters, the appropriate interrupt + * handler will be invoked, and the DMA2D set back to ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @sclass + */ +void dma2dJobExecuteS(DMA2DDriver *dma2dp) { + + osalDbgCheckClassS(); + osalDbgCheck(dma2dp == &DMA2DD1); + + dma2dJobStartI(dma2dp); +#if DMA2D_USE_WAIT + dma2dp->thread = chThdGetSelfX(); + chSchGoSleepS(CH_STATE_SUSPENDED); +#else + while (DMA2D->CR & DMA2D_CR_START) + chSchDoYieldS(); +#endif +} + +/** + * @brief Execute job. + * @details Starts the job and waits for its completion, synchronously. + * @note Should there be invalid parameters, the appropriate interrupt + * handler will be invoked, and the DMA2D set back to ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dJobExecute(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dJobExecuteS(dma2dp); + chSysUnlock(); +} + +/** + * @brief Suspend current job. + * @details Suspends the current job. The driver is set to a paused state. + * @pre There is an active job. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @iclass + */ +void dma2dJobSuspendI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck((DMA2D->CR & DMA2D_CR_SUSP) == 0); + osalDbgAssert(dma2dp->state == DMA2D_ACTIVE, "invalid state"); + + dma2dp->state = DMA2D_PAUSED; + DMA2D->CR |= DMA2D_CR_SUSP; +} + +/** + * @brief Suspend current job. + * @details Suspends the current job. The driver is set to a paused state. + * @pre There is an active job. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dJobSuspend(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dJobSuspendI(dma2dp); + chSysUnlock(); +} + +/** + * @brief Resume current job. + * @details Resumes the current job. + * @pre There is a paused job. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @iclass + */ +void dma2dJobResumeI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck((DMA2D->CR & DMA2D_CR_SUSP) != 0); + osalDbgAssert(dma2dp->state == DMA2D_PAUSED, "invalid state"); + + dma2dp->state = DMA2D_ACTIVE; + DMA2D->CR &= ~DMA2D_CR_SUSP; +} + +/** + * @brief Resume current job. + * @details Resumes the current job. + * @pre There is a paused job. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dJobResume(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dJobResumeI(dma2dp); + chSysUnlock(); +} + +/** + * @brief Abort current job. + * @details Abots the current job (if any), and the driver becomes ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @iclass + */ +void dma2dJobAbortI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck((DMA2D->CR & DMA2D_CR_SUSP) == 0); + osalDbgAssert(dma2dp->state >= DMA2D_READY, "invalid state"); + + dma2dp->state = DMA2D_READY; + DMA2D->CR |= DMA2D_CR_ABORT; +} + +/** + * @brief Abort current job. + * @details Abots the current job (if any), and the driver becomes ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @api + */ +void dma2dJobAbort(DMA2DDriver *dma2dp) { + + chSysLock(); + dma2dJobAbortI(dma2dp); + chSysUnlock(); +} + +/** @} */ + +/** + * @name DMA2D background layer methods + * @{ + */ + +/** + * @brief Get background layer buffer address. + * @details Gets the buffer address of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return buffer address + * + * @iclass + */ +void *dma2dBgGetAddressI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (void *)DMA2D->BGMAR; +} + +/** + * @brief Get background layer buffer address. + * @details Gets the buffer address of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return buffer address + * + * @api + */ +void *dma2dBgGetAddress(DMA2DDriver *dma2dp) { + + void *bufferp; + chSysLock(); + bufferp = dma2dBgGetAddressI(dma2dp); + chSysUnlock(); + return bufferp; +} + +/** + * @brief Set background layer buffer address. + * @details Sets the buffer address of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] bufferp buffer address + * + * @iclass + */ +void dma2dBgSetAddressI(DMA2DDriver *dma2dp, void *bufferp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgCheck(dma2dIsAligned(bufferp, dma2dBgGetPixelFormatI(dma2dp))); + (void)dma2dp; + + DMA2D->BGMAR = (uint32_t)bufferp; +} + +/** + * @brief Set background layer buffer address. + * @details Sets the buffer address of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] bufferp buffer address + * + * @api + */ +void dma2dBgSetAddress(DMA2DDriver *dma2dp, void *bufferp) { + + chSysLock(); + dma2dBgSetAddressI(dma2dp, bufferp); + chSysUnlock(); +} + +/** + * @brief Get background layer wrap offset. + * @details Gets the buffer line wrap offset of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return wrap offset, in pixels + * + * @iclass + */ +size_t dma2dBgGetWrapOffsetI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (size_t)(DMA2D->BGOR & DMA2D_BGOR_LO); +} + +/** + * @brief Get background layer wrap offset. + * @details Gets the buffer line wrap offset of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return wrap offset, in pixels + * + * @api + */ +size_t dma2dBgGetWrapOffset(DMA2DDriver *dma2dp) { + + size_t offset; + chSysLock(); + offset = dma2dBgGetWrapOffsetI(dma2dp); + chSysUnlock(); + return offset; +} + +/** + * @brief Set background layer wrap offset. + * @details Sets the buffer line wrap offset of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] offset wrap offset, in pixels + * + * @iclass + */ +void dma2dBgSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert(offset <= DMA2D_MAX_OFFSET, "bounds"); + (void)dma2dp; + + DMA2D->BGOR = (DMA2D->BGOR & ~DMA2D_BGOR_LO) | + ((uint32_t)offset & DMA2D_BGOR_LO); +} + +/** + * @brief Set background layer wrap offset. + * @details Sets the buffer line wrap offset of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] offset wrap offset, in pixels + * + * @api + */ +void dma2dBgSetWrapOffset(DMA2DDriver *dma2dp, size_t offset) { + + chSysLock(); + dma2dBgSetWrapOffsetI(dma2dp, offset); + chSysUnlock(); +} + +/** + * @brief Get background layer constant alpha. + * @details Gets the constant alpha component of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return constant alpha component, A-8 + * + * @iclass + */ +uint8_t dma2dBgGetConstantAlphaI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (uint8_t)((DMA2D->BGPFCCR & DMA2D_BGPFCCR_ALPHA) >> 24); +} + +/** + * @brief Get background layer constant alpha. + * @details Gets the constant alpha component of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return constant alpha component, A-8 + * + * @api + */ +uint8_t dma2dBgGetConstantAlpha(DMA2DDriver *dma2dp) { + + uint8_t a; + chSysLock(); + a = dma2dBgGetConstantAlphaI(dma2dp); + chSysUnlock(); + return a; +} + +/** + * @brief Set background layer constant alpha. + * @details Sets the constant alpha component of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] a constant alpha component, A-8 + * + * @iclass + */ +void dma2dBgSetConstantAlphaI(DMA2DDriver *dma2dp, uint8_t a) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + (void)dma2dp; + + DMA2D->BGPFCCR = (DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_ALPHA) | + (((uint32_t)a << 24) & DMA2D_BGPFCCR_ALPHA); +} + +/** + * @brief Set background layer constant alpha. + * @details Sets the constant alpha component of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] a constant alpha component, A-8 + * + * @api + */ +void dma2dBgSetConstantAlpha(DMA2DDriver *dma2dp, uint8_t a) { + + chSysLock(); + dma2dBgSetConstantAlphaI(dma2dp, a); + chSysUnlock(); +} + +/** + * @brief Get background layer alpha mode. + * @details Gets the alpha mode of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return alpha mode + * + * @iclass + */ +dma2d_amode_t dma2dBgGetAlphaModeI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_amode_t)(DMA2D->BGPFCCR & DMA2D_BGPFCCR_AM); +} + +/** + * @brief Get background layer alpha mode. + * @details Gets the alpha mode of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return alpha mode + * + * @api + */ +dma2d_amode_t dma2dBgGetAlphaMode(DMA2DDriver *dma2dp) { + + dma2d_amode_t mode; + chSysLock(); + mode = dma2dBgGetAlphaModeI(dma2dp); + chSysUnlock(); + return mode; +} + +/** + * @brief Set background layer alpha mode. + * @details Sets the alpha mode of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] mode alpha mode + * + * @iclass + */ +void dma2dBgSetAlphaModeI(DMA2DDriver *dma2dp, dma2d_amode_t mode) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert((mode & ~DMA2D_BGPFCCR_AM) == 0, "bounds"); + osalDbgAssert((mode & DMA2D_BGPFCCR_AM) != DMA2D_BGPFCCR_AM, "bounds"); + (void)dma2dp; + + DMA2D->BGPFCCR = (DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_AM) | + ((uint32_t)mode & DMA2D_BGPFCCR_AM); +} + +/** + * @brief Set background layer alpha mode. + * @details Sets the alpha mode of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] mode alpha mode + * + * @api + */ +void dma2dBgSetAlphaMode(DMA2DDriver *dma2dp, dma2d_amode_t mode) { + + chSysLock(); + dma2dBgSetAlphaModeI(dma2dp, mode); + chSysUnlock(); +} + +/** + * @brief Get background layer pixel format. + * @details Gets the pixel format of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return pixel format + * + * @iclass + */ +dma2d_pixfmt_t dma2dBgGetPixelFormatI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_pixfmt_t)(DMA2D->BGPFCCR & DMA2D_BGPFCCR_CM); +} + +/** + * @brief Get background layer pixel format. + * @details Gets the pixel format of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return pixel format + * + * @api + */ +dma2d_pixfmt_t dma2dBgGetPixelFormat(DMA2DDriver *dma2dp) { + + dma2d_pixfmt_t fmt; + chSysLock(); + fmt = dma2dBgGetPixelFormatI(dma2dp); + chSysUnlock(); + return fmt; +} + +/** + * @brief Set background layer pixel format. + * @details Sets the pixel format of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] fmt pixel format + * + * @iclass + */ +void dma2dBgSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert(fmt <= DMA2D_MAX_PIXFMT_ID, "bounds"); + (void)dma2dp; + + DMA2D->BGPFCCR = (DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_CM) | + ((uint32_t)fmt & DMA2D_BGPFCCR_CM); +} + +/** + * @brief Set background layer pixel format. + * @details Sets the pixel format of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] fmt pixel format + * + * @api + */ +void dma2dBgSetPixelFormat(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { + + chSysLock(); + dma2dBgSetPixelFormatI(dma2dp, fmt); + chSysUnlock(); +} + +/** + * @brief Get background layer default color. + * @details Gets the default color of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return default color, RGB-888 + * + * @iclass + */ +dma2d_color_t dma2dBgGetDefaultColorI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_color_t)(DMA2D->BGCOLR & 0x00FFFFFF); +} + +/** + * @brief Get background layer default color. + * @details Gets the default color of the background layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return default color, RGB-888 + * + * @api + */ +dma2d_color_t dma2dBgGetDefaultColor(DMA2DDriver *dma2dp) { + + dma2d_color_t c; + chSysLock(); + c = dma2dBgGetDefaultColorI(dma2dp); + chSysUnlock(); + return c; +} + +/** + * @brief Set background layer default color. + * @details Sets the default color of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] c default color, RGB-888 + * + * @iclass + */ +void dma2dBgSetDefaultColorI(DMA2DDriver *dma2dp, dma2d_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + (void)dma2dp; + + DMA2D->BGCOLR = (uint32_t)c & 0x00FFFFFF; +} + +/** + * @brief Set background layer default color. + * @details Sets the default color of the background layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] c default color, RGB-888 + * + * @api + */ +void dma2dBgSetDefaultColor(DMA2DDriver *dma2dp, dma2d_color_t c) { + + chSysLock(); + dma2dBgSetDefaultColorI(dma2dp, c); + chSysUnlock(); +} + +/** + * @brief Get background layer palette specifications. + * @details Gets the palette specifications of the background layer. + * @note The palette colors pointer is actually addressed to a @p volatile + * memory zone. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] palettep pointer to the palette specifications + * + * @iclass + */ +void dma2dBgGetPaletteI(DMA2DDriver *dma2dp, dma2d_palcfg_t *palettep) { + + uint32_t r; + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck(palettep != NULL); + (void)dma2dp; + + r = DMA2D->BGPFCCR; + palettep->colorsp = (const void *)DMA2D->BGCLUT; + palettep->length = (uint16_t)((r & DMA2D_BGPFCCR_CS) >> 8) + 1; + palettep->fmt = (dma2d_pixfmt_t)((r & DMA2D_BGPFCCR_CCM) >> 4); +} + +/** + * @brief Get background layer palette specifications. + * @details Gets the palette specifications of the background layer. + * @note The palette colors pointer is actually addressed to a @p volatile + * memory zone. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] palettep pointer to the palette specifications + * + * @api + */ +void dma2dBgGetPalette(DMA2DDriver *dma2dp, dma2d_palcfg_t *palettep) { + + chSysLock(); + dma2dBgGetPaletteI(dma2dp, palettep); + chSysUnlock(); +} + +/** + * @brief Set background layer palette specifications. + * @details Sets the palette specifications of the background layer. + * @note This function should not be called while the DMA2D is already + * executing a job, otherwise the appropriate error interrupt might be + * invoked. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] palettep pointer to the palette specifications + * + * @sclass + */ +void dma2dBgSetPaletteS(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep) { + + osalDbgCheckClassS(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgCheck(palettep != NULL); + osalDbgCheck(palettep->colorsp != NULL); + osalDbgAssert(palettep->length > 0, "bounds"); + osalDbgAssert(palettep->length <= DMA2D_MAX_PALETTE_LENGTH, "bounds"); + osalDbgAssert(((palettep->fmt == DMA2D_FMT_ARGB8888) || + (palettep->fmt == DMA2D_FMT_RGB888)), "invalid format"); + + DMA2D->BGCMAR = (uint32_t)palettep->colorsp; + DMA2D->BGPFCCR = (DMA2D->BGPFCCR & ~(DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM)) | + ((((uint32_t)palettep->length - 1) << 8) & DMA2D_BGPFCCR_CS) + | ((uint32_t)palettep->fmt << 4); + + dma2dp->state = DMA2D_ACTIVE; + DMA2D->BGPFCCR |= DMA2D_BGPFCCR_START; + +#if DMA2D_USE_WAIT + dma2dp->thread = chThdGetSelfX(); + chSchGoSleepS(CH_STATE_SUSPENDED); +#else + while (DMA2D->BGPFCCR & DMA2D_BGPFCCR_START) + chSchDoYieldS(); +#endif /* DMA2D_USE_WAIT */ +} + +/** + * @brief Set background layer palette specifications. + * @details Sets the palette specifications of the background layer. + * @note This function should not be called while the DMA2D is already + * executing a job, otherwise the appropriate error interrupt might be + * invoked. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] palettep pointer to the palette specifications + * + * @api + */ +void dma2dBgSetPalette(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep) { + + chSysLock(); + dma2dBgSetPaletteS(dma2dp, palettep); + chSysUnlock(); +} + +/** + * @brief Get background layer specifications. + * @details Gets the background layer specifications at once. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @iclass + */ +void dma2dBgGetLayerI(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck(cfgp != NULL); + + cfgp->bufferp = dma2dBgGetAddressI(dma2dp); + cfgp->wrap_offset = dma2dBgGetWrapOffsetI(dma2dp); + cfgp->fmt = dma2dBgGetPixelFormatI(dma2dp); + cfgp->def_color = dma2dBgGetDefaultColorI(dma2dp); + cfgp->const_alpha = dma2dBgGetConstantAlphaI(dma2dp); + if (cfgp->palettep != NULL) + dma2dBgGetPaletteI(dma2dp, (dma2d_palcfg_t *)cfgp->palettep); +} + +/** + * @brief Get background layer specifications. + * @details Gets the background layer specifications at once. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @api + */ +void dma2dBgGetLayer(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp) { + + chSysLock(); + dma2dBgGetLayerI(dma2dp, cfgp); + chSysUnlock(); +} + +/** + * @brief Set background layer specifications. + * @details Sets the background layer specifications at once. + * @note If the palette is unspecified, the layer palette is unmodified. + * @note This function should not be called while the DMA2D is already + * executing a job, otherwise the appropriate error interrupt might be + * invoked. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @sclass + */ +void dma2dBgSetConfigS(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp) { + + osalDbgCheckClassS(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgCheck(cfgp != NULL); + + dma2dBgSetAddressI(dma2dp, cfgp->bufferp); + dma2dBgSetWrapOffsetI(dma2dp, cfgp->wrap_offset); + dma2dBgSetPixelFormatI(dma2dp, cfgp->fmt); + dma2dBgSetDefaultColorI(dma2dp, cfgp->def_color); + dma2dBgSetConstantAlphaI(dma2dp, cfgp->const_alpha); + if (cfgp->palettep != NULL) + dma2dBgSetPaletteS(dma2dp, cfgp->palettep); +} + +/** + * @brief Set background layer specifications. + * @details Sets the background layer specifications at once. + * @note If the palette is unspecified, the layer palette is unmodified. + * @note This function should not be called while the DMA2D is already + * executing a job, otherwise the appropriate error interrupt might be + * invoked. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @api + */ +void dma2dBgSetConfig(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp) { + + chSysLock(); + dma2dBgSetConfigS(dma2dp, cfgp); + chSysUnlock(); +} + +/** @} */ + +/** + * @name DMA2D foreground layer methods + * @{ + */ + +/** + * @brief Get foreground layer buffer address. + * @details Gets the buffer address of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return buffer address + * + * @iclass + */ +void *dma2dFgGetAddressI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (void *)DMA2D->FGMAR; +} + +/** + * @brief Get foreground layer buffer address. + * @details Gets the buffer address of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return buffer address + * + * @api + */ +void *dma2dFgGetAddress(DMA2DDriver *dma2dp) { + + void *bufferp; + chSysLock(); + bufferp = dma2dFgGetAddressI(dma2dp); + chSysUnlock(); + return bufferp; +} + +/** + * @brief Set foreground layer buffer address. + * @details Sets the buffer address of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] bufferp buffer address + * + * @iclass + */ +void dma2dFgSetAddressI(DMA2DDriver *dma2dp, void *bufferp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgCheck(dma2dIsAligned(bufferp, dma2dFgGetPixelFormatI(dma2dp))); + (void)dma2dp; + + DMA2D->FGMAR = (uint32_t)bufferp; +} + +/** + * @brief Set foreground layer buffer address. + * @details Sets the buffer address of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] bufferp buffer address + * + * @api + */ +void dma2dFgSetAddress(DMA2DDriver *dma2dp, void *bufferp) { + + chSysLock(); + dma2dFgSetAddressI(dma2dp, bufferp); + chSysUnlock(); +} + +/** + * @brief Get foreground layer wrap offset. + * @details Gets the buffer line wrap offset of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return wrap offset, in pixels + * + * @iclass + */ +size_t dma2dFgGetWrapOffsetI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (size_t)(DMA2D->FGOR & DMA2D_FGOR_LO); +} + +/** + * @brief Get foreground layer wrap offset. + * @details Gets the buffer line wrap offset of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return wrap offset, in pixels + * + * @api + */ +size_t dma2dFgGetWrapOffset(DMA2DDriver *dma2dp) { + + size_t offset; + chSysLock(); + offset = dma2dFgGetWrapOffsetI(dma2dp); + chSysUnlock(); + return offset; +} + +/** + * @brief Set foreground layer wrap offset. + * @details Sets the buffer line wrap offset of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] offset wrap offset, in pixels + * + * @iclass + */ +void dma2dFgSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert(offset <= DMA2D_MAX_OFFSET, "bounds"); + (void)dma2dp; + + DMA2D->FGOR = (DMA2D->FGOR & ~DMA2D_FGOR_LO) | + ((uint32_t)offset & DMA2D_FGOR_LO); +} + +/** + * @brief Set foreground layer wrap offset. + * @details Sets the buffer line wrap offset of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] offset wrap offset, in pixels + * + * @api + */ +void dma2dFgSetWrapOffset(DMA2DDriver *dma2dp, size_t offset) { + + chSysLock(); + dma2dFgSetWrapOffsetI(dma2dp, offset); + chSysUnlock(); +} + +/** + * @brief Get foreground layer constant alpha. + * @details Gets the constant alpha component of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return constant alpha component, A-8 + * + * @iclass + */ +uint8_t dma2dFgGetConstantAlphaI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (uint8_t)((DMA2D->FGPFCCR & DMA2D_FGPFCCR_ALPHA) >> 24); +} + +/** + * @brief Get foreground layer constant alpha. + * @details Gets the constant alpha component of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return constant alpha component, A-8 + * + * @api + */ +uint8_t dma2dFgGetConstantAlpha(DMA2DDriver *dma2dp) { + + uint8_t a; + chSysLock(); + a = dma2dFgGetConstantAlphaI(dma2dp); + chSysUnlock(); + return a; +} + +/** + * @brief Set foreground layer constant alpha. + * @details Sets the constant alpha component of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] a constant alpha component, A-8 + * + * @iclass + */ +void dma2dFgSetConstantAlphaI(DMA2DDriver *dma2dp, uint8_t a) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + (void)dma2dp; + + DMA2D->FGPFCCR = (DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_ALPHA) | + (((uint32_t)a << 24) & DMA2D_FGPFCCR_ALPHA); +} + +/** + * @brief Set foreground layer constant alpha. + * @details Sets the constant alpha component of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] a constant alpha component, A-8 + * + * @api + */ +void dma2dFgSetConstantAlpha(DMA2DDriver *dma2dp, uint8_t a) { + + chSysLock(); + dma2dFgSetConstantAlphaI(dma2dp, a); + chSysUnlock(); +} + +/** + * @brief Get foreground layer alpha mode. + * @details Gets the alpha mode of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return alpha mode + * + * @iclass + */ +dma2d_amode_t dma2dFgGetAlphaModeI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_amode_t)(DMA2D->FGPFCCR & DMA2D_FGPFCCR_AM); +} + +/** + * @brief Get foreground layer alpha mode. + * @details Gets the alpha mode of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return alpha mode + * + * @api + */ +dma2d_amode_t dma2dFgGetAlphaMode(DMA2DDriver *dma2dp) { + + dma2d_amode_t mode; + chSysLock(); + mode = dma2dFgGetAlphaModeI(dma2dp); + chSysUnlock(); + return mode; +} + +/** + * @brief Set foreground layer alpha mode. + * @details Sets the alpha mode of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] mode alpha mode + * + * @iclass + */ +void dma2dFgSetAlphaModeI(DMA2DDriver *dma2dp, dma2d_amode_t mode) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert((mode & ~DMA2D_FGPFCCR_AM) == 0, "bounds"); + osalDbgAssert((mode & DMA2D_FGPFCCR_AM) != DMA2D_FGPFCCR_AM, "bounds"); + (void)dma2dp; + + DMA2D->FGPFCCR = (DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_AM) | + ((uint32_t)mode & DMA2D_FGPFCCR_AM); +} + +/** + * @brief Set foreground layer alpha mode. + * @details Sets the alpha mode of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] mode alpha mode + * + * @api + */ +void dma2dFgSetAlphaMode(DMA2DDriver *dma2dp, dma2d_amode_t mode) { + + chSysLock(); + dma2dFgSetAlphaModeI(dma2dp, mode); + chSysUnlock(); +} + +/** + * @brief Get foreground layer pixel format. + * @details Gets the pixel format of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return pixel format + * + * @iclass + */ +dma2d_pixfmt_t dma2dFgGetPixelFormatI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_pixfmt_t)(DMA2D->FGPFCCR & DMA2D_FGPFCCR_CM); +} + +/** + * @brief Get foreground layer pixel format. + * @details Gets the pixel format of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return pixel format + * + * @api + */ +dma2d_pixfmt_t dma2dFgGetPixelFormat(DMA2DDriver *dma2dp) { + + dma2d_pixfmt_t fmt; + chSysLock(); + fmt = dma2dFgGetPixelFormatI(dma2dp); + chSysUnlock(); + return fmt; +} + +/** + * @brief Set foreground layer pixel format. + * @details Sets the pixel format of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] fmt pixel format + * + * @iclass + */ +void dma2dFgSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert(fmt <= DMA2D_MAX_PIXFMT_ID, "bounds"); + (void)dma2dp; + + DMA2D->FGPFCCR = (DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_CM) | + ((uint32_t)fmt & DMA2D_FGPFCCR_CM); +} + +/** + * @brief Set foreground layer pixel format. + * @details Sets the pixel format of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] fmt pixel format + * + * @api + */ +void dma2dFgSetPixelFormat(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { + + chSysLock(); + dma2dFgSetPixelFormatI(dma2dp, fmt); + chSysUnlock(); +} + +/** + * @brief Get foreground layer default color. + * @details Gets the default color of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return default color, RGB-888 + * + * @iclass + */ +dma2d_color_t dma2dFgGetDefaultColorI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_color_t)(DMA2D->FGCOLR & 0x00FFFFFF); +} + +/** + * @brief Get foreground layer default color. + * @details Gets the default color of the foreground layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return default color, RGB-888 + * + * @api + */ +dma2d_color_t dma2dFgGetDefaultColor(DMA2DDriver *dma2dp) { + + dma2d_color_t c; + chSysLock(); + c = dma2dFgGetDefaultColorI(dma2dp); + chSysUnlock(); + return c; +} + +/** + * @brief Set foreground layer default color. + * @details Sets the default color of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] c default color, RGB-888 + * + * @iclass + */ +void dma2dFgSetDefaultColorI(DMA2DDriver *dma2dp, dma2d_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + (void)dma2dp; + + DMA2D->FGCOLR = (uint32_t)c & 0x00FFFFFF; +} + +/** + * @brief Set foreground layer default color. + * @details Sets the default color of the foreground layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] c default color, RGB-888 + * + * @api + */ +void dma2dFgSetDefaultColor(DMA2DDriver *dma2dp, dma2d_color_t c) { + + chSysLock(); + dma2dFgSetDefaultColorI(dma2dp, c); + chSysUnlock(); +} + +/** + * @brief Get foreground layer palette specifications. + * @details Gets the palette specifications of the foreground layer. + * @note The palette colors pointer is actually addressed to a @p volatile + * memory zone. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] palettep pointer to the palette specifications + * + * @iclass + */ +void dma2dFgGetPaletteI(DMA2DDriver *dma2dp, dma2d_palcfg_t *palettep) { + + uint32_t r; + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck(palettep != NULL); + (void)dma2dp; + + r = DMA2D->FGPFCCR; + palettep->colorsp = (const void *)DMA2D->FGCLUT; + palettep->length = (uint16_t)((r & DMA2D_FGPFCCR_CS) >> 8) + 1; + palettep->fmt = (dma2d_pixfmt_t)((r & DMA2D_FGPFCCR_CCM) >> 4); +} + +/** + * @brief Get foreground layer palette specifications. + * @details Gets the palette specifications of the foreground layer. + * @note The palette colors pointer is actually addressed to a @p volatile + * memory zone. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] palettep pointer to the palette specifications + * + * @api + */ +void dma2dFgGetPalette(DMA2DDriver *dma2dp, dma2d_palcfg_t *palettep) { + + chSysLock(); + dma2dFgGetPaletteI(dma2dp, palettep); + chSysUnlock(); +} + +/** + * @brief Set foreground layer palette specifications. + * @details Sets the palette specifications of the foreground layer. + * @note This function should not be called while the DMA2D is already + * executing a job, otherwise the appropriate error interrupt might be + * invoked. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] palettep pointer to the palette specifications + * + * @sclass + */ +void dma2dFgSetPaletteS(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep) { + + osalDbgCheckClassS(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgCheck(palettep != NULL); + osalDbgCheck(palettep->colorsp != NULL); + osalDbgAssert(palettep->length > 0, "bounds"); + osalDbgAssert(palettep->length <= DMA2D_MAX_PALETTE_LENGTH, "bounds"); + osalDbgAssert(((palettep->fmt == DMA2D_FMT_ARGB8888) || + (palettep->fmt == DMA2D_FMT_RGB888)), "invalid format"); + + DMA2D->FGCMAR = (uint32_t)palettep->colorsp; + DMA2D->FGPFCCR = (DMA2D->FGPFCCR & ~(DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM)) | + ((((uint32_t)palettep->length - 1) << 8) & DMA2D_FGPFCCR_CS) + | ((uint32_t)palettep->fmt << 4); + + dma2dp->state = DMA2D_ACTIVE; + DMA2D->FGPFCCR |= DMA2D_FGPFCCR_START; + +#if DMA2D_USE_WAIT + dma2dp->thread = chThdGetSelfX(); + chSchGoSleepS(CH_STATE_SUSPENDED); +#else + while (DMA2D->FGPFCCR & DMA2D_FGPFCCR_START) + chSchDoYieldS(); +#endif /* DMA2D_USE_WAIT */ +} + +/** + * @brief Set foreground layer palette specifications. + * @details Sets the palette specifications of the foreground layer. + * @note This function should not be called while the DMA2D is already + * executing a job, otherwise the appropriate error interrupt might be + * invoked. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] palettep pointer to the palette specifications + * + * @api + */ +void dma2dFgSetPalette(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep) { + + chSysLock(); + dma2dFgSetPaletteS(dma2dp, palettep); + chSysUnlock(); +} + +/** + * @brief Get foreground layer specifications. + * @details Gets the foreground layer specifications at once. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @iclass + */ +void dma2dFgGetLayerI(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck(cfgp != NULL); + + cfgp->bufferp = dma2dFgGetAddressI(dma2dp); + cfgp->wrap_offset = dma2dFgGetWrapOffsetI(dma2dp); + cfgp->fmt = dma2dFgGetPixelFormatI(dma2dp); + cfgp->def_color = dma2dFgGetDefaultColorI(dma2dp); + cfgp->const_alpha = dma2dFgGetConstantAlphaI(dma2dp); + if (cfgp->palettep != NULL) + dma2dFgGetPaletteI(dma2dp, (dma2d_palcfg_t *)cfgp->palettep); +} + +/** + * @brief Get foreground layer specifications. + * @details Gets the foreground layer specifications at once. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @api + */ +void dma2dFgGetLayer(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp) { + + chSysLock(); + dma2dFgGetLayerI(dma2dp, cfgp); + chSysUnlock(); +} + +/** + * @brief Set foreground layer specifications. + * @details Sets the foreground layer specifications at once. + * @note If the palette is unspecified, the layer palette is unmodified. + * @note This function should not be called while the DMA2D is already + * executing a job, otherwise the appropriate error interrupt might be + * invoked. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @sclass + */ +void dma2dFgSetConfigS(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp) { + + osalDbgCheckClassS(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgCheck(cfgp != NULL); + + dma2dFgSetAddressI(dma2dp, cfgp->bufferp); + dma2dFgSetWrapOffsetI(dma2dp, cfgp->wrap_offset); + dma2dFgSetPixelFormatI(dma2dp, cfgp->fmt); + dma2dFgSetDefaultColorI(dma2dp, cfgp->def_color); + dma2dFgSetConstantAlphaI(dma2dp, cfgp->const_alpha); + if (cfgp->palettep != NULL) + dma2dFgSetPaletteS(dma2dp, cfgp->palettep); +} + +/** + * @brief Set foreground layer specifications. + * @details Sets the foreground layer specifications at once. + * @note If the palette is unspecified, the layer palette is unmodified. + * @note This function should not be called while the DMA2D is already + * executing a job, otherwise the appropriate error interrupt might be + * invoked. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @api + */ +void dma2dFgSetConfig(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp) { + + chSysLock(); + dma2dFgSetConfigS(dma2dp, cfgp); + chSysUnlock(); +} + +/** @} */ + +/** + * @name DMA2D output layer methods + * @{ + */ + +/** + * @brief Get output layer buffer address. + * @details Gets the buffer address of the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return buffer address + * + * @iclass + */ +void *dma2dOutGetAddressI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (void *)DMA2D->OMAR; +} + +/** + * @brief Get output layer buffer address. + * @details Gets the buffer address of the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return buffer address + * + * @api + */ +void *dma2dOutGetAddress(DMA2DDriver *dma2dp) { + + void *bufferp; + chSysLock(); + bufferp = dma2dOutGetAddressI(dma2dp); + chSysUnlock(); + return bufferp; +} + +/** + * @brief Set output layer buffer address. + * @details Sets the buffer address of the output layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] bufferp buffer address + * + * @iclass + */ +void dma2dOutSetAddressI(DMA2DDriver *dma2dp, void *bufferp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgCheck(dma2dIsAligned(bufferp, dma2dOutGetPixelFormatI(dma2dp))); + (void)dma2dp; + + DMA2D->OMAR = (uint32_t)bufferp; +} + +/** + * @brief Set output layer buffer address. + * @details Sets the buffer address of the output layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] bufferp buffer address + * + * @api + */ +void dma2dOutSetAddress(DMA2DDriver *dma2dp, void *bufferp) { + + chSysLock(); + dma2dOutSetAddressI(dma2dp, bufferp); + chSysUnlock(); +} + +/** + * @brief Get output layer wrap offset. + * @details Gets the buffer line wrap offset of the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return wrap offset, in pixels + * + * @iclass + */ +size_t dma2dOutGetWrapOffsetI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (size_t)(DMA2D->OOR & DMA2D_OOR_LO); +} + +/** + * @brief Get output layer wrap offset. + * @details Gets the buffer line wrap offset of the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return wrap offset, in pixels + * + * @api + */ +size_t dma2dOutGetWrapOffset(DMA2DDriver *dma2dp) { + + size_t offset; + chSysLock(); + offset = dma2dOutGetWrapOffsetI(dma2dp); + chSysUnlock(); + return offset; +} + +/** + * @brief Set output layer wrap offset. + * @details Sets the buffer line wrap offset of the output layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] offset wrap offset, in pixels + * + * @iclass + */ +void dma2dOutSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert(offset <= DMA2D_MAX_OFFSET, "bounds"); + (void)dma2dp; + + DMA2D->OOR = (DMA2D->OOR & ~DMA2D_OOR_LO) | + ((uint32_t)offset & DMA2D_OOR_LO); +} + +/** + * @brief Set output layer wrap offset. + * @details Sets the buffer line wrap offset of the output layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] offset wrap offset, in pixels + * + * @api + */ +void dma2dOutSetWrapOffset(DMA2DDriver *dma2dp, size_t offset) { + + chSysLock(); + dma2dOutSetWrapOffsetI(dma2dp, offset); + chSysUnlock(); +} + +/** + * @brief Get output layer pixel format. + * @details Gets the pixel format of the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return pixel format + * + * @iclass + */ +dma2d_pixfmt_t dma2dOutGetPixelFormatI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_pixfmt_t)(DMA2D->OPFCCR & DMA2D_OPFCCR_CM); +} + +/** + * @brief Get output layer pixel format. + * @details Gets the pixel format of the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return pixel format + * + * @api + */ +dma2d_pixfmt_t dma2dOutGetPixelFormat(DMA2DDriver *dma2dp) { + + dma2d_pixfmt_t fmt; + chSysLock(); + fmt = dma2dOutGetPixelFormatI(dma2dp); + chSysUnlock(); + return fmt; +} + +/** + * @brief Set output layer pixel format. + * @details Sets the pixel format of the output layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] fmt pixel format + * + * @iclass + */ +void dma2dOutSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgAssert(fmt <= DMA2D_MAX_OUTPIXFMT_ID, "bounds"); + (void)dma2dp; + + DMA2D->OPFCCR = (DMA2D->OPFCCR & ~DMA2D_OPFCCR_CM) | + ((uint32_t)fmt & DMA2D_OPFCCR_CM); +} + +/** + * @brief Set output layer pixel format. + * @details Sets the pixel format of the output layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] fmt pixel format + * + * @api + */ +void dma2dOutSetPixelFormat(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { + + chSysLock(); + dma2dOutSetPixelFormatI(dma2dp, fmt); + chSysUnlock(); +} + +/** + * @brief Get output layer default color. + * @details Gets the default color of the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return default color, chosen output format + * + * @iclass + */ +dma2d_color_t dma2dOutGetDefaultColorI(DMA2DDriver *dma2dp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + (void)dma2dp; + + return (dma2d_color_t)(DMA2D->OCOLR & 0x00FFFFFF); +} + +/** + * @brief Get output layer default color. + * @details Gets the default color of the output layer. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * + * @return default color, chosen output format + * + * @api + */ +dma2d_color_t dma2dOutGetDefaultColor(DMA2DDriver *dma2dp) { + + dma2d_color_t c; + chSysLock(); + c = dma2dOutGetDefaultColorI(dma2dp); + chSysUnlock(); + return c; +} + +/** + * @brief Set output layer default color. + * @details Sets the default color of the output layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] c default color, chosen output format + * + * @iclass + */ +void dma2dOutSetDefaultColorI(DMA2DDriver *dma2dp, dma2d_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + (void)dma2dp; + + DMA2D->OCOLR = (uint32_t)c & 0x00FFFFFF; +} + +/** + * @brief Set output layer default color. + * @details Sets the default color of the output layer. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] c default color, chosen output format + * + * @api + */ +void dma2dOutSetDefaultColor(DMA2DDriver *dma2dp, dma2d_color_t c) { + + chSysLock(); + dma2dOutSetDefaultColorI(dma2dp, c); + chSysUnlock(); +} + +/** + * @brief Get output layer specifications. + * @details Gets the output layer specifications at once. + * @note Constant alpha and palette specifications are ignored. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @iclass + */ +void dma2dOutGetLayerI(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgCheck(cfgp != NULL); + + cfgp->bufferp = dma2dOutGetAddressI(dma2dp); + cfgp->wrap_offset = dma2dOutGetWrapOffsetI(dma2dp); + cfgp->fmt = dma2dOutGetPixelFormatI(dma2dp); + cfgp->def_color = dma2dOutGetDefaultColorI(dma2dp); +} + +/** + * @brief Get output layer specifications. + * @details Gets the output layer specifications at once. + * @note Constant alpha and palette specifications are ignored. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @api + */ +void dma2dOutGetLayer(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp) { + + chSysLock(); + dma2dOutGetLayerI(dma2dp, cfgp); + chSysUnlock(); +} + +/** + * @brief Set output layer specifications. + * @details Sets the output layer specifications at once. + * @note Constant alpha and palette specifications are ignored. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @iclass + */ +void dma2dOutSetConfigI(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp) { + + osalDbgCheckClassI(); + osalDbgCheck(dma2dp == &DMA2DD1); + osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); + osalDbgCheck(cfgp != NULL); + + dma2dOutSetAddressI(dma2dp, cfgp->bufferp); + dma2dOutSetWrapOffsetI(dma2dp, cfgp->wrap_offset); + dma2dOutSetPixelFormatI(dma2dp, cfgp->fmt); + dma2dOutSetDefaultColorI(dma2dp, cfgp->def_color); +} + +/** + * @brief Set output layer specifications. + * @details Sets the output layer specifications at once. + * @note Constant alpha and palette specifications are ignored. + * @pre DMA2D is ready. + * + * @param[in] dma2dp pointer to the @p DMA2DDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @api + */ +void dma2dOutSetConfig(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp) { + + chSysLock(); + dma2dOutSetConfigI(dma2dp, cfgp); + chSysUnlock(); +} + +/** @} */ + +/** + * @name DMA2D helper functions + * @{ + */ + +/** + * @brief Compute pixel address. + * @details Computes the buffer address of a pixel, given the buffer + * specifications. + * + * @param[in] originp buffer origin address + * @param[in] pitch buffer pitch, in bytes + * @param[in] fmt buffer pixel format + * @param[in] x horizontal pixel coordinate + * @param[in] y vertical pixel coordinate + * + * @return pixel address, constant data + * + * @api + */ +const void *dma2dComputeAddressConst(const void *originp, size_t pitch, + dma2d_pixfmt_t fmt, + uint16_t x, uint16_t y) { + + osalDbgCheck(pitch > 0); + + switch (fmt) { + case DMA2D_FMT_ARGB8888: + return (const void *)((uintptr_t)originp + + (uintptr_t)y * pitch + (uintptr_t)x * 4); + case DMA2D_FMT_RGB888: + return (const void *)((uintptr_t)originp + + (uintptr_t)y * pitch + (uintptr_t)x * 3); + case DMA2D_FMT_RGB565: + case DMA2D_FMT_ARGB1555: + case DMA2D_FMT_ARGB4444: + case DMA2D_FMT_AL88: + return (const void *)((uintptr_t)originp + + (uintptr_t)y * pitch + (uintptr_t)x * 2); + case DMA2D_FMT_L8: + case DMA2D_FMT_AL44: + case DMA2D_FMT_A8: + return (const void *)((uintptr_t)originp + + (uintptr_t)y * pitch + (uintptr_t)x); + case DMA2D_FMT_L4: + case DMA2D_FMT_A4: + osalDbgAssert((x & 1) == 0, "not aligned"); + return (const void *)((uintptr_t)originp + + (uintptr_t)y * pitch + (uintptr_t)x / 2); + default: + osalDbgAssert(false, "invalid format"); + return NULL; + } +} + +/** + * @brief Address is aligned. + * @details Tells whether the address is aligned with the provided pixel format. + * + * @param[in] bufferp address + * @param[in] fmt pixel format + * + * @return address is aligned + * + * @api + */ +bool dma2dIsAligned(const void *bufferp, dma2d_pixfmt_t fmt) { + + switch (fmt) { + case DMA2D_FMT_ARGB8888: + case DMA2D_FMT_RGB888: + return ((uintptr_t)bufferp & 3) == 0; /* 32-bit alignment.*/ + case DMA2D_FMT_RGB565: + case DMA2D_FMT_ARGB1555: + case DMA2D_FMT_ARGB4444: + case DMA2D_FMT_AL88: + return ((uintptr_t)bufferp & 1) == 0; /* 16-bit alignment.*/ + case DMA2D_FMT_L8: + case DMA2D_FMT_AL44: + case DMA2D_FMT_L4: + case DMA2D_FMT_A8: + case DMA2D_FMT_A4: + return true; /* 8-bit alignment.*/ + default: + osalDbgAssert(false, "invalid format"); + return false; + } +} + +/** + * @brief Compute bits per pixel. + * @details Computes the bits per pixel for the specified pixel format. + * + * @param[in] fmt pixel format + * + * @retuen bits per pixel + * + * @api + */ +size_t dma2dBitsPerPixel(dma2d_pixfmt_t fmt) { + + osalDbgAssert(fmt < DMA2D_MAX_PIXFMT_ID, "invalid format"); + + return (size_t)dma2d_bpp[(unsigned)fmt]; +} + +#if DMA2D_USE_SOFTWARE_CONVERSIONS || defined(__DOXYGEN__) + +/** + * @brief Convert from ARGB-8888. + * @details Converts an ARGB-8888 color to the specified pixel format. + * + * @param[in] c color, ARGB-8888 + * @param[in] fmt target pixel format + * + * @return raw color value for the target pixel format, left + * padded with zeros. + * + * @api + */ +dma2d_color_t dma2dFromARGB8888(dma2d_color_t c, dma2d_pixfmt_t fmt) { + + switch (fmt) { + case DMA2D_FMT_ARGB8888: { + return c; + } + case DMA2D_FMT_RGB888: { + return c & 0x00FFFFFF; + } + case DMA2D_FMT_RGB565: { + return ((c & 0x000000F8) >> ( 8 - 5)) | + ((c & 0x0000FC00) >> (16 - 11)) | + ((c & 0x00F80000) >> (24 - 16)); + } + case DMA2D_FMT_ARGB1555: { + return ((c & 0x000000F8) >> ( 8 - 5)) | + ((c & 0x0000F800) >> (16 - 10)) | + ((c & 0x00F80000) >> (24 - 15)) | + ((c & 0x80000000) >> (32 - 16)); + } + case DMA2D_FMT_ARGB4444: { + return ((c & 0x000000F0) >> ( 8 - 4)) | + ((c & 0x0000F000) >> (16 - 8)) | + ((c & 0x00F00000) >> (24 - 12)) | + ((c & 0xF0000000) >> (32 - 16)); + } + case DMA2D_FMT_L8: { + return c & 0x000000FF; + } + case DMA2D_FMT_AL44: { + return ((c & 0x000000F0) >> ( 8 - 4)) | + ((c & 0xF0000000) >> (32 - 8)); + } + case DMA2D_FMT_AL88: { + return ((c & 0x000000FF) >> ( 8 - 8)) | + ((c & 0xFF000000) >> (32 - 16)); + } + case DMA2D_FMT_L4: { + return c & 0x0000000F; + } + case DMA2D_FMT_A8: { + return (c & 0xFF000000) >> (32 - 8); + } + case DMA2D_FMT_A4: { + return (c & 0xF0000000) >> (32 - 4); + } + default: + osalDbgAssert(false, "invalid format"); + return 0; + } +} + +/** + * @brief Convert to ARGB-8888. + * @details Converts color of the specified pixel format to an ARGB-8888 color. + * + * @param[in] c color for the source pixel format, left padded with + * zeros. + * @param[in] fmt source pixel format + * + * @return color in ARGB-8888 format + * + * @api + */ +dma2d_color_t dma2dToARGB8888(dma2d_color_t c, dma2d_pixfmt_t fmt) { + + switch (fmt) { + case DMA2D_FMT_ARGB8888: { + return c; + } + case DMA2D_FMT_RGB888: { + return (c & 0x00FFFFFF) | 0xFF000000; + } + case DMA2D_FMT_RGB565: { + register dma2d_color_t output = 0xFF000000; + if (c & 0x001F) output |= ((c & 0x001F) << ( 8 - 5)) | 0x00000007; + if (c & 0x07E0) output |= ((c & 0x07E0) << (16 - 11)) | 0x00000300; + if (c & 0xF800) output |= ((c & 0xF800) << (24 - 16)) | 0x00070000; + return output; + } + case DMA2D_FMT_ARGB1555: { + register dma2d_color_t output = 0x00000000; + if (c & 0x001F) output |= ((c & 0x001F) << ( 8 - 5)) | 0x00000007; + if (c & 0x03E0) output |= ((c & 0x03E0) << (16 - 10)) | 0x00000700; + if (c & 0x7C00) output |= ((c & 0x7C00) << (24 - 15)) | 0x00070000; + if (c & 0x8000) output |= 0xFF000000; + return output; + } + case DMA2D_FMT_ARGB4444: { + register dma2d_color_t output = 0x00000000; + if (c & 0x000F) output |= ((c & 0x000F) << ( 8 - 4)) | 0x0000000F; + if (c & 0x00F0) output |= ((c & 0x00F0) << (16 - 8)) | 0x00000F00; + if (c & 0x0F00) output |= ((c & 0x0F00) << (24 - 12)) | 0x000F0000; + if (c & 0xF000) output |= ((c & 0xF000) << (32 - 16)) | 0x0F000000; + return output; + } + case DMA2D_FMT_L8: { + return (c & 0xFF) | 0xFF000000; + } + case DMA2D_FMT_AL44: { + register dma2d_color_t output = 0x00000000; + if (c & 0x0F) output |= ((c & 0x0F) << ( 8 - 4)) | 0x0000000F; + if (c & 0xF0) output |= ((c & 0xF0) << (32 - 8)) | 0x0F000000; + return output; + } + case DMA2D_FMT_AL88: { + return ((c & 0x00FF) << ( 8 - 8)) | + ((c & 0xFF00) << (32 - 16)); + } + case DMA2D_FMT_L4: { + return (c & 0x0F) | 0xFF000000; + } + case DMA2D_FMT_A8: { + return (c & 0xFF) << (32 - 8); + } + case DMA2D_FMT_A4: { + return (c & 0x0F) << (32 - 4); + } + default: + osalDbgAssert(false, "invalid format"); + return 0; + } +} + +#endif /* DMA2D_NEED_CONVERSIONS */ + +/** @} */ + +/** @} */ + +#endif /* STM32_DMA2D_USE_DMA2D */ diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h new file mode 100644 index 0000000..c118be2 --- /dev/null +++ b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h @@ -0,0 +1,690 @@ +/* + Copyright (C) 2013-2015 Andrea Zoppi + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file stm32_dma2d.h + * @brief DMA2D/Chrom-ART driver. + * + * @addtogroup dma2d + * @{ + */ + +#ifndef _STM32_DMA2D_H_ +#define _STM32_DMA2D_H_ + +/** + * @brief Using the DMA2D driver. + */ +#if !defined(STM32_DMA2D_USE_DMA2D) || defined(__DOXYGEN__) +#define STM32_DMA2D_USE_DMA2D FALSE +#endif + +#if (TRUE == STM32_DMA2D_USE_DMA2D) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name DMA2D job modes + * @{ + */ +#define DMA2D_JOB_COPY (0 << 16) /**< Copy, replace(FG only).*/ +#define DMA2D_JOB_CONVERT (1 << 16) /**< Copy, convert (FG + PFC).*/ +#define DMA2D_JOB_BLEND (2 << 16) /**< Copy, blend (FG + BG + PFC).*/ +#define DMA2D_JOB_CONST (3 << 16) /**< Default color only (FG REG).*/ +/** @} */ + +/** + * @name DMA2D enable flag + * @{ + */ +#define DMA2D_EF_ENABLE (1 << 0) /**< DMA2D enabled.*/ +#define DMA2D_EF_DITHER (1 << 16) /**< Dithering enabled.*/ +#define DMA2D_EF_PIXCLK_INVERT (1 << 28) /**< Inverted pixel clock.*/ +#define DMA2D_EF_DATAEN_HIGH (1 << 29) /**< Active-high data enable.*/ +#define DMA2D_EF_VSYNC_HIGH (1 << 30) /**< Active-high vsync.*/ +#define DMA2D_EF_HSYNC_HIGH (1 << 31) /**< Active-high hsync.*/ + +/** Enable flags mask. */ +#define DMA2D_EF_MASK \ + (DMA2D_EF_ENABLE | DMA2D_EF_DITHER | DMA2D_EF_PIXCLK_INVERT | \ + DMA2D_EF_DATAEN_HIGH | DMA2D_EF_VSYNC_HIGH | DMA2D_EF_HSYNC_HIGH) +/** @} */ + +/** + * @name DMA2D layer enable flags + * @{ + */ +#define DMA2D_LEF_ENABLE (1 << 0) /**< Layer enabled*/ +#define DMA2D_LEF_KEYING (1 << 1) /**< Color keying enabled.*/ +#define DMA2D_LEF_PALETTE (1 << 4) /**< Palette enabled.*/ + +/** Layer enable flag masks. */ +#define DMA2D_LEF_MASK \ + (DMA2D_LEF_ENABLE | DMA2D_LEF_KEYING | DMA2D_LEF_PALETTE) +/** @} */ + +/** + * @name DMA2D pixel formats + * @{ + */ +#define DMA2D_FMT_ARGB8888 (0) /**< ARGB-8888 format.*/ +#define DMA2D_FMT_RGB888 (1) /**< RGB-888 format.*/ +#define DMA2D_FMT_RGB565 (2) /**< RGB-565 format.*/ +#define DMA2D_FMT_ARGB1555 (3) /**< ARGB-1555 format.*/ +#define DMA2D_FMT_ARGB4444 (4) /**< ARGB-4444 format.*/ +#define DMA2D_FMT_L8 (5) /**< L-8 format.*/ +#define DMA2D_FMT_AL44 (6) /**< AL-44 format.*/ +#define DMA2D_FMT_AL88 (7) /**< AL-88 format.*/ +#define DMA2D_FMT_L4 (8) /**< L-4 format.*/ +#define DMA2D_FMT_A8 (9) /**< A-8 format.*/ +#define DMA2D_FMT_A4 (10) /**< A-4 format.*/ +/** @} */ + +/** + * @name DMA2D pixel format aliased raw masks + * @{ + */ +#define DMA2D_XMASK_ARGB8888 (0xFFFFFFFF) /**< ARGB-8888 aliased mask.*/ +#define DMA2D_XMASK_RGB888 (0x00FFFFFF) /**< RGB-888 aliased mask.*/ +#define DMA2D_XMASK_RGB565 (0x00F8FCF8) /**< RGB-565 aliased mask.*/ +#define DMA2D_XMASK_ARGB1555 (0x80F8F8F8) /**< ARGB-1555 aliased mask.*/ +#define DMA2D_XMASK_ARGB4444 (0xF0F0F0F0) /**< ARGB-4444 aliased mask.*/ +#define DMA2D_XMASK_L8 (0x000000FF) /**< L-8 aliased mask.*/ +#define DMA2D_XMASK_AL44 (0xF00000F0) /**< AL-44 aliased mask.*/ +#define DMA2D_XMASK_AL88 (0xFF0000FF) /**< AL-88 aliased mask.*/ +#define DMA2D_XMASK_L4 (0x0000000F) /**< L-4 aliased mask.*/ +#define DMA2D_XMASK_A8 (0xFF000000) /**< A-8 aliased mask.*/ +#define DMA2D_XMASK_A4 (0xF0000000) /**< A-4 aliased mask.*/ +/** @} */ + +/** + * @name DMA2D alpha modes + * @{ + */ +#define DMA2D_ALPHA_KEEP (0x00000000) /**< Original alpha channel.*/ +#define DMA2D_ALPHA_REPLACE (0x00010000) /**< Replace with constant.*/ +#define DMA2D_ALPHA_MODULATE (0x00020000) /**< Modulate with constant.*/ +/** @} */ + +/** + * @name DMA2D parameter bounds + * @{ + */ + +#define DMA2D_MIN_PIXFMT_ID (0) /**< Minimum pixel format ID.*/ +#define DMA2D_MAX_PIXFMT_ID (11) /**< Maximum pixel format ID.*/ +#define DMA2D_MIN_OUTPIXFMT_ID (0) /**< Minimum output pixel format ID.*/ +#define DMA2D_MAX_OUTPIXFMT_ID (4) /**< Maximum output pixel format ID.*/ + +#define DMA2D_MAX_OFFSET ((1 << 14) - 1) + +#define DMA2D_MAX_PALETTE_LENGTH (256) /***/ + +#define DMA2D_MAX_WIDTH ((1 << 14) - 1) +#define DMA2D_MAX_HEIGHT ((1 << 16) - 1) + +#define DMA2D_MAX_WATERMARK_POS ((1 << 16) - 1) + +#define DMA2D_MAX_DEADTIME_CYCLES ((1 << 8) - 1) + +/** @} */ + +/** + * @name DMA2D basic ARGB-8888 colors. + * @{ + */ +/* Microsoft Windows default 16-color palette.*/ +#define DMA2D_COLOR_BLACK (0xFF000000) +#define DMA2D_COLOR_MAROON (0xFF800000) +#define DMA2D_COLOR_GREEN (0xFF008000) +#define DMA2D_COLOR_OLIVE (0xFF808000) +#define DMA2D_COLOR_NAVY (0xFF000080) +#define DMA2D_COLOR_PURPLE (0xFF800080) +#define DMA2D_COLOR_TEAL (0xFF008080) +#define DMA2D_COLOR_SILVER (0xFFC0C0C0) +#define DMA2D_COLOR_GRAY (0xFF808080) +#define DMA2D_COLOR_RED (0xFFFF0000) +#define DMA2D_COLOR_LIME (0xFF00FF00) +#define DMA2D_COLOR_YELLOW (0xFFFFFF00) +#define DMA2D_COLOR_BLUE (0xFF0000FF) +#define DMA2D_COLOR_FUCHSIA (0xFFFF00FF) +#define DMA2D_COLOR_AQUA (0xFF00FFFF) +#define DMA2D_COLOR_WHITE (0xFFFFFFFF) +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/* + * These definitions should already be defined by stm32_isr.h + */ +#if !defined(STM32_DMA2D_NUMBER) && !defined(__DOXYGEN__) +#define STM32_DMA2D_NUMBER (DMA2D_IRQn) +#endif + +/* + * These definitions should already be defined by hal_lld.h + */ +#if !defined(DMA2D_IRQHandler) && !defined(__DOXYGEN__) +#define DMA2D_IRQHandler Vector1A8 +#endif + +#if !defined(STM32_HAS_DMA2D) && !defined(__DOXYGEN__) +#ifdef STM32F429_439xx +#define STM32_HAS_DMA2D (TRUE) +#else +#define STM32_HAS_DMA2D (FALSE) +#endif +#endif + +/** + * @name DMA2D configuration options + * @{ + */ + +/** + * @brief DMA2D event interrupt priority level setting. + */ +#if !defined(STM32_DMA2D_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_DMA2D_IRQ_PRIORITY (11) +#endif + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DMA2D_USE_WAIT) || defined(__DOXYGEN__) +#define DMA2D_USE_WAIT (TRUE) +#endif + +/** + * @brief Enables the @p dma2dAcquireBus() and @p dma2dReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DMA2D_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define DMA2D_USE_MUTUAL_EXCLUSION (TRUE) +#endif + +/** + * @brief Provides software color conversion functions. + * @note Disabling this option saves both code and data space. + */ +#if !defined(DMA2D_USE_SOFTWARE_CONVERSIONS) || defined(__DOXYGEN__) +#define DMA2D_USE_SOFTWARE_CONVERSIONS (TRUE) +#endif + +/** + * @brief Enables checks for DMA2D functions. + * @note Disabling this option saves both code and data space. + * @note Disabling checks by ChibiOS will automatically disable DMA2D checks. + */ +#if !defined(DMA2D_USE_CHECKS) || defined(__DOXYGEN__) +#define DMA2D_USE_CHECKS (TRUE) +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#ifndef STM32F429_439xx +#error "Currently only STM32F429xx and STM32F439xx are supported" +#endif + +#if (TRUE != STM32_HAS_DMA2D) +#error "DMA2D must be present when using the DMA2D subsystem" +#endif + +#if (TRUE != STM32_DMA2D_USE_DMA2D) && (TRUE != STM32_HAS_DMA2D) +#error "DMA2D not present in the selected device" +#endif + +#if (TRUE == DMA2D_USE_MUTUAL_EXCLUSION) +#if (TRUE != CH_CFG_USE_MUTEXES) && (TRUE != CH_CFG_USE_SEMAPHORES) +#error "DMA2D_USE_MUTUAL_EXCLUSION requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES" +#endif +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/* Complex types forwarding.*/ +typedef union dma2d_coloralias_t dma2d_coloralias_t; +typedef struct dma2d_palcfg_t dma2d_palcfg_t; +typedef struct dma2d_laycfg_t dma2d_layercfg_t; +typedef struct DMA2DConfig DMA2DConfig; +typedef enum dma2d_state_t dma2d_state_t; +typedef struct DMA2DDriver DMA2DDriver; + +/** + * @name DMA2D Data types + * @{ + */ + +/** + * @brief DMA2D generic color. + */ +typedef uint32_t dma2d_color_t; + +/** + * @brief DMA2D color aliases. + * @detail Mapped with ARGB-8888, except for luminance (L mapped onto B). + * Padding fields prefixed with 'x', which should be clear + * (all 0) before compression and set (all 1) after expansion. + */ +typedef union dma2d_coloralias_t { + struct { + unsigned b : 8; + unsigned g : 8; + unsigned r : 8; + unsigned a : 8; + } argb8888; /**< Mapped ARGB-8888 bits.*/ + struct { + unsigned b : 8; + unsigned g : 8; + unsigned r : 8; + unsigned xa : 8; + } rgb888; /**< Mapped RGB-888 bits.*/ + struct { + unsigned xb : 3; + unsigned b : 5; + unsigned xg : 2; + unsigned g : 6; + unsigned xr : 3; + unsigned r : 5; + unsigned xa : 8; + } rgb565; /**< Mapped RGB-565 bits.*/ + struct { + unsigned xb : 3; + unsigned b : 5; + unsigned xg : 3; + unsigned g : 5; + unsigned xr : 3; + unsigned r : 5; + unsigned xa : 7; + unsigned a : 1; + } argb1555; /**< Mapped ARGB-1555 values.*/ + struct { + unsigned xb : 4; + unsigned b : 4; + unsigned xg : 4; + unsigned g : 4; + unsigned xr : 4; + unsigned r : 4; + unsigned xa : 4; + unsigned a : 4; + } argb4444; /**< Mapped ARGB-4444 values.*/ + struct { + unsigned l : 8; + unsigned x : 16; + unsigned xa : 8; + } l8; /**< Mapped L-8 bits.*/ + struct { + unsigned xl : 4; + unsigned l : 4; + unsigned x : 16; + unsigned xa : 4; + unsigned a : 4; + } al44; /**< Mapped AL-44 bits.*/ + struct { + unsigned l : 8; + unsigned x : 16; + unsigned a : 8; + } al88; /**< Mapped AL-88 bits.*/ + struct { + unsigned l : 4; + unsigned xl : 4; + unsigned x : 16; + unsigned xa : 8; + } l4; /**< Mapped L-4 bits.*/ + struct { + unsigned x : 24; + unsigned a : 8; + } a8; /**< Mapped A-8 bits.*/ + struct { + unsigned x : 24; + unsigned xa : 4; + unsigned a : 4; + } a4; /**< Mapped A-4 bits.*/ + dma2d_color_t aliased; /**< Aliased raw bits.*/ +} dma2d_coloralias_t; + +/** + * @brief DMA2D job (transfer) mode. + */ +typedef uint32_t dma2d_jobmode_t; + +/** + * @brief DMA2D pixel format. + */ +typedef uint32_t dma2d_pixfmt_t; + +/** + * @brief DMA2D alpha mode. + */ +typedef uint32_t dma2d_amode_t; + +/** + * @brief DMA2D ISR callback. + */ +typedef void (*dma2d_isrcb_t)(DMA2DDriver *dma2dp); + +/** + * @brief DMA2D palette specifications. + */ +typedef struct dma2d_palcfg_t { + const void *colorsp; /**< Pointer to color entries.*/ + uint16_t length; /**< Number of color entries.*/ + dma2d_pixfmt_t fmt; /**< Format, RGB-888 or ARGB-8888.*/ +} dma2d_palcfg_t; + +/** + * @brief DMA2D layer specifications. + */ +typedef struct dma2d_layercfg_t { + void *bufferp; /**< Frame buffer address.*/ + size_t wrap_offset; /**< Offset between lines, in pixels.*/ + dma2d_pixfmt_t fmt; /**< Pixel format.*/ + dma2d_color_t def_color; /**< Default color, RGB-888.*/ + uint8_t const_alpha; /**< Constant alpha factor.*/ + const dma2d_palcfg_t *palettep; /**< Palette specs, or @p NULL.*/ +} dma2d_laycfg_t; + +/** + * @brief DMA2D driver configuration. + */ +typedef struct DMA2DConfig { + /* ISR callbacks.*/ + dma2d_isrcb_t cfgerr_isr; /**< Configuration error, or @p NULL.*/ + dma2d_isrcb_t paltrfdone_isr; /**< Palette transfer done, or @p NULL.*/ + dma2d_isrcb_t palacserr_isr; /**< Palette access error, or @p NULL.*/ + dma2d_isrcb_t trfwmark_isr; /**< Transfer watermark, or @p NULL.*/ + dma2d_isrcb_t trfdone_isr; /**< Transfer complete, or @p NULL.*/ + dma2d_isrcb_t trferr_isr; /**< Transfer error, or @p NULL.*/ +} DMA2DConfig; + +/** + * @brief DMA2D driver state. + */ +typedef enum dma2d_state_t { + DMA2D_UNINIT = (0), /**< Not initialized.*/ + DMA2D_STOP = (1), /**< Stopped.*/ + DMA2D_READY = (2), /**< Ready.*/ + DMA2D_ACTIVE = (3), /**< Executing commands.*/ + DMA2D_PAUSED = (4), /**< Transfer suspended.*/ +} dma2d_state_t; + +/** + * @brief DMA2D driver. + */ +typedef struct DMA2DDriver { + dma2d_state_t state; /**< Driver state.*/ + const DMA2DConfig *config; /**< Driver configuration.*/ + + /* Multithreading stuff.*/ +#if (TRUE == DMA2D_USE_WAIT) || defined(__DOXYGEN__) + thread_t *thread; /**< Waiting thread.*/ +#endif /* DMA2D_USE_WAIT */ +#if (TRUE == DMA2D_USE_MUTUAL_EXCLUSION) +#if (TRUE == CH_CFG_USE_MUTEXES) + mutex_t lock; /**< Multithreading lock.*/ +#elif (TRUE == CH_CFG_USE_SEMAPHORES) + semaphore_t lock; /**< Multithreading lock.*/ +#endif +#endif /* DMA2D_USE_MUTUAL_EXCLUSION */ +} DMA2DDriver; + +/** @} */ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Makes an ARGB-8888 value from byte components. + * + * @param[in] a alpha byte component + * @param[in] r red byte component + * @param[in] g green byte component + * @param[in] b blue byte component + * + * @return color in ARGB-8888 format + * + * @api + */ +#define dma2dMakeARGB8888(a, r, g, b) \ + ((((dma2d_color_t)(a) & 0xFF) << 24) | \ + (((dma2d_color_t)(r) & 0xFF) << 16) | \ + (((dma2d_color_t)(g) & 0xFF) << 8) | \ + (((dma2d_color_t)(b) & 0xFF) << 0)) + +/** + * @brief Compute bytes per pixel. + * @details Computes the bytes per pixel for the specified pixel format. + * Rounds to the ceiling. + * + * @param[in] fmt pixel format + * + * @return bytes per pixel + * + * @api + */ +#define dma2dBytesPerPixel(fmt) \ + ((dma2dBitsPerPixel(fmt) + 7) >> 3) + +/** + * @brief Compute pixel address. + * @details Computes the buffer address of a pixel, given the buffer + * specifications. + * + * @param[in] originp buffer origin address + * @param[in] pitch buffer pitch, in bytes + * @param[in] fmt buffer pixel format + * @param[in] x horizontal pixel coordinate + * @param[in] y vertical pixel coordinate + * + * @return pixel address + * + * @api + */ +#define dma2dComputeAddress(originp, pitch, fmt, x, y) \ + ((void *)dma2dComputeAddressConst(originp, pitch, fmt, x, y)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern DMA2DDriver DMA2DD1; + +#ifdef __cplusplus +extern "C" { +#endif + + /* Driver methods.*/ + void dma2dInit(void); + void dma2dObjectInit(DMA2DDriver *dma2dp); + dma2d_state_t dma2dGetStateI(DMA2DDriver *dma2dp); + dma2d_state_t dma2dGetState(DMA2DDriver *dma2dp); + void dma2dStart(DMA2DDriver *dma2dp, const DMA2DConfig *configp); + void dma2dStop(DMA2DDriver *dma2dp); +#if (TRUE == DMA2D_USE_MUTUAL_EXCLUSION) + void dma2dAcquireBusS(DMA2DDriver *dma2dp); + void dma2dAcquireBus(DMA2DDriver *dma2dp); + void dma2dReleaseBusS(DMA2DDriver *dma2dp); + void dma2dReleaseBus(DMA2DDriver *dma2dp); +#endif /* DMA2D_USE_MUTUAL_EXCLUSION */ + + /* Global methods.*/ + uint16_t dma2dGetWatermarkPosI(DMA2DDriver *dma2dp); + uint16_t dma2dGetWatermarkPos(DMA2DDriver *dma2dp); + void dma2dSetWatermarkPosI(DMA2DDriver *dma2dp, uint16_t line); + void dma2dSetWatermarkPos(DMA2DDriver *dma2dp, uint16_t line); + bool dma2dIsWatermarkEnabledI(DMA2DDriver *dma2dp); + bool dma2dIsWatermarkEnabled(DMA2DDriver *dma2dp); + void dma2dEnableWatermarkI(DMA2DDriver *dma2dp); + void dma2dEnableWatermark(DMA2DDriver *dma2dp); + void dma2dDisableWatermarkI(DMA2DDriver *dma2dp); + void dma2dDisableWatermark(DMA2DDriver *dma2dp); + uint32_t dma2dGetDeadTimeI(DMA2DDriver *dma2dp); + uint32_t dma2dGetDeadTime(DMA2DDriver *dma2dp); + void dma2dSetDeadTimeI(DMA2DDriver *dma2dp, uint32_t cycles); + void dma2dSetDeadTime(DMA2DDriver *dma2dp, uint32_t cycles); + bool dma2dIsDeadTimeEnabledI(DMA2DDriver *dma2dp); + bool dma2dIsDeadTimeEnabled(DMA2DDriver *dma2dp); + void dma2dEnableDeadTimeI(DMA2DDriver *dma2dp); + void dma2dEnableDeadTime(DMA2DDriver *dma2dp); + void dma2dDisableDeadTimeI(DMA2DDriver *dma2dp); + void dma2dDisableDeadTime(DMA2DDriver *dma2dp); + + /* Job methods.*/ + dma2d_jobmode_t dma2dJobGetModeI(DMA2DDriver *dma2dp); + dma2d_jobmode_t dma2dJobGetMode(DMA2DDriver *dma2dp); + void dma2dJobSetModeI(DMA2DDriver *dma2dp, dma2d_jobmode_t mode); + void dma2dJobSetMode(DMA2DDriver *dma2dp, dma2d_jobmode_t mode); + void dma2dJobGetSizeI(DMA2DDriver *dma2dp, + uint16_t *widthp, uint16_t *heightp); + void dma2dJobGetSize(DMA2DDriver *dma2dp, + uint16_t *widthp, uint16_t *heightp); + void dma2dJobSetSizeI(DMA2DDriver *dma2dp, uint16_t width, uint16_t height); + void dma2dJobSetSize(DMA2DDriver *dma2dp, uint16_t width, uint16_t height); + bool dma2dJobIsExecutingI(DMA2DDriver *dma2dp); + bool dma2dJobIsExecuting(DMA2DDriver *dma2dp); + void dma2dJobStartI(DMA2DDriver *dma2dp); + void dma2dJobStart(DMA2DDriver *dma2dp); + void dma2dJobExecuteS(DMA2DDriver *dma2dp); + void dma2dJobExecute(DMA2DDriver *dma2dp); + void dma2dJobSuspendI(DMA2DDriver *dma2dp); + void dma2dJobSuspend(DMA2DDriver *dma2dp); + void dma2dJobResumeI(DMA2DDriver *dma2dp); + void dma2dJobResume(DMA2DDriver *dma2dp); + void dma2dJobAbortI(DMA2DDriver *dma2dp); + void dma2dJobAbort(DMA2DDriver *dma2dp); + + /* Background layer methods.*/ + void *dma2dBgGetAddressI(DMA2DDriver *dma2dp); + void *dma2dBgGetAddress(DMA2DDriver *dma2dp); + void dma2dBgSetAddressI(DMA2DDriver *dma2dp, void *bufferp); + void dma2dBgSetAddress(DMA2DDriver *dma2dp, void *bufferp); + size_t dma2dBgGetWrapOffsetI(DMA2DDriver *dma2dp); + size_t dma2dBgGetWrapOffset(DMA2DDriver *dma2dp); + void dma2dBgSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset); + void dma2dBgSetWrapOffset(DMA2DDriver *dma2dp, size_t offset); + uint8_t dma2dBgGetConstantAlphaI(DMA2DDriver *dma2dp); + uint8_t dma2dBgGetConstantAlpha(DMA2DDriver *dma2dp); + void dma2dBgSetConstantAlphaI(DMA2DDriver *dma2dp, uint8_t a); + void dma2dBgSetConstantAlpha(DMA2DDriver *dma2dp, uint8_t a); + dma2d_amode_t dma2dBgGetAlphaModeI(DMA2DDriver *dma2dp); + dma2d_amode_t dma2dBgGetAlphaMode(DMA2DDriver *dma2dp); + void dma2dBgSetAlphaModeI(DMA2DDriver *dma2dp, dma2d_amode_t mode); + void dma2dBgSetAlphaMode(DMA2DDriver *dma2dp, dma2d_amode_t mode); + dma2d_pixfmt_t dma2dBgGetPixelFormatI(DMA2DDriver *dma2dp); + dma2d_pixfmt_t dma2dBgGetPixelFormat(DMA2DDriver *dma2dp); + void dma2dBgSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt); + void dma2dBgSetPixelFormat(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt); + dma2d_color_t dma2dBgGetDefaultColorI(DMA2DDriver *dma2dp); + dma2d_color_t dma2dBgGetDefaultColor(DMA2DDriver *dma2dp); + void dma2dBgSetDefaultColorI(DMA2DDriver *dma2dp, dma2d_color_t c); + void dma2dBgSetDefaultColor(DMA2DDriver *dma2dp, dma2d_color_t c); + void dma2dBgGetPaletteI(DMA2DDriver *dma2dp, dma2d_palcfg_t *palettep); + void dma2dBgGetPalette(DMA2DDriver *dma2dp, dma2d_palcfg_t *palettep); + void dma2dBgSetPaletteS(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep); + void dma2dBgSetPalette(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep); + void dma2dBgGetLayerI(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp); + void dma2dBgGetLayer(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp); + void dma2dBgSetConfigS(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp); + void dma2dBgSetConfig(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp); + + /* Foreground layer methods.*/ + void *dma2dFgGetAddressI(DMA2DDriver *dma2dp); + void *dma2dFgGetAddress(DMA2DDriver *dma2dp); + void dma2dFgSetAddressI(DMA2DDriver *dma2dp, void *bufferp); + void dma2dFgSetAddress(DMA2DDriver *dma2dp, void *bufferp); + size_t dma2dFgGetWrapOffsetI(DMA2DDriver *dma2dp); + size_t dma2dFgGetWrapOffset(DMA2DDriver *dma2dp); + void dma2dFgSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset); + void dma2dFgSetWrapOffset(DMA2DDriver *dma2dp, size_t offset); + uint8_t dma2dFgGetConstantAlphaI(DMA2DDriver *dma2dp); + uint8_t dma2dFgGetConstantAlpha(DMA2DDriver *dma2dp); + void dma2dFgSetConstantAlphaI(DMA2DDriver *dma2dp, uint8_t a); + void dma2dFgSetConstantAlpha(DMA2DDriver *dma2dp, uint8_t a); + dma2d_amode_t dma2dFgGetAlphaModeI(DMA2DDriver *dma2dp); + dma2d_amode_t dma2dFgGetAlphaMode(DMA2DDriver *dma2dp); + void dma2dFgSetAlphaModeI(DMA2DDriver *dma2dp, dma2d_amode_t mode); + void dma2dFgSetAlphaMode(DMA2DDriver *dma2dp, dma2d_amode_t mode); + dma2d_pixfmt_t dma2dFgGetPixelFormatI(DMA2DDriver *dma2dp); + dma2d_pixfmt_t dma2dFgGetPixelFormat(DMA2DDriver *dma2dp); + void dma2dFgSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt); + void dma2dFgSetPixelFormat(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt); + dma2d_color_t dma2dFgGetDefaultColorI(DMA2DDriver *dma2dp); + dma2d_color_t dma2dFgGetDefaultColor(DMA2DDriver *dma2dp); + void dma2dFgSetDefaultColorI(DMA2DDriver *dma2dp, dma2d_color_t c); + void dma2dFgSetDefaultColor(DMA2DDriver *dma2dp, dma2d_color_t c); + void dma2dFgGetPaletteI(DMA2DDriver *dma2dp, dma2d_palcfg_t *palettep); + void dma2dFgGetPalette(DMA2DDriver *dma2dp, dma2d_palcfg_t *palettep); + void dma2dFgSetPaletteS(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep); + void dma2dFgSetPalette(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep); + void dma2dFgGetLayerI(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp); + void dma2dFgGetLayer(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp); + void dma2dFgSetConfigS(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp); + void dma2dFgSetConfig(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp); + + /* Output layer methods.*/ + void *dma2dOutGetAddressI(DMA2DDriver *dma2dp); + void *dma2dOutGetAddress(DMA2DDriver *dma2dp); + void dma2dOutSetAddressI(DMA2DDriver *dma2dp, void *bufferp); + void dma2dOutSetAddress(DMA2DDriver *dma2dp, void *bufferp); + size_t dma2dOutGetWrapOffsetI(DMA2DDriver *dma2dp); + size_t dma2dOutGetWrapOffset(DMA2DDriver *dma2dp); + void dma2dOutSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset); + void dma2dOutSetWrapOffset(DMA2DDriver *dma2dp, size_t offset); + dma2d_pixfmt_t dma2dOutGetPixelFormatI(DMA2DDriver *dma2dp); + dma2d_pixfmt_t dma2dOutGetPixelFormat(DMA2DDriver *dma2dp); + void dma2dOutSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt); + void dma2dOutSetPixelFormat(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt); + dma2d_color_t dma2dOutGetDefaultColorI(DMA2DDriver *dma2dp); + dma2d_color_t dma2dOutGetDefaultColor(DMA2DDriver *dma2dp); + void dma2dOutSetDefaultColorI(DMA2DDriver *dma2dp, dma2d_color_t c); + void dma2dOutSetDefaultColor(DMA2DDriver *dma2dp, dma2d_color_t c); + void dma2dOutGetLayerI(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp); + void dma2dOutGetLayer(DMA2DDriver *dma2dp, dma2d_laycfg_t *cfgp); + void dma2dOutSetConfigI(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp); + void dma2dOutSetConfig(DMA2DDriver *dma2dp, const dma2d_laycfg_t *cfgp); + + /* Helper functions.*/ + const void *dma2dComputeAddressConst(const void *originp, size_t pitch, + dma2d_pixfmt_t fmt, + uint16_t x, uint16_t y); + bool dma2dIsAligned(const void *bufferp, dma2d_pixfmt_t fmt); + size_t dma2dBitsPerPixel(dma2d_pixfmt_t fmt); +#if (TRUE == DMA2D_USE_SOFTWARE_CONVERSIONS) || defined(__DOXYGEN__) + dma2d_color_t dma2dFromARGB8888(dma2d_color_t c, dma2d_pixfmt_t fmt); + dma2d_color_t dma2dToARGB8888(dma2d_color_t c, dma2d_pixfmt_t fmt); +#endif /* DMA2D_USE_SOFTWARE_CONVERSIONS */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32_DMA2D_USE_DMA2D */ + +#endif /* _STM32_DMA2D_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c new file mode 100644 index 0000000..c7cabfc --- /dev/null +++ b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c @@ -0,0 +1,3792 @@ +/* + Copyright (C) 2013-2015 Andrea Zoppi + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file stm32_ltdc.c + * @brief LCD-TFT Controller Driver. + */ + +#include "ch.h" +#include "hal.h" + +#include "stm32_ltdc.h" + +#if (TRUE == STM32_LTDC_USE_LTDC) || defined(__DOXYGEN__) + +/* TODO: Check preconditions (e.g., LTDC is ready).*/ + +/* Ignore annoying warning messages for actually safe code.*/ +#if defined(__GNUC__) && !defined(__DOXYGEN__) +#pragma GCC diagnostic ignored "-Wtype-limits" +#endif + +/** + * @addtogroup ltdc + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#if !defined(LTDC_LxBFCR_BF) && !defined(__DOXYGEN__) +#define LTDC_LxBFCR_BF (LTDC_LxBFCR_BF1 | LTDC_LxBFCR_BF2) +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief LTDC1 driver identifier. + */ +LTDCDriver LTDCD1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/** + * @brief Bits per pixel lookup table. + */ +static const uint8_t ltdc_bpp[LTDC_MAX_PIXFMT_ID + 1] = { + 32, /* LTDC_FMT_ARGB8888 */ + 24, /* LTDC_FMT_RGB888 */ + 16, /* LTDC_FMT_RGB565 */ + 16, /* LTDC_FMT_ARGB1555 */ + 16, /* LTDC_FMT_ARGB4444 */ + 8, /* LTDC_FMT_L8 */ + 8, /* LTDC_FMT_AL44 */ + 16 /* LTDC_FMT_AL88 */ +}; + +/** + * @brief Invalid frame. + */ +static const ltdc_frame_t ltdc_invalid_frame = { + NULL, + 1, + 1, + 1, + LTDC_FMT_L8 +}; + +/** + * @brief Invalid window. + * @details Pixel size, located at the origin of the screen. + */ +static const ltdc_window_t ltdc_invalid_window = { + 0, + 1, + 0, + 1 +}; + +/** + * @brief Default layer specifications. + */ +static const ltdc_laycfg_t ltdc_default_laycfg = { + <dc_invalid_frame, + <dc_invalid_window, + LTDC_COLOR_BLACK, + 0x00, + LTDC_COLOR_BLACK, + NULL, + 0, + LTDC_BLEND_FIX1_FIX2, + 0 +}; + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/** + * @brief Forces LTDC register reload. + * @details Blocking function. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @sclass + * @notapi + */ +static void ltdc_force_reload_s(LTDCDriver *ltdcp) { + + osalDbgCheckClassS(); + osalDbgCheck(ltdcp == <DCD1); + + LTDC->SRCR |= LTDC_SRCR_IMR; + while (LTDC->SRCR & (LTDC_SRCR_IMR | LTDC_SRCR_VBR)) + chSchDoYieldS(); +} + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @name LTDC interrupt handlers + * @{ + */ + +/** + * @brief LTDC event interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_LTDC_EV_HANDLER) { + + LTDCDriver *const ltdcp = <DCD1; + thread_t *tp = NULL; + + OSAL_IRQ_PROLOGUE(); + + /* Handle Line Interrupt ISR.*/ + if ((LTDC->ISR & LTDC_ISR_LIF) && (LTDC->IER & LTDC_IER_LIE)) { + osalDbgAssert(ltdcp->config->line_isr != NULL, "invalid state"); + ltdcp->config->line_isr(ltdcp); + LTDC->ICR |= LTDC_ICR_CLIF; + } + + /* Handle Register Reload ISR.*/ + if ((LTDC->ISR & LTDC_ISR_RRIF) && (LTDC->IER & LTDC_IER_RRIE)) { + if (ltdcp->config->rr_isr != NULL) + ltdcp->config->rr_isr(ltdcp); + + osalSysLockFromISR(); + osalDbgAssert(ltdcp->state == LTDC_ACTIVE, "invalid state"); +#if (TRUE == LTDC_USE_WAIT) + /* Wake the waiting thread up.*/ + if (ltdcp->thread != NULL) { + tp = ltdcp->thread; + ltdcp->thread = NULL; + tp->p_u.rdymsg = MSG_OK; + chSchReadyI(tp); + } +#endif /* LTDC_USE_WAIT */ + ltdcp->state = LTDC_READY; + osalSysUnlockFromISR(); + + LTDC->ICR |= LTDC_ICR_CRRIF; + } + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief LTDC error interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_LTDC_ER_HANDLER) { + + static LTDCDriver *const ltdcp = <DCD1; + + OSAL_IRQ_PROLOGUE(); + + /* Handle FIFO Underrun ISR.*/ + if ((LTDC->ISR & LTDC_ISR_FUIF) && (LTDC->IER & LTDC_IER_FUIE)) { + osalDbgAssert(ltdcp->config->fuerr_isr != NULL, "invalid state"); + ltdcp->config->fuerr_isr(ltdcp); + LTDC->ICR |= LTDC_ICR_CFUIF; + } + + /* Handle Transfer Error ISR.*/ + if ((LTDC->ISR & LTDC_ISR_TERRIF) && (LTDC->IER & LTDC_IER_TERRIE)) { + osalDbgAssert(ltdcp->config->terr_isr != NULL, "invalid state"); + ltdcp->config->terr_isr(ltdcp); + LTDC->ICR |= LTDC_ICR_CTERRIF; + } + + OSAL_IRQ_EPILOGUE(); +} + +/** @} */ + +/** + * @name LTDC driver-specific methods + * @{ + */ + +/** + * @brief LTDC Driver initialization. + * @details Initializes the LTDC subsystem and chosen drivers. Should be + * called at board initialization. + * + * @init + */ +void ltdcInit(void) { + + /* Reset the LTDC hardware module.*/ + rccResetLTDC(); + + /* Enable the LTDC clock.*/ + RCC->DCKCFGR = (RCC->DCKCFGR & ~RCC_DCKCFGR_PLLSAIDIVR) | (2 << 16); /* /8 */ + rccEnableLTDC(false); + + /* Driver struct initialization.*/ + ltdcObjectInit(<DCD1); + LTDCD1.state = LTDC_STOP; +} + +/** + * @brief Initializes the standard part of a @p LTDCDriver structure. + * + * @param[out] ltdcp pointer to the @p LTDCDriver object + * + * @init + */ +void ltdcObjectInit(LTDCDriver *ltdcp) { + + osalDbgCheck(ltdcp == <DCD1); + + ltdcp->state = LTDC_UNINIT; + ltdcp->config = NULL; + ltdcp->active_window = ltdc_invalid_window; +#if (TRUE == LTDC_USE_WAIT) + ltdcp->thread = NULL; +#endif /* LTDC_USE_WAIT */ +#if (TRUE == LTDC_USE_MUTUAL_EXCLUSION) +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxObjectInit(<dcp->lock); +#else + chSemObjectInit(<dcp->lock, 1); +#endif +#endif /* LTDC_USE_MUTUAL_EXCLUSION */ +} + +/** + * @brief Get the driver state. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @retun driver state + * + * @iclass + */ +ltdc_state_t ltdcGetStateI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + + return ltdcp->state; +} + +/** + * @brief Get the driver state. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @retun driver state + * + * @api + */ +ltdc_state_t ltdcGetState(LTDCDriver *ltdcp) { + + ltdc_state_t state; + osalSysLock(); + state = ltdcGetStateI(ltdcp); + osalSysUnlock(); + return state; +} + +/** + * @brief Configures and activates the LTDC peripheral. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] configp pointer to the @p LTDCConfig object + * + * @api + */ +void ltdcStart(LTDCDriver *ltdcp, const LTDCConfig *configp) { + + uint32_t hacc, vacc, flags; + + osalSysLock(); + + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(configp != NULL); + osalDbgAssert(ltdcp->state == LTDC_STOP, "invalid state"); + + ltdcp->config = configp; + + /* Turn off the controller and its interrupts.*/ + LTDC->GCR = 0; + LTDC->IER = 0; + ltdc_force_reload_s(ltdcp); + + /* Set synchronization params.*/ + osalDbgAssert(configp->hsync_width >= LTDC_MIN_HSYNC_WIDTH, "bounds"); + osalDbgAssert(configp->hsync_width <= LTDC_MAX_HSYNC_WIDTH, "bounds"); + osalDbgAssert(configp->vsync_height >= LTDC_MIN_VSYNC_HEIGHT, "bounds"); + osalDbgAssert(configp->vsync_height <= LTDC_MAX_VSYNC_HEIGHT, "bounds"); + + hacc = configp->hsync_width - 1; + vacc = configp->vsync_height - 1; + + LTDC->SSCR = ((hacc << 16) & LTDC_SSCR_HSW) | + ((vacc << 0) & LTDC_SSCR_VSH); + + /* Set accumulated back porch params.*/ + osalDbgAssert(configp->hbp_width >= LTDC_MIN_HBP_WIDTH, "bounds"); + osalDbgAssert(configp->hbp_width <= LTDC_MAX_HBP_WIDTH, "bounds"); + osalDbgAssert(configp->vbp_height >= LTDC_MIN_VBP_HEIGHT, "bounds"); + osalDbgAssert(configp->vbp_height <= LTDC_MAX_VBP_HEIGHT, "bounds"); + + hacc += configp->hbp_width; + vacc += configp->vbp_height; + + osalDbgAssert(hacc + 1 >= LTDC_MIN_ACC_HBP_WIDTH, "bounds"); + osalDbgAssert(hacc + 1 <= LTDC_MAX_ACC_HBP_WIDTH, "bounds"); + osalDbgAssert(vacc + 1 >= LTDC_MIN_ACC_VBP_HEIGHT, "bounds"); + osalDbgAssert(vacc + 1 <= LTDC_MAX_ACC_VBP_HEIGHT, "bounds"); + + LTDC->BPCR = ((hacc << 16) & LTDC_BPCR_AHBP) | + ((vacc << 0) & LTDC_BPCR_AVBP); + + ltdcp->active_window.hstart = hacc + 1; + ltdcp->active_window.vstart = vacc + 1; + + /* Set accumulated active params.*/ + osalDbgAssert(configp->screen_width >= LTDC_MIN_SCREEN_WIDTH, "bounds"); + osalDbgAssert(configp->screen_width <= LTDC_MAX_SCREEN_WIDTH, "bounds"); + osalDbgAssert(configp->screen_height >= LTDC_MIN_SCREEN_HEIGHT, "bounds"); + osalDbgAssert(configp->screen_height <= LTDC_MAX_SCREEN_HEIGHT, "bounds"); + + hacc += configp->screen_width; + vacc += configp->screen_height; + + osalDbgAssert(hacc + 1 >= LTDC_MIN_ACC_ACTIVE_WIDTH, "bounds"); + osalDbgAssert(hacc + 1 <= LTDC_MAX_ACC_ACTIVE_WIDTH, "bounds"); + osalDbgAssert(vacc + 1 >= LTDC_MIN_ACC_ACTIVE_HEIGHT, "bounds"); + osalDbgAssert(vacc + 1 <= LTDC_MAX_ACC_ACTIVE_HEIGHT, "bounds"); + + LTDC->AWCR = ((hacc << 16) & LTDC_AWCR_AAW) | + ((vacc << 0) & LTDC_AWCR_AAH); + + ltdcp->active_window.hstop = hacc; + ltdcp->active_window.vstop = vacc; + + /* Set accumulated total params.*/ + osalDbgAssert(configp->hfp_width >= LTDC_MIN_HFP_WIDTH, "bounds"); + osalDbgAssert(configp->hfp_width <= LTDC_MAX_HFP_WIDTH, "bounds"); + osalDbgAssert(configp->vfp_height >= LTDC_MIN_VFP_HEIGHT, "bounds"); + osalDbgAssert(configp->vfp_height <= LTDC_MAX_VFP_HEIGHT, "bounds"); + + hacc += configp->hfp_width; + vacc += configp->vfp_height; + + osalDbgAssert(hacc + 1 >= LTDC_MIN_ACC_TOTAL_WIDTH, "bounds"); + osalDbgAssert(hacc + 1 <= LTDC_MAX_ACC_TOTAL_WIDTH, "bounds"); + osalDbgAssert(vacc + 1 >= LTDC_MIN_ACC_TOTAL_HEIGHT, "bounds"); + osalDbgAssert(vacc + 1 <= LTDC_MAX_ACC_TOTAL_HEIGHT, "bounds"); + + LTDC->TWCR = ((hacc << 16) & LTDC_TWCR_TOTALW) | + ((vacc << 0) & LTDC_TWCR_TOTALH); + + /* Set signal polarities and other flags.*/ + ltdcSetEnableFlagsI(ltdcp, configp->flags & ~LTDC_EF_ENABLE); + + /* Color settings.*/ + ltdcSetClearColorI(ltdcp, configp->clear_color); + + /* Load layer configurations.*/ + ltdcBgSetConfigI(ltdcp, configp->bg_laycfg); + ltdcFgSetConfigI(ltdcp, configp->fg_laycfg); + + /* Enable only the assigned interrupt service routines.*/ + nvicEnableVector(STM32_LTDC_EV_NUMBER, STM32_LTDC_EV_IRQ_PRIORITY); + nvicEnableVector(STM32_LTDC_ER_NUMBER, STM32_LTDC_ER_IRQ_PRIORITY); + + flags = LTDC_IER_RRIE; + if (configp->line_isr != NULL) + flags |= LTDC_IER_LIE; + if (configp->fuerr_isr != NULL) + flags |= LTDC_IER_FUIE; + if (configp->terr_isr != NULL) + flags |= LTDC_IER_TERRIE; + LTDC->IER = flags; + + /* Apply settings.*/ + ltdc_force_reload_s(ltdcp); + + /* Turn on the controller.*/ + LTDC->GCR |= LTDC_GCR_LTDCEN; + ltdc_force_reload_s(ltdcp); + + ltdcp->state = LTDC_READY; + osalSysUnlock(); +} + +/** + * @brief Deactivates the LTDC peripheral. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcStop(LTDCDriver *ltdcp) { + + osalDbgCheck(ltdcp == <DCD1); + + osalSysLock(); + osalDbgAssert(ltdcp->state == LTDC_READY, "invalid state"); + + /* Turn off the controller and its interrupts.*/ + LTDC->GCR &= ~LTDC_GCR_LTDCEN; + LTDC->IER = 0; +#if (TRUE == LTDC_USE_WAIT) + ltdcReloadS(ltdcp, true); +#else + ltdcStartReloadI(ltdcp, true); + while (ltdcIsReloadingI(ltdcp)) + chSchDoYieldS(); +#endif /* LTDC_USE_WAIT */ + + ltdcp->state = LTDC_STOP; + osalSysUnlock(); +} + +#if (TRUE == LTDC_USE_MUTUAL_EXCLUSION) + +/** + * @brief Gains exclusive access to the LTDC module. + * @details This function tries to gain ownership to the LTDC module, if the + * module is already being used then the invoking thread is queued. + * @pre In order to use this function the option + * @p LTDC_USE_MUTUAL_EXCLUSION must be enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @sclass + */ +void ltdcAcquireBusS(LTDCDriver *ltdcp) { + + osalDbgCheckClassS(); + osalDbgCheck(ltdcp == <DCD1); + +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxLockS(<dcp->lock); +#else + chSemWaitS(<dcp->lock); +#endif +} + +/** + * @brief Gains exclusive access to the LTDC module. + * @details This function tries to gain ownership to the LTDC module, if the + * module is already being used then the invoking thread is queued. + * @pre In order to use this function the option + * @p LTDC_USE_MUTUAL_EXCLUSION must be enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcAcquireBus(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcAcquireBusS(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Releases exclusive access to the LTDC module. + * @pre In order to use this function the option + * @p LTDC_USE_MUTUAL_EXCLUSION must be enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @sclass + */ +void ltdcReleaseBusS(LTDCDriver *ltdcp) { + + osalDbgCheckClassS(); + osalDbgCheck(ltdcp == <DCD1); + +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxUnlockS(<dcp->lock); +#else + chSemSignalI(<dcp->lock); +#endif +} + +/** + * @brief Releases exclusive access to the LTDC module. + * @pre In order to use this function the option + * @p LTDC_USE_MUTUAL_EXCLUSION must be enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcReleaseBus(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcReleaseBusS(ltdcp); + osalSysUnlock(); +} + +#endif /* LTDC_USE_MUTUAL_EXCLUSION */ + +/** @} */ + +/** + * @name LTDC global methods + * @{ + */ + +/** + * @brief Get enabled flags. + * @details Returns all the flags of the LTDC_EF_* group at once. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled flags + * + * @iclass + */ +ltdc_flags_t ltdcGetEnableFlagsI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return LTDC->GCR & LTDC_EF_MASK; +} + +/** + * @brief Get enabled flags. + * @details Returns all the flags of the LTDC_EF_* group at once. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled flags + * + * @api + */ +ltdc_flags_t ltdcGetEnableFlags(LTDCDriver *ltdcp) { + + ltdc_flags_t flags; + osalSysLock(); + flags = ltdcGetEnableFlagsI(ltdcp); + osalSysUnlock(); + return flags; +} + +/** + * @brief Set enabled flags. + * @details Sets all the flags of the LTDC_EF_* group at once. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] flags enabled flags + * + * @iclass + */ +void ltdcSetEnableFlagsI(LTDCDriver *ltdcp, ltdc_flags_t flags) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC->GCR = flags & LTDC_EF_MASK; +} + +/** + * @brief Set enabled flags. + * @details Sets all the flags of the LTDC_EF_* group at once. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] flags enabled flags + * + * @api + */ +void ltdcSetEnableFlags(LTDCDriver *ltdcp, ltdc_flags_t flags) { + + osalSysLock(); + ltdcSetEnableFlagsI(ltdcp, flags); + osalSysUnlock(); +} + +/** + * @brief Reloading shadow registers. + * @details Tells whether the LTDC is reloading shadow registers. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return reloading + * + * @iclass + */ +bool ltdcIsReloadingI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC->SRCR & (LTDC_SRCR_IMR | LTDC_SRCR_VBR)) != 0; +} + +/** + * @brief Reloading shadow registers. + * @details Tells whether the LTDC is reloading shadow registers. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return reloading + * + * @api + */ +bool ltdcIsReloading(LTDCDriver *ltdcp) { + + bool reloading; + osalSysLock(); + reloading = ltdcIsReloadingI(ltdcp); + osalSysUnlock(); + return reloading; +} + +/** + * @brief Reload shadow registers. + * @details Starts reloading LTDC shadow registers, upon vsync or immediately. + * @post At the end of the operation the configured callback is invoked. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] immediately reload immediately, not upon vsync + * + * @iclass + */ +void ltdcStartReloadI(LTDCDriver *ltdcp, bool immediately) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgAssert(ltdcp->state == LTDC_READY, "not ready"); + (void)ltdcp; + + ltdcp->state = LTDC_ACTIVE; + if (immediately) + LTDC->SRCR |= LTDC_SRCR_IMR; + else + LTDC->SRCR |= LTDC_SRCR_VBR; +} + +/** + * @brief Reload shadow registers. + * @details Starts reloading LTDC shadow registers, upon vsync or immediately. + * @post At the end of the operation the configured callback is invoked. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] immediately reload immediately, not upon vsync + * + * @api + */ +void ltdcStartReload(LTDCDriver *ltdcp, bool immediately) { + + osalSysLock(); + ltdcStartReloadI(ltdcp, immediately); + osalSysUnlock(); +} + +/** + * @brief Reload shadow registers. + * @details Reloads LTDC shadow registers, upon vsync or immediately. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] immediately reload immediately, not upon vsync + * + * @sclass + */ +void ltdcReloadS(LTDCDriver *ltdcp, bool immediately) { + + osalDbgCheckClassS(); + osalDbgCheck(ltdcp == <DCD1); + + ltdcStartReloadI(ltdcp, immediately); + +#if (TRUE == LTDC_USE_WAIT) + osalDbgAssert(ltdcp->thread == NULL, "already waiting"); + + if (immediately) { + while (LTDC->SRCR & LTDC_SRCR_IMR) + chSchDoYieldS(); + ltdcp->state = LTDC_READY; + } else { + ltdcp->thread = chThdGetSelfX(); + chSchGoSleepS(CH_STATE_SUSPENDED); + } +#else + while (LTDC->SRCR & LTDC_SRCR_IMR) + chSchDoYieldS(); + ltdcp->state = LTDC_READY; +#endif +} + +/** + * @brief Reload shadow registers. + * @details Reloads LTDC shadow registers, upon vsync or immediately. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] immediately reload immediately, not upon vsync + * + * @api + */ +void ltdcReload(LTDCDriver *ltdcp, bool immediately) { + + osalSysLock(); + ltdcReloadS(ltdcp, immediately); + osalSysUnlock(); +} + +/** + * @brief Dithering enabled. + * @details Tells whether the dithering is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @iclass + */ +bool ltdcIsDitheringEnabledI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC->GCR & LTDC_GCR_DTEN) != 0; +} + +/** + * @brief Dithering enabled. + * @details Tells whether the dithering is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @api + */ +bool ltdcIsDitheringEnabled(LTDCDriver *ltdcp) { + + bool enabled; + osalSysLock(); + enabled = ltdcIsDitheringEnabledI(ltdcp); + osalSysUnlock(); + return enabled; +} + +/** + * @brief Enable dithering. + * @details Enables dithering capabilities for pixel formats with less than + * 8 bits per channel. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcEnableDitheringI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC->GCR |= LTDC_GCR_DTEN; +} + +/** + * @brief Enable dithering. + * @details Enables dithering capabilities for pixel formats with less than + * 8 bits per channel. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcEnableDithering(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcEnableDitheringI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Disable dithering. + * @details Disables dithering capabilities for pixel formats with less than + * 8 bits per channel. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcDisableDitheringI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC->GCR &= ~LTDC_GCR_DTEN; +} + +/** + * @brief Disable dithering. + * @details Disables dithering capabilities for pixel formats with less than + * 8 bits per channel. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcDisableDithering(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcDisableDitheringI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Get clear screen color. + * @details Gets the clear screen (actual background) color. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return clear screen color, RGB-888 + * + * @iclass + */ +ltdc_color_t ltdcGetClearColorI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_color_t)(LTDC->BCCR & 0x00FFFFFF); +} + +/** + * @brief Get clear screen color. + * @details Gets the clear screen (actual background) color. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return clear screen color, RGB-888 + * + * @api + */ +ltdc_color_t ltdcGetClearColor(LTDCDriver *ltdcp) { + + ltdc_color_t color; + osalSysLock(); + color = ltdcGetClearColorI(ltdcp); + osalSysUnlock(); + return color; +} + +/** + * @brief Set clear screen color. + * @details Sets the clear screen (actual background) color. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c clear screen color, RGB-888 + * + * @iclass + */ +void ltdcSetClearColorI(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC->BCCR = (LTDC->BCCR & ~0x00FFFFFF) | (c & 0x00FFFFFF); +} + +/** + * @brief Set clear screen color. + * @details Sets the clear screen (actual background) color. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c clear screen color, RGB-888 + * + * @api + */ +void ltdcSetClearColor(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalSysLock(); + ltdcSetClearColorI(ltdcp, c); + osalSysUnlock(); +} + +/** + * @brief Get line interrupt position. + * @details Gets the line interrupt position. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return line interrupt position + * + * @iclass + */ +uint16_t ltdcGetLineInterruptPosI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (uint16_t)(LTDC->LIPCR & LTDC_LIPCR_LIPOS); +} + +/** + * @brief Get line interrupt position. + * @details Gets the line interrupt position. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return line interrupt position + * + * @api + */ +uint16_t ltdcGetLineInterruptPos(LTDCDriver *ltdcp) { + + uint16_t line; + osalSysLock(); + line = ltdcGetLineInterruptPosI(ltdcp); + osalSysUnlock(); + return line; +} + +/** + * @brief Set line interrupt position. + * @details Sets the line interrupt position. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcSetLineInterruptPosI(LTDCDriver *ltdcp, uint16_t line) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC->LIPCR = (LTDC->LIPCR & ~LTDC_LIPCR_LIPOS) | + ((uint32_t)line & LTDC_LIPCR_LIPOS); +} + +/** + * @brief Set line interrupt position. + * @details Sets the line interrupt position. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcSetLineInterruptPos(LTDCDriver *ltdcp, uint16_t line) { + + osalSysLock(); + ltdcSetLineInterruptPosI(ltdcp, line); + osalSysUnlock(); +} + +/** + * @brief Line interrupt enabled. + * @details Tells whether the line interrupt is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @iclass + */ +bool ltdcIsLineInterruptEnabledI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC->IER & LTDC_IER_LIE) != 0; +} + +/** + * @brief Line interrupt enabled. + * @details Tells whether the line interrupt is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @api + */ +bool ltdcIsLineInterruptEnabled(LTDCDriver *ltdcp) { + + bool enabled; + osalSysLock(); + enabled = ltdcIsLineInterruptEnabledI(ltdcp); + osalSysUnlock(); + return enabled; +} + +/** + * @brief Enable line interrupt. + * @details Enables line interrupt. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcEnableLineInterruptI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC->IER |= LTDC_IER_LIE; +} + +/** + * @brief Enable line interrupt. + * @details Enables line interrupt. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcEnableLineInterrupt(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcEnableLineInterruptI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Disable line interrupt. + * @details Disables line interrupt. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcDisableLineInterruptI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC->IER &= ~LTDC_IER_LIE; +} + +/** + * @brief Disable line interrupt. + * @details Disables line interrupt. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcDisableLineInterrupt(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcDisableLineInterruptI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Get current position. + * @details Gets the current position. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] xp pointer to the destination horizontal coordinate + * @param[out] yp pointer to the destination vertical coordinate + * + * @iclass + */ +void ltdcGetCurrentPosI(LTDCDriver *ltdcp, uint16_t *xp, uint16_t *yp) { + + const uint32_t r = LTDC->CPSR; + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + *xp = (uint16_t)((r & LTDC_CPSR_CXPOS) >> 16); + *yp = (uint16_t)((r & LTDC_CPSR_CYPOS) >> 0); +} + +/** + * @brief Get current position. + * @details Gets the current position. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] xp pointer to the destination horizontal coordinate + * @param[out] yp pointer to the destination vertical coordinate + * + * @api + */ +void ltdcGetCurrentPos(LTDCDriver *ltdcp, uint16_t *xp, uint16_t *yp) { + + osalSysLock(); + ltdcGetCurrentPosI(ltdcp, xp, yp); + osalSysUnlock(); +} + +/** @} */ + +/** + * @name LTDC background layer (layer 1) methods + * @{ + */ + +/** + * @brief Get background layer enabled flags. + * @details Returns all the flags of the LTDC_LEF_* group at once. + * Targeting the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled flags + * + * @iclass + */ +ltdc_flags_t ltdcBgGetEnableFlagsI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return LTDC_Layer1->CR & LTDC_LEF_MASK; +} + +/** + * @brief Get background layer enabled flags. + * @details Returns all the flags of the LTDC_LEF_* group at once. + * Targeting the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled flags + * + * @api + */ +ltdc_flags_t ltdcBgGetEnableFlags(LTDCDriver *ltdcp) { + + ltdc_flags_t flags; + osalSysLock(); + flags = ltdcBgGetEnableFlagsI(ltdcp); + osalSysUnlock(); + return flags; +} + +/** + * @brief Set background layer enabled flags. + * @details Sets all the flags of the LTDC_LEF_* group at once. + * Targeting the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] flags enabled flags + * + * @iclass + */ +void ltdcBgSetEnableFlagsI(LTDCDriver *ltdcp, ltdc_flags_t flags) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CR = (LTDC_Layer1->CR & ~LTDC_LEF_MASK) | + ((uint32_t)flags & LTDC_LEF_MASK); +} + +/** + * @brief Set background layer enabled flags. + * @details Sets all the flags of the LTDC_LEF_* group at once. + * Targeting the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] flags enabled flags + * + * @api + */ +void ltdcBgSetEnableFlags(LTDCDriver *ltdcp, ltdc_flags_t flags) { + + osalSysLock(); + ltdcBgSetEnableFlagsI(ltdcp, flags); + osalSysUnlock(); +} + +/** + * @brief Background layer enabled. + * @details Tells whether the background layer (layer 1) is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @iclass + */ +bool ltdcBgIsEnabledI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC_Layer1->CR & ~LTDC_LxCR_LEN) != 0; +} + +/** + * @brief Background layer enabled. + * @details Tells whether the background layer (layer 1) is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @api + */ +bool ltdcBgIsEnabled(LTDCDriver *ltdcp) { + + bool enabled; + osalSysLock(); + enabled = ltdcBgIsEnabledI(ltdcp); + osalSysUnlock(); + return enabled; +} + +/** + * @brief Background layer enable. + * @details Enables the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcBgEnableI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CR |= LTDC_LxCR_LEN; +} + +/** + * @brief Background layer enable. + * @details Enables the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcBgEnable(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcBgEnableI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Background layer disable. + * @details Disables the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcBgDisableI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CR &= ~LTDC_LxCR_LEN; +} + +/** + * @brief Background layer disable. + * @details Disables the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcBgDisable(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcBgDisableI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Background layer palette enabled. + * @details Tells whether the background layer (layer 1) palette (color lookup + * table) is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @iclass + */ +bool ltdcBgIsPaletteEnabledI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC_Layer1->CR & ~LTDC_LxCR_CLUTEN) != 0; +} + +/** + * @brief Background layer palette enabled. + * @details Tells whether the background layer (layer 1) palette (color lookup + * table) is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @api + */ +bool ltdcBgIsPaletteEnabled(LTDCDriver *ltdcp) { + + bool enabled; + osalSysLock(); + enabled = ltdcBgIsPaletteEnabledI(ltdcp); + osalSysUnlock(); + return enabled; +} + +/** + * @brief Enable background layer palette. + * @details Enables the palette (color lookup table) of the background layer + * (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcBgEnablePaletteI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CR |= LTDC_LxCR_CLUTEN; +} + +/** + * @brief Enable background layer palette. + * @details Enables the palette (color lookup table) of the background layer + * (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcBgEnablePalette(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcBgEnablePaletteI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Disable background layer palette. + * @details Disables the palette (color lookup table) of the background layer + * (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcBgDisablePaletteI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CR &= ~LTDC_LxCR_CLUTEN; +} + +/** + * @brief Disable background layer palette. + * @details Disables the palette (color lookup table) of the background layer + * (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcBgDisablePalette(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcBgDisablePaletteI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Set background layer palette color. + * @details Sets the color of a palette (color lookup table) slot to the + * background layer (layer 1). + * @pre The layer must be disabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] slot palette slot + * @param[in] c color, RGB-888 + * + * @iclass + */ +void ltdcBgSetPaletteColorI(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgAssert(!ltdcBgIsEnabledI(ltdcp), "invalid state"); + (void)ltdcp; + + LTDC_Layer1->CLUTWR = ((uint32_t)slot << 24) | (c & 0x00FFFFFF); +} + +/** + * @brief Set background layer palette color. + * @details Sets the color of a palette (color lookup table) slot to the + * background layer (layer 1). + * @pre The layer must be disabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] slot palette slot + * @param[in] c color, RGB-888 + * + * @api + */ +void ltdcBgSetPaletteColor(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c) { + + osalSysLock(); + ltdcBgSetPaletteColorI(ltdcp, slot, c); + osalSysUnlock(); +} + +/** + * @brief Set background layer palette. + * @details Sets the entire palette color (color lookup table) slot. + * @pre The layer must be disabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] colors array of palette colors, RGB-888 + * @param[in] length number of palette colors + * + * @iclass + */ +void ltdcBgSetPaletteI(LTDCDriver *ltdcp, const ltdc_color_t colors[], + uint16_t length) { + + uint16_t i; + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck((colors == NULL) == (length == 0)); + osalDbgAssert(length <= LTDC_MAX_PALETTE_LENGTH, "bounds"); + osalDbgAssert(!ltdcBgIsEnabledI(ltdcp), "invalid state"); + (void)ltdcp; + + for (i = 0; i < length; ++i) + LTDC_Layer1->CLUTWR = ((uint32_t)i << 24) | (colors[i] & 0x00FFFFFF); +} + +/** + * @brief Set background layer palette. + * @details Sets the entire palette color (color lookup table) slot. + * @pre The layer must be disabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] colors array of palette colors, RGB-888 + * @param[in] length number of palette colors + * + * @api + */ +void ltdcBgSetPalette(LTDCDriver *ltdcp, const ltdc_color_t colors[], + uint16_t length) { + + osalSysLock(); + ltdcBgSetPaletteI(ltdcp, colors, length); + osalSysUnlock(); +} + +/** + * @brief Get background layer pixel format. + * @details Gets the pixel format of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return pixel format + * + * @iclass + */ +ltdc_pixfmt_t ltdcBgGetPixelFormatI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_pixfmt_t)(LTDC_Layer1->PFCR & LTDC_LxPFCR_PF); +} + +/** + * @brief Get background layer pixel format. + * @details Gets the pixel format of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return pixel format + * + * @api + */ +ltdc_pixfmt_t ltdcBgGetPixelFormat(LTDCDriver *ltdcp) { + + ltdc_pixfmt_t fmt; + osalSysLock(); + fmt = ltdcBgGetPixelFormatI(ltdcp); + osalSysUnlock(); + return fmt; +} + +/** + * @brief Set background layer pixel format. + * @details Sets the pixel format of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] fmt pixel format + * + * @iclass + */ +void ltdcBgSetPixelFormatI(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgAssert(fmt >= LTDC_MIN_PIXFMT_ID, "bounds"); + osalDbgAssert(fmt <= LTDC_MAX_PIXFMT_ID, "bounds"); + (void)ltdcp; + + LTDC_Layer1->PFCR = (LTDC_Layer1->PFCR & ~LTDC_LxPFCR_PF) | + ((uint32_t)fmt & LTDC_LxPFCR_PF); +} + +/** + * @brief Set background layer pixel format. + * @details Sets the pixel format of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] fmt pixel format + * + * @api + */ +void ltdcBgSetPixelFormat(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt) { + + osalSysLock(); + ltdcBgSetPixelFormatI(ltdcp, fmt); + osalSysUnlock(); +} + +/** + * @brief Background layer color keying enabled. + * @details Tells whether the background layer (layer 1) has color keying + * enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @iclass + */ +bool ltdcBgIsKeyingEnabledI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC_Layer1->CR & ~LTDC_LxCR_COLKEN) != 0; +} + +/** + * @brief Background layer color keying enabled. + * @details Tells whether the background layer (layer 1) has color keying + * enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @api + */ +bool ltdcBgIsKeyingEnabled(LTDCDriver *ltdcp) { + + bool enabled; + osalSysLock(); + enabled = ltdcBgIsKeyingEnabledI(ltdcp); + osalSysUnlock(); + return enabled; +} + +/** + * @brief Enable background layer color keying. + * @details Enables color keying capabilities of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcBgEnableKeyingI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CR |= LTDC_LxCR_COLKEN; +} + +/** + * @brief Enable background layer color keying. + * @details Enables color keying capabilities of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcBgEnableKeying(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcBgEnableKeyingI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Disable background layer color keying. + * @details Disables color keying capabilities of the background layer (layer + * 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcBgDisableKeyingI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CR &= ~LTDC_LxCR_COLKEN; +} + +/** + * @brief Disable background layer color keying. + * @details Disables color keying capabilities of the background layer (layer + * 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcBgDisableKeying(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcBgDisableKeyingI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Get background layer color key. + * @details Gets the color key of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return color key, RGB-888 + * + * @iclass + */ +ltdc_color_t ltdcBgGetKeyingColorI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_color_t)(LTDC_Layer1->CKCR & 0x00FFFFFF); +} + +/** + * @brief Get background layer color key. + * @details Gets the color key of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return color key, RGB-888 + * + * @api + */ +ltdc_color_t ltdcBgGetKeyingColor(LTDCDriver *ltdcp) { + + ltdc_color_t color; + osalSysLock(); + color = ltdcBgGetKeyingColorI(ltdcp); + osalSysUnlock(); + return color; +} + +/** + * @brief Set background layer color key. + * @details Sets the color key of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c color key, RGB-888 + * + * @iclass + */ +void ltdcBgSetKeyingColorI(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CKCR = (LTDC_Layer1->CKCR & ~0x00FFFFFF) | + ((uint32_t)c & 0x00FFFFFF); +} + +/** + * @brief Set background layer color key. + * @details Sets the color key of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c color key, RGB-888 + * + * @api + */ +void ltdcBgSetKeyingColor(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalSysLock(); + ltdcBgSetKeyingColorI(ltdcp, c); + osalSysUnlock(); +} + +/** + * @brief Get background layer constant alpha. + * @details Gets the constant alpha component of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return constant alpha component, A-8 + * + * @iclass + */ +uint8_t ltdcBgGetConstantAlphaI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (uint8_t)(LTDC_Layer1->CACR & LTDC_LxCACR_CONSTA); +} + +/** + * @brief Get background layer constant alpha. + * @details Gets the constant alpha component of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return constant alpha component, A-8 + * + * @api + */ +uint8_t ltdcBgGetConstantAlpha(LTDCDriver *ltdcp) { + + uint8_t a; + osalSysLock(); + a = ltdcBgGetConstantAlphaI(ltdcp); + osalSysUnlock(); + return a; +} + +/** + * @brief Set background layer constant alpha. + * @details Sets the constant alpha component of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] a constant alpha component, A-8 + * + * @iclass + */ +void ltdcBgSetConstantAlphaI(LTDCDriver *ltdcp, uint8_t a) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CACR = (LTDC_Layer1->CACR & ~LTDC_LxCACR_CONSTA) | + ((uint32_t)a & LTDC_LxCACR_CONSTA); +} + +/** + * @brief Set background layer constant alpha. + * @details Sets the constant alpha component of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] a constant alpha component, A-8 + * + * @api + */ +void ltdcBgSetConstantAlpha(LTDCDriver *ltdcp, uint8_t a) { + + osalSysLock(); + ltdcBgSetConstantAlphaI(ltdcp, a); + osalSysUnlock(); +} + +/** + * @brief Get background layer default color. + * @details Gets the default color of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return default color, RGB-888 + * + * @iclass + */ +ltdc_color_t ltdcBgGetDefaultColorI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_color_t)LTDC_Layer1->DCCR; +} + +/** + * @brief Get background layer default color. + * @details Gets the default color of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return default color, RGB-888 + * + * @api + */ +ltdc_color_t ltdcBgGetDefaultColor(LTDCDriver *ltdcp) { + + ltdc_color_t color; + osalSysLock(); + color = ltdcBgGetDefaultColorI(ltdcp); + osalSysUnlock(); + return color; +} + +/** + * @brief Set background layer default color. + * @details Sets the default color of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c default color, RGB-888 + * + * @iclass + */ +void ltdcBgSetDefaultColorI(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->DCCR = (uint32_t)c; +} + +/** + * @brief Set background layer default color. + * @details Sets the default color of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c default color, RGB-888 + * + * @api + */ +void ltdcBgSetDefaultColor(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalSysLock(); + ltdcBgSetDefaultColorI(ltdcp, c); + osalSysUnlock(); +} + +/** + * @brief Get background layer blending factors. + * @details Gets the blending factors of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return blending factors + * + * @iclass + */ +ltdc_blendf_t ltdcBgGetBlendingFactorsI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_blendf_t)(LTDC_Layer1->BFCR & LTDC_LxBFCR_BF); +} + +/** + * @brief Get background layer blending factors. + * @details Gets the blending factors of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return blending factors + * + * @api + */ +ltdc_blendf_t ltdcBgGetBlendingFactors(LTDCDriver *ltdcp) { + + ltdc_blendf_t bf; + osalSysLock(); + bf = ltdcBgGetBlendingFactorsI(ltdcp); + osalSysUnlock(); + return bf; +} + +/** + * @brief Set background layer blending factors. + * @details Sets the blending factors of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] factors blending factors + * + * @iclass + */ +void ltdcBgSetBlendingFactorsI(LTDCDriver *ltdcp, ltdc_blendf_t bf) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->BFCR = (LTDC_Layer1->BFCR & ~LTDC_LxBFCR_BF) | + ((uint32_t)bf & LTDC_LxBFCR_BF); +} + +/** + * @brief Set background layer blending factors. + * @details Sets the blending factors of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] factors blending factors + * + * @api + */ +void ltdcBgSetBlendingFactors(LTDCDriver *ltdcp, ltdc_blendf_t bf) { + + osalSysLock(); + ltdcBgSetBlendingFactorsI(ltdcp, bf); + osalSysUnlock(); +} + +/** + * @brief Get background layer window specs. + * @details Gets the window specifications of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] windowp pointer to the window specifications + * + * @iclass + */ +void ltdcBgGetWindowI(LTDCDriver *ltdcp, ltdc_window_t *windowp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(windowp != NULL); + (void)ltdcp; + + windowp->hstart = + (uint16_t)((LTDC_Layer1->WHPCR & LTDC_LxWHPCR_WHSTPOS) >> 0); + windowp->hstop = + (uint16_t)((LTDC_Layer1->WHPCR & LTDC_LxWHPCR_WHSPPOS) >> 16); + windowp->vstart = + (uint16_t)((LTDC_Layer1->WVPCR & LTDC_LxWVPCR_WVSTPOS) >> 0); + windowp->vstop = + (uint16_t)((LTDC_Layer1->WVPCR & LTDC_LxWVPCR_WVSPPOS) >> 16); +} + +/** + * @brief Get background layer window specs. + * @details Gets the window specifications of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] windowp pointer to the window specifications + * + * @api + */ +void ltdcBgGetWindow(LTDCDriver *ltdcp, ltdc_window_t *windowp) { + + osalSysLock(); + ltdcBgGetWindowI(ltdcp, windowp); + osalSysUnlock(); +} + +/** + * @brief Set background layer window specs. + * @details Sets the window specifications of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] windowp pointer to the window specifications + * + * @iclass + */ +void ltdcBgSetWindowI(LTDCDriver *ltdcp, const ltdc_window_t *windowp) { + + uint32_t start, stop; + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(windowp != NULL); + (void)ltdcp; + + osalDbgAssert(windowp->hstop < ltdcp->config->screen_width, "bounds"); + osalDbgAssert(windowp->vstop < ltdcp->config->screen_height, "bounds"); + + /* Horizontal boundaries.*/ + start = (uint32_t)windowp->hstart + ltdcp->active_window.hstart; + stop = (uint32_t)windowp->hstop + ltdcp->active_window.hstart; + + osalDbgAssert(start >= ltdcp->active_window.hstart, "bounds"); + osalDbgAssert(stop <= ltdcp->active_window.hstop, "bounds"); + + LTDC_Layer1->WHPCR = ((start << 0) & LTDC_LxWHPCR_WHSTPOS) | + ((stop << 16) & LTDC_LxWHPCR_WHSPPOS); + + /* Vertical boundaries.*/ + start = (uint32_t)windowp->vstart + ltdcp->active_window.vstart; + stop = (uint32_t)windowp->vstop + ltdcp->active_window.vstart; + + osalDbgAssert(start >= ltdcp->active_window.vstart, "bounds"); + osalDbgAssert(stop <= ltdcp->active_window.vstop, "bounds"); + + LTDC_Layer1->WVPCR = ((start << 0) & LTDC_LxWVPCR_WVSTPOS) | + ((stop << 16) & LTDC_LxWVPCR_WVSPPOS); +} + +/** + * @brief Set background layer window specs. + * @details Sets the window specifications of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] windowp pointer to the window specifications + * + * @api + */ +void ltdcBgSetWindow(LTDCDriver *ltdcp, const ltdc_window_t *windowp) { + + osalSysLock(); + ltdcBgSetWindowI(ltdcp, windowp); + osalSysUnlock(); +} + +/** + * @brief Set background layer window as invalid. + * @details Sets the window specifications of the background layer (layer 1) + * so that the window is pixel sized at the screen origin. + * @note Useful before reconfiguring the frame specifications of the layer, + * to avoid errors. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcBgSetInvalidWindowI(LTDCDriver *ltdcp) { + + ltdcBgSetWindowI(ltdcp, <dc_invalid_window); +} + +/** + * @brief Set background layer window as invalid. + * @details Sets the window specifications of the background layer (layer 1) + * so that the window is pixel sized at the screen origin. + * @note Useful before reconfiguring the frame specifications of the layer, + * to avoid errors. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcBgSetInvalidWindow(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcBgSetWindowI(ltdcp, <dc_invalid_window); + osalSysUnlock(); +} + +/** + * @brief Get background layer frame buffer specs. + * @details Gets the frame buffer specifications of the background layer + * (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] framep pointer to the frame buffer specifications + * + * @iclass + */ +void ltdcBgGetFrameI(LTDCDriver *ltdcp, ltdc_frame_t *framep) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(framep != NULL); + + framep->bufferp = (void *)(LTDC_Layer1->CFBAR & LTDC_LxCFBAR_CFBADD); + framep->pitch = (size_t)((LTDC_Layer1->CFBLR & LTDC_LxCFBLR_CFBP) >> 16); + framep->width = (uint16_t)(((LTDC_Layer1->CFBLR & LTDC_LxCFBLR_CFBLL) - 3) / + ltdcBytesPerPixel(ltdcBgGetPixelFormatI(ltdcp))); + framep->height = (uint16_t)(LTDC_Layer1->CFBLNR & LTDC_LxCFBLNR_CFBLNBR); +} + +/** + * @brief Get background layer frame buffer specs. + * @details Gets the frame buffer specifications of the background layer + * (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] framep pointer to the frame buffer specifications + * + * @api + */ +void ltdcBgGetFrame(LTDCDriver *ltdcp, ltdc_frame_t *framep) { + + osalSysLock(); + ltdcBgGetFrameI(ltdcp, framep); + osalSysUnlock(); +} + +/** + * @brief Set background layer frame buffer specs. + * @details Sets the frame buffer specifications of the background layer + * (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] framep pointer to the frame buffer specifications + * + * @iclass + */ +void ltdcBgSetFrameI(LTDCDriver *ltdcp, const ltdc_frame_t *framep) { + + size_t linesize; + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(framep != NULL); + + ltdcBgSetPixelFormatI(ltdcp, framep->fmt); + + linesize = ltdcBytesPerPixel(framep->fmt) * framep->width; + + osalDbgAssert(framep->width <= ltdcp->config->screen_width, "bounds"); + osalDbgAssert(framep->height <= ltdcp->config->screen_height, "bounds"); + osalDbgAssert(linesize >= LTDC_MIN_FRAME_WIDTH_BYTES, "bounds"); + osalDbgAssert(linesize <= LTDC_MAX_FRAME_WIDTH_BYTES, "bounds"); + osalDbgAssert(framep->height >= LTDC_MIN_FRAME_HEIGHT_LINES, "bounds"); + osalDbgAssert(framep->height <= LTDC_MAX_FRAME_HEIGHT_LINES, "bounds"); + osalDbgAssert(framep->pitch >= linesize, "bounds"); + + LTDC_Layer1->CFBAR = (uint32_t)framep->bufferp & LTDC_LxCFBAR_CFBADD; + LTDC_Layer1->CFBLR = ((((uint32_t)framep->pitch << 16) & LTDC_LxCFBLR_CFBP) | + ((linesize + 3) & LTDC_LxCFBLR_CFBLL)); + LTDC_Layer1->CFBLNR = (uint32_t)framep->height & LTDC_LxCFBLNR_CFBLNBR; +} + +/** + * @brief Set background layer frame buffer specs. + * @details Sets the frame buffer specifications of the background layer + * (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] framep pointer to the frame buffer specifications + * + * @api + */ +void ltdcBgSetFrame(LTDCDriver *ltdcp, const ltdc_frame_t *framep) { + + osalSysLock(); + ltdcBgSetFrameI(ltdcp, framep); + osalSysUnlock(); +} + +/** + * @brief Get background layer frame buffer address. + * @details Gets the frame buffer address of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return frame buffer address + * + * @iclass + */ +void *ltdcBgGetFrameAddressI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (void *)LTDC_Layer1->CFBAR; +} + +/** + * @brief Get background layer frame buffer address. + * @details Gets the frame buffer address of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return frame buffer address + * + * @api + */ +void *ltdcBgGetFrameAddress(LTDCDriver *ltdcp) { + + void *bufferp; + osalSysLock(); + bufferp = ltdcBgGetFrameAddressI(ltdcp); + osalSysUnlock(); + return bufferp; +} + +/** + * @brief Set background layer frame buffer address. + * @details Sets the frame buffer address of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] bufferp frame buffer address + * + * @iclass + */ +void ltdcBgSetFrameAddressI(LTDCDriver *ltdcp, void *bufferp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer1->CFBAR = (uint32_t)bufferp; +} + +/** + * @brief Set background layer frame buffer address. + * @details Sets the frame buffer address of the background layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] bufferp frame buffer address + * + * @api + */ +void ltdcBgSetFrameAddress(LTDCDriver *ltdcp, void *bufferp) { + + osalSysLock(); + ltdcBgSetFrameAddressI(ltdcp, bufferp); + osalSysUnlock(); +} + +/** + * @brief Get background layer specifications. + * @details Gets the background layer (layer 1) specifications at once. + * @note If palette specifications cannot be retrieved, they are set to + * @p NULL. This is not an error. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @iclass + */ +void ltdcBgGetLayerI(LTDCDriver *ltdcp, ltdc_laycfg_t *cfgp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(cfgp != NULL); + + ltdcBgGetFrameI(ltdcp, (ltdc_frame_t *)cfgp->frame); + ltdcBgGetWindowI(ltdcp, (ltdc_window_t *)cfgp->window); + cfgp->def_color = ltdcBgGetDefaultColorI(ltdcp); + cfgp->key_color = ltdcBgGetKeyingColorI(ltdcp); + cfgp->const_alpha = ltdcBgGetConstantAlphaI(ltdcp); + cfgp->blending = ltdcBgGetBlendingFactorsI(ltdcp); + + cfgp->pal_colors = NULL; + cfgp->pal_length = 0; + + cfgp->flags = ltdcBgGetEnableFlagsI(ltdcp); +} + +/** + * @brief Get background layer specifications. + * @details Gets the background layer (layer 1) specifications at once. + * @note If palette specifications cannot be retrieved, they are set to + * @p NULL. This is not an error. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @api + */ +void ltdcBgGetLayer(LTDCDriver *ltdcp, ltdc_laycfg_t *cfgp) { + + osalSysLock(); + ltdcBgGetLayerI(ltdcp, cfgp); + osalSysUnlock(); +} + +/** + * @brief Set background layer specifications. + * @details Sets the background layer (layer 1) specifications at once. + * @note If the palette is unspecified, the layer palette is unmodified. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @iclass + */ +void ltdcBgSetConfigI(LTDCDriver *ltdcp, const ltdc_laycfg_t *cfgp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + + if (cfgp == NULL) + cfgp = <dc_default_laycfg; + + osalDbgCheck((cfgp->pal_colors == NULL) == (cfgp->pal_length == 0)); + + ltdcBgSetFrameI(ltdcp, cfgp->frame); + ltdcBgSetWindowI(ltdcp, cfgp->window); + ltdcBgSetDefaultColorI(ltdcp, cfgp->def_color); + ltdcBgSetKeyingColorI(ltdcp, cfgp->key_color); + ltdcBgSetConstantAlphaI(ltdcp, cfgp->const_alpha); + ltdcBgSetBlendingFactorsI(ltdcp, cfgp->blending); + + if (cfgp->pal_length > 0) + ltdcBgSetPaletteI(ltdcp, cfgp->pal_colors, cfgp->pal_length); + + ltdcBgSetEnableFlagsI(ltdcp, cfgp->flags); +} + +/** + * @brief Set background layer specifications. + * @details Sets the background layer (layer 1) specifications at once. + * @note If the palette is unspecified, the layer palette is unmodified. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @api + */ +void ltdcBgSetConfig(LTDCDriver *ltdcp, const ltdc_laycfg_t *cfgp) { + + osalSysLock(); + ltdcBgSetConfigI(ltdcp, cfgp); + osalSysUnlock(); +} + +/** @} */ + +/** + * @name LTDC foreground layer (layer 2) methods + * @{ + */ + +/** + * @brief Get foreground layer enabled flags. + * @details Returns all the flags of the LTDC_LEF_* group at once. + * Targeting the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled flags + * + * @iclass + */ +ltdc_flags_t ltdcFgGetEnableFlagsI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return LTDC_Layer2->CR & LTDC_LEF_MASK; +} + +/** + * @brief Get foreground layer enabled flags. + * @details Returns all the flags of the LTDC_LEF_* group at once. + * Targeting the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled flags + * + * @api + */ +ltdc_flags_t ltdcFgGetEnableFlags(LTDCDriver *ltdcp) { + + ltdc_flags_t flags; + osalSysLock(); + flags = ltdcFgGetEnableFlagsI(ltdcp); + osalSysUnlock(); + return flags; +} + +/** + * @brief Set foreground layer enabled flags. + * @details Sets all the flags of the LTDC_LEF_* group at once. + * Targeting the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] flags enabled flags + * + * @iclass + */ +void ltdcFgSetEnableFlagsI(LTDCDriver *ltdcp, ltdc_flags_t flags) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CR = (LTDC_Layer2->CR & ~LTDC_LEF_MASK) | + ((uint32_t)flags & LTDC_LEF_MASK); +} + +/** + * @brief Set foreground layer enabled flags. + * @details Sets all the flags of the LTDC_LEF_* group at once. + * Targeting the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] flags enabled flags + * + * @api + */ +void ltdcFgSetEnableFlags(LTDCDriver *ltdcp, ltdc_flags_t flags) { + + osalSysLock(); + ltdcFgSetEnableFlagsI(ltdcp, flags); + osalSysUnlock(); +} + +/** + * @brief Foreground layer enabled. + * @details Tells whether the foreground layer (layer 2) is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @iclass + */ +bool ltdcFgIsEnabledI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC_Layer2->CR & ~LTDC_LxCR_LEN) != 0; +} + +/** + * @brief Foreground layer enabled. + * @details Tells whether the foreground layer (layer 2) is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @api + */ +bool ltdcFgIsEnabled(LTDCDriver *ltdcp) { + + bool enabled; + osalSysLock(); + enabled = ltdcFgIsEnabledI(ltdcp); + osalSysUnlock(); + return enabled; +} + +/** + * @brief Foreground layer enable. + * @details Enables the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcFgEnableI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CR |= LTDC_LxCR_LEN; +} + +/** + * @brief Foreground layer enable. + * @details Enables the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcFgEnable(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcFgEnableI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Foreground layer disable. + * @details Disables the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcFgDisableI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CR &= ~LTDC_LxCR_LEN; +} + +/** + * @brief Foreground layer disable. + * @details Disables the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcFgDisable(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcFgDisableI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Foreground layer palette enabled. + * @details Tells whether the foreground layer (layer 2) palette (color lookup + * table) is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @iclass + */ +bool ltdcFgIsPaletteEnabledI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC_Layer2->CR & ~LTDC_LxCR_CLUTEN) != 0; +} + +/** + * @brief Foreground layer palette enabled. + * @details Tells whether the foreground layer (layer 2) palette (color lookup + * table) is enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @api + */ +bool ltdcFgIsPaletteEnabled(LTDCDriver *ltdcp) { + + bool enabled; + osalSysLock(); + enabled = ltdcFgIsPaletteEnabledI(ltdcp); + osalSysUnlock(); + return enabled; +} + +/** + * @brief Enable foreground layer palette. + * @details Enables the palette (color lookup table) of the foreground layer + * (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcFgEnablePaletteI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CR |= LTDC_LxCR_CLUTEN; +} + +/** + * @brief Enable foreground layer palette. + * @details Enables the palette (color lookup table) of the foreground layer + * (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcFgEnablePalette(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcFgEnablePaletteI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Disable foreground layer palette. + * @details Disables the palette (color lookup table) of the foreground layer + * (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcFgDisablePaletteI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CR &= ~LTDC_LxCR_CLUTEN; +} + +/** + * @brief Disable foreground layer palette. + * @details Disables the palette (color lookup table) of the foreground layer + * (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcFgDisablePalette(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcFgDisablePaletteI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Set foreground layer palette color. + * @details Sets the color of a palette (color lookup table) slot to the + * foreground layer (layer 2). + * @pre The layer must be disabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] slot palette slot + * @param[in] c color, RGB-888 + * + * @iclass + */ +void ltdcFgSetPaletteColorI(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgAssert(!ltdcFgIsEnabledI(ltdcp), "invalid state"); + (void)ltdcp; + + LTDC_Layer2->CLUTWR = ((uint32_t)slot << 24) | (c & 0x00FFFFFF); +} + +/** + * @brief Set foreground layer palette color. + * @details Sets the color of a palette (color lookup table) slot to the + * foreground layer (layer 2). + * @pre The layer must be disabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] slot palette slot + * @param[in] c color, RGB-888 + * + * @api + */ +void ltdcFgSetPaletteColor(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c) { + + osalSysLock(); + ltdcFgSetPaletteColorI(ltdcp, slot, c); + osalSysUnlock(); +} + +/** + * @brief Set foreground layer palette. + * @details Sets the entire palette color (color lookup table) slot. + * @pre The layer must be disabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] colors array of palette colors, RGB-888 + * @param[in] length number of palette colors + * + * @iclass + */ +void ltdcFgSetPaletteI(LTDCDriver *ltdcp, const ltdc_color_t colors[], + uint16_t length) { + + uint16_t i; + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck((colors == NULL) == (length == 0)); + osalDbgAssert(length <= LTDC_MAX_PALETTE_LENGTH, "bounds"); + osalDbgAssert(!ltdcFgIsEnabledI(ltdcp), "invalid state"); + (void)ltdcp; + + for (i = 0; i < length; ++i) + LTDC_Layer2->CLUTWR = ((uint32_t)i << 24) | (colors[i] & 0x00FFFFFF); +} + +/** + * @brief Set foreground layer palette. + * @details Sets the entire palette color (color lookup table) slot. + * @pre The layer must be disabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] colors array of palette colors, RGB-888 + * @param[in] length number of palette colors + * + * @api + */ +void ltdcFgSetPalette(LTDCDriver *ltdcp, const ltdc_color_t colors[], + uint16_t length) { + + osalSysLock(); + ltdcFgSetPaletteI(ltdcp, colors, length); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer pixel format. + * @details Gets the pixel format of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return pixel format + * + * @iclass + */ +ltdc_pixfmt_t ltdcFgGetPixelFormatI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_pixfmt_t)(LTDC_Layer2->PFCR & LTDC_LxPFCR_PF); +} + +/** + * @brief Get foreground layer pixel format. + * @details Gets the pixel format of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return pixel format + * + * @api + */ +ltdc_pixfmt_t ltdcFgGetPixelFormat(LTDCDriver *ltdcp) { + + ltdc_pixfmt_t fmt; + osalSysLock(); + fmt = ltdcFgGetPixelFormatI(ltdcp); + osalSysUnlock(); + return fmt; +} + +/** + * @brief Set foreground layer pixel format. + * @details Sets the pixel format of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] fmt pixel format + * + * @iclass + */ +void ltdcFgSetPixelFormatI(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgAssert(fmt >= LTDC_MIN_PIXFMT_ID, "bounds"); + osalDbgAssert(fmt <= LTDC_MAX_PIXFMT_ID, "bounds"); + (void)ltdcp; + + LTDC_Layer2->PFCR = (LTDC_Layer2->PFCR & ~LTDC_LxPFCR_PF) | + ((uint32_t)fmt & LTDC_LxPFCR_PF); +} + +/** + * @brief Set foreground layer pixel format. + * @details Sets the pixel format of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] fmt pixel format + * + * @api + */ +void ltdcFgSetPixelFormat(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt) { + + osalSysLock(); + ltdcFgSetPixelFormatI(ltdcp, fmt); + osalSysUnlock(); +} + +/** + * @brief Foreground layer color keying enabled. + * @details Tells whether the foreground layer (layer 2) has color keying + * enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @iclass + */ +bool ltdcFgIsKeyingEnabledI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (LTDC_Layer2->CR & ~LTDC_LxCR_COLKEN) != 0; +} + +/** + * @brief Foreground layer color keying enabled. + * @details Tells whether the foreground layer (layer 2) has color keying + * enabled. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return enabled + * + * @api + */ +bool ltdcFgIsKeyingEnabled(LTDCDriver *ltdcp) { + + bool enabled; + osalSysLock(); + enabled = ltdcFgIsKeyingEnabledI(ltdcp); + osalSysUnlock(); + return enabled; +} + +/** + * @brief Enable foreground layer color keying. + * @details Enables color keying capabilities of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcFgEnableKeyingI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CR |= LTDC_LxCR_COLKEN; +} + +/** + * @brief Enable foreground layer color keying. + * @details Enables color keying capabilities of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcFgEnableKeying(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcFgEnableKeyingI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Disable foreground layer color keying. + * @details Disables color keying capabilities of the foreground layer (layer + * 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcFgDisableKeyingI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CR &= ~LTDC_LxCR_COLKEN; +} + +/** + * @brief Disable foreground layer color keying. + * @details Disables color keying capabilities of the foreground layer (layer + * 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcFgDisableKeying(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcFgDisableKeyingI(ltdcp); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer color key. + * @details Gets the color key of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return color key, RGB-888 + * + * @iclass + */ +ltdc_color_t ltdcFgGetKeyingColorI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_color_t)(LTDC_Layer2->CKCR & 0x00FFFFFF); +} + +/** + * @brief Get foreground layer color key. + * @details Gets the color key of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return color key, RGB-888 + * + * @api + */ +ltdc_color_t ltdcFgGetKeyingColor(LTDCDriver *ltdcp) { + + ltdc_color_t color; + osalSysLock(); + color = ltdcFgGetKeyingColorI(ltdcp); + osalSysUnlock(); + return color; +} + +/** + * @brief Set foreground layer color key. + * @details Sets the color key of the foreground layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c color key, RGB-888 + * + * @iclass + */ +void ltdcFgSetKeyingColorI(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CKCR = (LTDC_Layer2->CKCR & ~0x00FFFFFF) | + ((uint32_t)c & 0x00FFFFFF); +} + +/** + * @brief Set foreground layer color key. + * @details Sets the color key of the foreground layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c color key, RGB-888 + * + * @api + */ +void ltdcFgSetKeyingColor(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalSysLock(); + ltdcFgSetKeyingColorI(ltdcp, c); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer constant alpha. + * @details Gets the constant alpha component of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return constant alpha component, A-8 + * + * @iclass + */ +uint8_t ltdcFgGetConstantAlphaI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (uint8_t)(LTDC_Layer2->CACR & LTDC_LxCACR_CONSTA); +} + +/** + * @brief Get foreground layer constant alpha. + * @details Gets the constant alpha component of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return constant alpha component, A-8 + * + * @api + */ +uint8_t ltdcFgGetConstantAlpha(LTDCDriver *ltdcp) { + + uint8_t a; + osalSysLock(); + a = ltdcFgGetConstantAlphaI(ltdcp); + osalSysUnlock(); + return a; +} + +/** + * @brief Set foreground layer constant alpha. + * @details Sets the constant alpha component of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] a constant alpha component, A-8 + * + * @iclass + */ +void ltdcFgSetConstantAlphaI(LTDCDriver *ltdcp, uint8_t a) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CACR = (LTDC_Layer2->CACR & ~LTDC_LxCACR_CONSTA) | + ((uint32_t)a & LTDC_LxCACR_CONSTA); +} + +/** + * @brief Set foreground layer constant alpha. + * @details Sets the constant alpha component of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] a constant alpha component, A-8 + * + * @api + */ +void ltdcFgSetConstantAlpha(LTDCDriver *ltdcp, uint8_t a) { + + osalSysLock(); + ltdcFgSetConstantAlphaI(ltdcp, a); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer default color. + * @details Gets the default color of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return default color, RGB-888 + * + * @iclass + */ +ltdc_color_t ltdcFgGetDefaultColorI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_color_t)LTDC_Layer2->DCCR; +} + +/** + * @brief Get foreground layer default color. + * @details Gets the default color of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return default color, RGB-888 + * + * @api + */ +ltdc_color_t ltdcFgGetDefaultColor(LTDCDriver *ltdcp) { + + ltdc_color_t color; + osalSysLock(); + color = ltdcFgGetDefaultColorI(ltdcp); + osalSysUnlock(); + return color; +} + +/** + * @brief Set foreground layer default color. + * @details Sets the default color of the foreground layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c default color, RGB-888 + * + * @iclass + */ +void ltdcFgSetDefaultColorI(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->DCCR = (uint32_t)c; +} + +/** + * @brief Set foreground layer default color. + * @details Sets the default color of the foreground layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] c default color, RGB-888 + * + * @api + */ +void ltdcFgSetDefaultColor(LTDCDriver *ltdcp, ltdc_color_t c) { + + osalSysLock(); + ltdcFgSetDefaultColorI(ltdcp, c); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer blending factors. + * @details Gets the blending factors of the foreground layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return blending factors + * + * @iclass + */ +ltdc_blendf_t ltdcFgGetBlendingFactorsI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (ltdc_blendf_t)(LTDC_Layer2->BFCR & LTDC_LxBFCR_BF); +} + +/** + * @brief Get foreground layer blending factors. + * @details Gets the blending factors of the foreground layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return blending factors + * + * @api + */ +ltdc_blendf_t ltdcFgGetBlendingFactors(LTDCDriver *ltdcp) { + + ltdc_blendf_t bf; + osalSysLock(); + bf = ltdcFgGetBlendingFactorsI(ltdcp); + osalSysUnlock(); + return bf; +} + +/** + * @brief Set foreground layer blending factors. + * @details Sets the blending factors of the foreground layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] factors blending factors + * + * @iclass + */ +void ltdcFgSetBlendingFactorsI(LTDCDriver *ltdcp, ltdc_blendf_t bf) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->BFCR = (LTDC_Layer2->BFCR & ~LTDC_LxBFCR_BF) | + ((uint32_t)bf & LTDC_LxBFCR_BF); +} + +/** + * @brief Set foreground layer blending factors. + * @details Sets the blending factors of the foreground layer (layer 1). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] factors blending factors + * + * @api + */ +void ltdcFgSetBlendingFactors(LTDCDriver *ltdcp, ltdc_blendf_t bf) { + + osalSysLock(); + ltdcFgSetBlendingFactorsI(ltdcp, bf); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer window specs. + * @details Gets the window specifications of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] windowp pointer to the window specifications + * + * @iclass + */ +void ltdcFgGetWindowI(LTDCDriver *ltdcp, ltdc_window_t *windowp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(windowp != NULL); + (void)ltdcp; + + windowp->hstart = + (uint16_t)((LTDC_Layer2->WHPCR & LTDC_LxWHPCR_WHSTPOS) >> 0); + windowp->hstop = + (uint16_t)((LTDC_Layer2->WHPCR & LTDC_LxWHPCR_WHSPPOS) >> 16); + windowp->vstart = + (uint16_t)((LTDC_Layer2->WVPCR & LTDC_LxWVPCR_WVSTPOS) >> 0); + windowp->vstop = + (uint16_t)((LTDC_Layer2->WVPCR & LTDC_LxWVPCR_WVSPPOS) >> 16); +} + +/** + * @brief Get foreground layer window specs. + * @details Gets the window specifications of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] windowp pointer to the window specifications + * + * @api + */ +void ltdcFgGetWindow(LTDCDriver *ltdcp, ltdc_window_t *windowp) { + + osalSysLock(); + ltdcFgGetWindowI(ltdcp, windowp); + osalSysUnlock(); +} + +/** + * @brief Set foreground layer window specs. + * @details Sets the window specifications of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] windowp pointer to the window specifications + * + * @iclass + */ +void ltdcFgSetWindowI(LTDCDriver *ltdcp, const ltdc_window_t *windowp) { + + uint32_t start, stop; + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(windowp != NULL); + (void)ltdcp; + + osalDbgAssert(windowp->hstop < ltdcp->config->screen_width, "bounds"); + osalDbgAssert(windowp->vstop < ltdcp->config->screen_height, "bounds"); + + /* Horizontal boundaries.*/ + start = (uint32_t)windowp->hstart + ltdcp->active_window.hstart; + stop = (uint32_t)windowp->hstop + ltdcp->active_window.hstart; + + osalDbgAssert(start >= ltdcp->active_window.hstart, "bounds"); + osalDbgAssert(stop <= ltdcp->active_window.hstop, "bounds"); + + LTDC_Layer2->WHPCR = ((start << 0) & LTDC_LxWHPCR_WHSTPOS) | + ((stop << 16) & LTDC_LxWHPCR_WHSPPOS); + + /* Vertical boundaries.*/ + start = (uint32_t)windowp->vstart + ltdcp->active_window.vstart; + stop = (uint32_t)windowp->vstop + ltdcp->active_window.vstart; + + osalDbgAssert(start >= ltdcp->active_window.vstart, "bounds"); + osalDbgAssert(stop <= ltdcp->active_window.vstop, "bounds"); + + LTDC_Layer2->WVPCR = ((start << 0) & LTDC_LxWVPCR_WVSTPOS) | + ((stop << 16) & LTDC_LxWVPCR_WVSPPOS); +} + +/** + * @brief Set foreground layer window specs. + * @details Sets the window specifications of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] windowp pointer to the window specifications + * + * @api + */ +void ltdcFgSetWindow(LTDCDriver *ltdcp, const ltdc_window_t *windowp) { + + osalSysLock(); + ltdcFgSetWindowI(ltdcp, windowp); + osalSysUnlock(); +} + +/** + * @brief Set foreground layer window as invalid. + * @details Sets the window specifications of the foreground layer (layer 2) + * so that the window is pixel sized at the screen origin. + * @note Useful before reconfiguring the frame specifications of the layer, + * to avoid errors. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @iclass + */ +void ltdcFgSetInvalidWindowI(LTDCDriver *ltdcp) { + + ltdcFgSetWindowI(ltdcp, <dc_invalid_window); +} + +/** + * @brief Set foreground layer window as invalid. + * @details Sets the window specifications of the foreground layer (layer 2) + * so that the window is pixel sized at the screen origin. + * @note Useful before reconfiguring the frame specifications of the layer, + * to avoid errors. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @api + */ +void ltdcFgSetInvalidWindow(LTDCDriver *ltdcp) { + + osalSysLock(); + ltdcFgSetWindowI(ltdcp, <dc_invalid_window); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer frame buffer specs. + * @details Gets the frame buffer specifications of the foreground layer + * (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] framep pointer to the frame buffer specifications + * + * @iclass + */ +void ltdcFgGetFrameI(LTDCDriver *ltdcp, ltdc_frame_t *framep) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(framep != NULL); + + framep->bufferp = (void *)(LTDC_Layer2->CFBAR & LTDC_LxCFBAR_CFBADD); + framep->pitch = (size_t)((LTDC_Layer2->CFBLR & LTDC_LxCFBLR_CFBP) >> 16); + framep->width = (uint16_t)(((LTDC_Layer2->CFBLR & LTDC_LxCFBLR_CFBLL) - 3) / + ltdcBytesPerPixel(ltdcFgGetPixelFormatI(ltdcp))); + framep->height = (uint16_t)(LTDC_Layer2->CFBLNR & LTDC_LxCFBLNR_CFBLNBR); +} + +/** + * @brief Get foreground layer frame buffer specs. + * @details Gets the frame buffer specifications of the foreground layer + * (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] framep pointer to the frame buffer specifications + * + * @api + */ +void ltdcFgGetFrame(LTDCDriver *ltdcp, ltdc_frame_t *framep) { + + osalSysLock(); + ltdcFgGetFrameI(ltdcp, framep); + osalSysUnlock(); +} + +/** + * @brief Set foreground layer frame buffer specs. + * @details Sets the frame buffer specifications of the foreground layer + * (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] framep pointer to the frame buffer specifications + * + * @iclass + */ +void ltdcFgSetFrameI(LTDCDriver *ltdcp, const ltdc_frame_t *framep) { + + size_t linesize; + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(framep != NULL); + + ltdcFgSetPixelFormatI(ltdcp, framep->fmt); + + linesize = ltdcBytesPerPixel(framep->fmt) * framep->width; + + osalDbgAssert(framep->width <= ltdcp->config->screen_width, "bounds"); + osalDbgAssert(framep->height <= ltdcp->config->screen_height, "bounds"); + osalDbgAssert(linesize >= LTDC_MIN_FRAME_WIDTH_BYTES, "bounds"); + osalDbgAssert(linesize <= LTDC_MAX_FRAME_WIDTH_BYTES, "bounds"); + osalDbgAssert(framep->height >= LTDC_MIN_FRAME_HEIGHT_LINES, "bounds"); + osalDbgAssert(framep->height <= LTDC_MAX_FRAME_HEIGHT_LINES, "bounds"); + osalDbgAssert(framep->pitch >= linesize, "bounds"); + + LTDC_Layer2->CFBAR = (uint32_t)framep->bufferp & LTDC_LxCFBAR_CFBADD; + LTDC_Layer2->CFBLR = ((((uint32_t)framep->pitch << 16) & LTDC_LxCFBLR_CFBP) | + ((linesize + 3) & LTDC_LxCFBLR_CFBLL)); + LTDC_Layer2->CFBLNR = (uint32_t)framep->height & LTDC_LxCFBLNR_CFBLNBR; +} + +/** + * @brief Set foreground layer frame buffer specs. + * @details Sets the frame buffer specifications of the foreground layer + * (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] framep pointer to the frame buffer specifications + * + * @api + */ +void ltdcFgSetFrame(LTDCDriver *ltdcp, const ltdc_frame_t *framep) { + + osalSysLock(); + ltdcFgSetFrameI(ltdcp, framep); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer frame buffer address. + * @details Gets the frame buffer address of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return frame buffer address + * + * @iclass + */ +void *ltdcFgGetFrameAddressI(LTDCDriver *ltdcp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + return (void *)LTDC_Layer2->CFBAR; +} + +/** + * @brief Get foreground layer frame buffer address. + * @details Gets the frame buffer address of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * + * @return frame buffer address + * + * @api + */ +void *ltdcFgGetFrameAddress(LTDCDriver *ltdcp) { + + void *bufferp; + osalSysLock(); + bufferp = ltdcFgGetFrameAddressI(ltdcp); + osalSysUnlock(); + return bufferp; +} + +/** + * @brief Set foreground layer frame buffer address. + * @details Sets the frame buffer address of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] bufferp frame buffer address + * + * @iclass + */ +void ltdcFgSetFrameAddressI(LTDCDriver *ltdcp, void *bufferp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + (void)ltdcp; + + LTDC_Layer2->CFBAR = (uint32_t)bufferp; +} + +/** + * @brief Set foreground layer frame buffer address. + * @details Sets the frame buffer address of the foreground layer (layer 2). + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] bufferp frame buffer address + * + * @api + */ +void ltdcFgSetFrameAddress(LTDCDriver *ltdcp, void *bufferp) { + + osalSysLock(); + ltdcFgSetFrameAddressI(ltdcp, bufferp); + osalSysUnlock(); +} + +/** + * @brief Get foreground layer specifications. + * @details Gets the foreground layer (layer 2) specifications at once. + * @note If palette specifications cannot be retrieved, they are set to + * @p NULL. This is not an error. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @iclass + */ +void ltdcFgGetLayerI(LTDCDriver *ltdcp, ltdc_laycfg_t *cfgp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + osalDbgCheck(cfgp != NULL); + + ltdcFgGetFrameI(ltdcp, (ltdc_frame_t *)cfgp->frame); + ltdcFgGetWindowI(ltdcp, (ltdc_window_t *)cfgp->window); + cfgp->def_color = ltdcFgGetDefaultColorI(ltdcp); + cfgp->key_color = ltdcFgGetKeyingColorI(ltdcp); + cfgp->const_alpha = ltdcFgGetConstantAlphaI(ltdcp); + cfgp->blending = ltdcFgGetBlendingFactorsI(ltdcp); + + cfgp->pal_colors = NULL; + cfgp->pal_length = 0; + + cfgp->flags = ltdcFgGetEnableFlagsI(ltdcp); +} + +/** + * @brief Get foreground layer specifications. + * @details Gets the foreground layer (layer 2) specifications at once. + * @note If palette specifications cannot be retrieved, they are set to + * @p NULL. This is not an error. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[out] cfgp pointer to the layer specifications + * + * @api + */ +void ltdcFgGetLayer(LTDCDriver *ltdcp, ltdc_laycfg_t *cfgp) { + + osalSysLock(); + ltdcFgGetLayerI(ltdcp, cfgp); + osalSysUnlock(); +} + +/** + * @brief Set foreground layer specifications. + * @details Sets the foreground layer (layer 2) specifications at once. + * @note If the palette is unspecified, the layer palette is unmodified. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @iclass + */ +void ltdcFgSetConfigI(LTDCDriver *ltdcp, const ltdc_laycfg_t *cfgp) { + + osalDbgCheckClassI(); + osalDbgCheck(ltdcp == <DCD1); + + if (cfgp == NULL) + cfgp = <dc_default_laycfg; + + osalDbgCheck((cfgp->pal_colors == NULL) == (cfgp->pal_length == 0)); + + ltdcFgSetFrameI(ltdcp, cfgp->frame); + ltdcFgSetWindowI(ltdcp, cfgp->window); + ltdcFgSetDefaultColorI(ltdcp, cfgp->def_color); + ltdcFgSetKeyingColorI(ltdcp, cfgp->key_color); + ltdcFgSetConstantAlphaI(ltdcp, cfgp->const_alpha); + ltdcFgSetBlendingFactorsI(ltdcp, cfgp->blending); + + if (cfgp->pal_length > 0) + ltdcFgSetPaletteI(ltdcp, cfgp->pal_colors, cfgp->pal_length); + + ltdcFgSetEnableFlagsI(ltdcp, cfgp->flags); +} + +/** + * @brief Set foreground layer specifications. + * @details Sets the foreground layer (layer 2) specifications at once. + * @note If the palette is unspecified, the layer palette is unmodified. + * + * @param[in] ltdcp pointer to the @p LTDCDriver object + * @param[in] cfgp pointer to the layer specifications + * + * @api + */ +void ltdcFgSetConfig(LTDCDriver *ltdcp, const ltdc_laycfg_t *cfgp) { + + osalSysLock(); + ltdcFgSetConfigI(ltdcp, cfgp); + osalSysUnlock(); +} + +/** @} */ + +/** + * @name LTDC helper functions + */ + +/** + * @brief Compute bits per pixel. + * @details Computes the bits per pixel for the specified pixel format. + * + * @param[in] fmt pixel format + * + * @retuen bits per pixel + * + * @api + */ +size_t ltdcBitsPerPixel(ltdc_pixfmt_t fmt) { + + osalDbgAssert(fmt < LTDC_MAX_PIXFMT_ID, "invalid format"); + + return (size_t)ltdc_bpp[(unsigned)fmt]; +} + +#if (TRUE == LTDC_USE_SOFTWARE_CONVERSIONS) || defined(__DOXYGEN__) + +/** + * @brief Convert from ARGB-8888. + * @details Converts an ARGB-8888 color to the specified pixel format. + * + * @param[in] c color, ARGB-8888 + * @param[in] fmt target pixel format + * + * @return raw color value for the target pixel format, left + * padded with zeros. + * + * @api + */ +ltdc_color_t ltdcFromARGB8888(ltdc_color_t c, ltdc_pixfmt_t fmt) { + + switch (fmt) { + case LTDC_FMT_ARGB8888: { + return c; + } + case LTDC_FMT_RGB888: { + return c & 0x00FFFFFF; + } + case LTDC_FMT_RGB565: { + return ((c & 0x000000F8) >> ( 8 - 5)) | + ((c & 0x0000FC00) >> (16 - 11)) | + ((c & 0x00F80000) >> (24 - 16)); + } + case LTDC_FMT_ARGB1555: { + return ((c & 0x000000F8) >> ( 8 - 5)) | + ((c & 0x0000F800) >> (16 - 10)) | + ((c & 0x00F80000) >> (24 - 15)) | + ((c & 0x80000000) >> (32 - 16)); + } + case LTDC_FMT_ARGB4444: { + return ((c & 0x000000F0) >> ( 8 - 4)) | + ((c & 0x0000F000) >> (16 - 8)) | + ((c & 0x00F00000) >> (24 - 12)) | + ((c & 0xF0000000) >> (32 - 16)); + } + case LTDC_FMT_L8: { + return c & 0x000000FF; + } + case LTDC_FMT_AL44: { + return ((c & 0x000000F0) >> ( 8 - 4)) | + ((c & 0xF0000000) >> (32 - 8)); + } + case LTDC_FMT_AL88: { + return ((c & 0x000000FF) >> ( 8 - 8)) | + ((c & 0xFF000000) >> (32 - 16)); + } + default: + osalDbgAssert(false, "invalid format"); + return 0; + } +} + +/** + * @brief Convert to ARGB-8888. + * @details Converts color of the specified pixel format to an ARGB-8888 color. + * + * @param[in] c color for the source pixel format, left padded with + * zeros. + * @param[in] fmt source pixel format + * + * @return color in ARGB-8888 format + * + * @api + */ +ltdc_color_t ltdcToARGB8888(ltdc_color_t c, ltdc_pixfmt_t fmt) { + + switch (fmt) { + case LTDC_FMT_ARGB8888: { + return c; + } + case LTDC_FMT_RGB888: { + return (c & 0x00FFFFFF) | 0xFF000000; + } + case LTDC_FMT_RGB565: { + register ltdc_color_t output = 0xFF000000; + if (c & 0x001F) output |= ((c & 0x001F) << ( 8 - 5)) | 0x00000007; + if (c & 0x07E0) output |= ((c & 0x07E0) << (16 - 11)) | 0x00000300; + if (c & 0xF800) output |= ((c & 0xF800) << (24 - 16)) | 0x00070000; + return output; + } + case LTDC_FMT_ARGB1555: { + register ltdc_color_t output = 0x00000000; + if (c & 0x001F) output |= ((c & 0x001F) << ( 8 - 5)) | 0x00000007; + if (c & 0x03E0) output |= ((c & 0x03E0) << (16 - 10)) | 0x00000700; + if (c & 0x7C00) output |= ((c & 0x7C00) << (24 - 15)) | 0x00070000; + if (c & 0x8000) output |= 0xFF000000; + return output; + } + case LTDC_FMT_ARGB4444: { + register ltdc_color_t output = 0x00000000; + if (c & 0x000F) output |= ((c & 0x000F) << ( 8 - 4)) | 0x0000000F; + if (c & 0x00F0) output |= ((c & 0x00F0) << (16 - 8)) | 0x00000F00; + if (c & 0x0F00) output |= ((c & 0x0F00) << (24 - 12)) | 0x000F0000; + if (c & 0xF000) output |= ((c & 0xF000) << (32 - 16)) | 0x0F000000; + return output; + } + case LTDC_FMT_L8: { + return (c & 0xFF) | 0xFF000000; + } + case LTDC_FMT_AL44: { + register ltdc_color_t output = 0x00000000; + if (c & 0x0F) output |= ((c & 0x0F) << ( 8 - 4)) | 0x0000000F; + if (c & 0xF0) output |= ((c & 0xF0) << (32 - 8)) | 0x0F000000; + return output; + } + case LTDC_FMT_AL88: { + return ((c & 0x00FF) << ( 8 - 8)) | + ((c & 0xFF00) << (32 - 16)); + } + default: + osalDbgAssert(false, "invalid format"); + return 0; + } +} + +#endif /* LTDC_USE_SOFTWARE_CONVERSIONS */ + +/** @} */ + +/** @} */ + +#endif /* STM32_LTDC_USE_LTDC */ diff --git a/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h new file mode 100644 index 0000000..a221c79 --- /dev/null +++ b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h @@ -0,0 +1,770 @@ +/* + Copyright (C) 2013-2015 Andrea Zoppi + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file stm32_ltdc.h + * @brief LCD-TFT Controller Driver. + * + * @addtogroup ltdc + * @{ + */ + +#ifndef _STM32_LTDC_H_ +#define _STM32_LTDC_H_ + +/** + * @brief Using the LTDC driver. + */ +#if !defined(STM32_LTDC_USE_LTDC) || defined(__DOXYGEN__) +#define STM32_LTDC_USE_LTDC FALSE +#endif + +#if (TRUE == STM32_LTDC_USE_LTDC) || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name LTDC enable flags + * @{ + */ +#define LTDC_EF_ENABLE (1 << 0) /**< LTDC enabled.*/ +#define LTDC_EF_DITHER (1 << 16) /**< Dithering enabled.*/ +#define LTDC_EF_PIXCLK_INVERT (1 << 28) /**< Inverted pixel clock.*/ +#define LTDC_EF_DATAEN_HIGH (1 << 29) /**< Active-high data enable.*/ +#define LTDC_EF_VSYNC_HIGH (1 << 30) /**< Active-high vsync.*/ +#define LTDC_EF_HSYNC_HIGH (1 << 31) /**< Active-high hsync.*/ + +#define LTDC_EF_MASK \ + (LTDC_EF_ENABLE | LTDC_EF_DITHER | LTDC_EF_PIXCLK_INVERT | \ + LTDC_EF_DATAEN_HIGH | LTDC_EF_VSYNC_HIGH | LTDC_EF_HSYNC_HIGH) +/** @} */ + +/** + * @name LTDC layer enable flags + * @{ + */ +#define LTDC_LEF_ENABLE (1 << 0) /**< Layer enabled*/ +#define LTDC_LEF_KEYING (1 << 1) /**< Color keying enabled.*/ +#define LTDC_LEF_PALETTE (1 << 4) /**< Palette enabled.*/ + +#define LTDC_LEF_MASK \ + (LTDC_LEF_ENABLE | LTDC_LEF_KEYING | LTDC_LEF_PALETTE) +/** @} */ + +/** + * @name LTDC pixel formats + * @{ + */ +#define LTDC_FMT_ARGB8888 0 /**< ARGB-8888 format.*/ +#define LTDC_FMT_RGB888 1 /**< RGB-888 format.*/ +#define LTDC_FMT_RGB565 2 /**< RGB-565 format.*/ +#define LTDC_FMT_ARGB1555 3 /**< ARGB-1555 format.*/ +#define LTDC_FMT_ARGB4444 4 /**< ARGB-4444 format.*/ +#define LTDC_FMT_L8 5 /**< L-8 format.*/ +#define LTDC_FMT_AL44 6 /**< AL-44 format.*/ +#define LTDC_FMT_AL88 7 /**< AL-88 format.*/ +/** @} */ + +/** + * @name LTDC pixel format aliased raw masks + * @{ + */ +#define LTDC_XMASK_ARGB8888 0xFFFFFFFF /**< ARGB-8888 aliased mask.*/ +#define LTDC_XMASK_RGB888 0x00FFFFFF /**< RGB-888 aliased mask.*/ +#define LTDC_XMASK_RGB565 0x00F8FCF8 /**< RGB-565 aliased mask.*/ +#define LTDC_XMASK_ARGB1555 0x80F8F8F8 /**< ARGB-1555 aliased mask.*/ +#define LTDC_XMASK_ARGB4444 0xF0F0F0F0 /**< ARGB-4444 aliased mask.*/ +#define LTDC_XMASK_L8 0x000000FF /**< L-8 aliased mask.*/ +#define LTDC_XMASK_AL44 0xF00000F0 /**< AL-44 aliased mask.*/ +#define LTDC_XMASK_AL88 0xFF0000FF /**< AL-88 aliased mask.*/ +/** @} */ + +/** + * @name LTDC blending factors + * @{ + */ +#define LTDC_BLEND_FIX1_FIX2 0x0405 /**< cnst1; 1 - cnst2 */ +#define LTDC_BLEND_FIX1_MOD2 0x0407 /**< cnst1; 1 - a2 * cnst2 */ +#define LTDC_BLEND_MOD1_FIX2 0x0605 /**< a1 * cnst1; 1 - cnst2 */ +#define LTDC_BLEND_MOD1_MOD2 0x0607 /**< a1 * cnst1; 1 - a2 * cnst2 */ +/** @} */ + +/** + * @name LTDC parameter bounds + * @{ + */ + +#define LTDC_MIN_SCREEN_WIDTH 1 +#define LTDC_MIN_SCREEN_HEIGHT 1 +#define LTDC_MAX_SCREEN_WIDTH 800 +#define LTDC_MAX_SCREEN_HEIGHT 600 + +#define LTDC_MIN_HSYNC_WIDTH 1 +#define LTDC_MIN_VSYNC_HEIGHT 1 +#define LTDC_MAX_HSYNC_WIDTH (1 << 12) +#define LTDC_MAX_VSYNC_HEIGHT (1 << 11) + +#define LTDC_MIN_HBP_WIDTH 0 +#define LTDC_MIN_VBP_HEIGHT 0 +#define LTDC_MAX_HBP_WIDTH (1 << 12) +#define LTDC_MAX_VBP_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_HBP_WIDTH 1 +#define LTDC_MIN_ACC_VBP_HEIGHT 1 +#define LTDC_MAX_ACC_HBP_WIDTH (1 << 12) +#define LTDC_MAX_ACC_VBP_HEIGHT (1 << 11) + +#define LTDC_MIN_HFP_WIDTH 0 +#define LTDC_MIN_VFP_HEIGHT 0 +#define LTDC_MAX_HFP_WIDTH (1 << 12) +#define LTDC_MAX_VFP_HEIGHT (1 << 11) + +#define LTDC_MIN_ACTIVE_WIDTH 0 +#define LTDC_MIN_ACTIVE_HEIGHT 0 +#define LTDC_MAX_ACTIVE_WIDTH (1 << 12) +#define LTDC_MAX_ACTIVE_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_ACTIVE_WIDTH 1 +#define LTDC_MIN_ACC_ACTIVE_HEIGHT 1 +#define LTDC_MAX_ACC_ACTIVE_WIDTH (1 << 12) +#define LTDC_MAX_ACC_ACTIVE_HEIGHT (1 << 11) + +#define LTDC_MIN_ACC_TOTAL_WIDTH 1 +#define LTDC_MIN_ACC_TOTAL_HEIGHT 1 +#define LTDC_MAX_ACC_TOTAL_WIDTH (1 << 12) +#define LTDC_MAX_ACC_TOTAL_HEIGHT (1 << 11) + +#define LTDC_MIN_LINE_INTERRUPT_POS 0 +#define LTDC_MAX_LINE_INTERRUPT_POS ((1 << 11) - 1) + +#define LTDC_MIN_WINDOW_HSTART 0 +#define LTDC_MIN_WINDOW_HSTART 0 +#define LTDC_MAX_WINDOW_HSTOP ((1 << 12) - 1) +#define LTDC_MAX_WINDOW_HSTOP ((1 << 12) - 1) + +#define LTDC_MIN_WINDOW_VSTART 0 +#define LTDC_MIN_WINDOW_VSTART 0 +#define LTDC_MAX_WINDOW_VSTOP ((1 << 11) - 1) +#define LTDC_MAX_WINDOW_VSTOP ((1 << 11) - 1) + +#define LTDC_MIN_FRAME_WIDTH_BYTES 0 +#define LTDC_MIN_FRAME_HEIGHT_LINES 0 +#define LTDC_MIN_FRAME_PITCH_BYTES 0 +#define LTDC_MAX_FRAME_WIDTH_BYTES ((1 << 13) - 1 - 3) +#define LTDC_MAX_FRAME_HEIGHT_LINES ((1 << 11) - 1) +#define LTDC_MAX_FRAME_PITCH_BYTES ((1 << 13) - 1) + +#define LTDC_MIN_PIXFMT_ID 0 +#define LTDC_MAX_PIXFMT_ID 7 + +#define LTDC_MAX_PALETTE_LENGTH 256 + +/** @} */ + +/** + * @name LTDC basic ARGB-8888 colors. + * @{ + */ +/* Microsoft Windows default 16-color palette.*/ +#define LTDC_COLOR_BLACK 0xFF000000 +#define LTDC_COLOR_MAROON 0xFF800000 +#define LTDC_COLOR_GREEN 0xFF008000 +#define LTDC_COLOR_OLIVE 0xFF808000 +#define LTDC_COLOR_NAVY 0xFF000080 +#define LTDC_COLOR_PURPLE 0xFF800080 +#define LTDC_COLOR_TEAL 0xFF008080 +#define LTDC_COLOR_SILVER 0xFFC0C0C0 +#define LTDC_COLOR_GRAY 0xFF808080 +#define LTDC_COLOR_RED 0xFFFF0000 +#define LTDC_COLOR_LIME 0xFF00FF00 +#define LTDC_COLOR_YELLOW 0xFFFFFF00 +#define LTDC_COLOR_BLUE 0xFF0000FF +#define LTDC_COLOR_FUCHSIA 0xFFFF00FF +#define LTDC_COLOR_AQUA 0xFF00FFFF +#define LTDC_COLOR_WHITE 0xFFFFFFFF +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/* + * These definitions should already be defined by stm32_isr.h + */ +#if !defined(STM32_LTDC_EV_NUMBER) && !defined(__DOXYGEN__) +#define STM32_LTDC_EV_NUMBER LTDC_IRQn +#endif + +#if !defined(STM32_LTDC_ER_NUMBER) && !defined(__DOXYGEN__) +#define STM32_LTDC_ER_NUMBER LTDC_ER_IRQn +#endif + +/* + * These definitions should already be defined by hal_lld.h + */ +#if !defined(STM32_LTDC_EV_HANDLER) && !defined(__DOXYGEN__) +#define STM32_LTDC_EV_HANDLER Vector1A0 +#endif + +#if !defined(STM32_LTDC_ER_HANDLER) && !defined(__DOXYGEN__) +#define STM32_LTDC_ER_HANDLER Vector1A4 +#endif + +#if !defined(STM32_HAS_LTDC) && !defined(__DOXYGEN__) +#ifdef STM32F429_439xx +#define STM32_HAS_LTDC TRUE +#else +#define STM32_HAS_LTDC FALSE +#endif +#endif + +/** + * @name LTDC configuration options + * @{ + */ + +/** + * @brief LTDC event interrupt priority level setting. + */ +#if !defined(STM32_LTDC_EV_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_LTDC_EV_IRQ_PRIORITY 11 +#endif + +/** + * @brief LTDC error interrupt priority level setting. + */ +#if !defined(STM32_LTDC_ER_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define STM32_LTDC_ER_IRQ_PRIORITY 11 +#endif + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(LTDC_USE_WAIT) || defined(__DOXYGEN__) +#define LTDC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p ltdcAcquireBus() and @p ltdcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(LTDC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define LTDC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/** + * @brief Provides software color conversion functions. + * @note Disabling this option saves both code and data space. + */ +#if !defined(LTDC_USE_SOFTWARE_CONVERSIONS) || defined(__DOXYGEN__) +#define LTDC_USE_SOFTWARE_CONVERSIONS TRUE +#endif + +/** + * @brief Enables checks for LTDC functions. + * @note Disabling this option saves both code and data space. + * @note Disabling checks by ChibiOS will automatically disable LTDC checks. + */ +#if !defined(LTDC_USE_CHECKS) || defined(__DOXYGEN__) +#define LTDC_USE_CHECKS TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#ifndef STM32F429_439xx +#error "Currently only STM32F429xx and STM32F439xx are supported" +#endif + +#if (TRUE != STM32_HAS_LTDC) +#error "LTDC must be present when using the LTDC subsystem" +#endif + +#if (TRUE == STM32_LTDC_USE_LTDC) && (TRUE != STM32_HAS_LTDC) +#error "LTDC not present in the selected device" +#endif + +#if (TRUE == LTDC_USE_MUTUAL_EXCLUSION) +#if (TRUE != CH_CFG_USE_MUTEXES) && (TRUE != CH_CFG_USE_SEMAPHORES) +#error "LTDC_USE_MUTUAL_EXCLUSION requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES" +#endif +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/* Complex types forwarding.*/ +typedef union ltdc_coloralias_t ltdc_coloralias_t; +typedef struct ltdc_window_t ltdc_window_t; +typedef struct ltdc_frame_t ltdc_frame_t; +typedef struct ltdc_laycfg_t ltdc_laycfg_t; +typedef struct LTDCConfig LTDCConfig; +typedef enum ltdc_state_t ltdc_state_t; +typedef struct LTDCDriver LTDCDriver; + +/** + * @name LTDC Data types + * @{ + */ + +/** + * @brief LTDC generic color. + */ +typedef uint32_t ltdc_color_t; + +/** + * @brief LTDC color aliases. + * @detail Mapped with ARGB-8888, except for luminance (L mapped onto B). + * Padding fields prefixed with 'x', which should be clear + * (all 0) before compression and set (all 1) after expansion. + */ +typedef union ltdc_coloralias_t { + struct { + unsigned b : 8; + unsigned g : 8; + unsigned r : 8; + unsigned a : 8; + } argb8888; /**< Mapped ARGB-8888 bits.*/ + struct { + unsigned b : 8; + unsigned g : 8; + unsigned r : 8; + unsigned xa : 8; + } rgb888; /**< Mapped RGB-888 bits.*/ + struct { + unsigned xb : 3; + unsigned b : 5; + unsigned xg : 2; + unsigned g : 6; + unsigned xr : 3; + unsigned r : 5; + unsigned xa : 8; + } rgb565; /**< Mapped RGB-565 bits.*/ + struct { + unsigned xb : 3; + unsigned b : 5; + unsigned xg : 3; + unsigned g : 5; + unsigned xr : 3; + unsigned r : 5; + unsigned xa : 7; + unsigned a : 1; + } argb1555; /**< Mapped ARGB-1555 values.*/ + struct { + unsigned xb : 4; + unsigned b : 4; + unsigned xg : 4; + unsigned g : 4; + unsigned xr : 4; + unsigned r : 4; + unsigned xa : 4; + unsigned a : 4; + } argb4444; /**< Mapped ARGB-4444 values.*/ + struct { + unsigned l : 8; + unsigned x : 16; + unsigned xa : 8; + } l8; /**< Mapped L-8 bits.*/ + struct { + unsigned xl : 4; + unsigned l : 4; + unsigned x : 16; + unsigned xa : 4; + unsigned a : 4; + } al44; /**< Mapped AL-44 bits.*/ + struct { + unsigned l : 8; + unsigned x : 16; + unsigned a : 8; + } al88; /**< Mapped AL-88 bits.*/ + ltdc_color_t aliased; /**< Aliased raw bits.*/ +} ltdc_coloralias_t; + +/** + * @brief LTDC layer identifier. + */ +typedef uint32_t ltdc_layerid_t; + +/** + * @brief LTDC pixel format. + */ +typedef uint32_t ltdc_pixfmt_t; + +/** + * @brief LTDC blending factor. + */ +typedef uint32_t ltdc_blendf_t; + +/** + * @brief LTDC ISR callback. + */ +typedef void (*ltdc_isrcb_t)(LTDCDriver *ltdcp); + +/** + * @brief LTDC window specifications. + */ +typedef struct ltdc_window_t { + uint16_t hstart; /**< Horizontal start pixel (left).*/ + uint16_t hstop; /**< Horizontal stop pixel (right).*/ + uint16_t vstart; /**< Vertical start pixel (top).*/ + uint16_t vstop; /**< Vertical stop pixel (bottom).*/ +} ltdc_window_t; + +/** + * @brief LTDC frame specifications. + */ +typedef struct ltdc_frame_t { + void *bufferp; /**< Frame buffer address.*/ + uint16_t width; /**< Frame width, in pixels.*/ + uint16_t height; /**< Frame height, in pixels.*/ + size_t pitch; /**< Line pitch, in bytes.*/ + ltdc_pixfmt_t fmt; /**< Pixel format.*/ +} ltdc_frame_t; + +/** + * @brief LTDC configuration flags. + */ +typedef uint8_t ltdc_flags_t; + +/** + * @brief LTDC startup layer configuration. + */ +typedef struct ltdc_laycfg_t { + const ltdc_frame_t *frame; /**< Frame buffer specifications.*/ + const ltdc_window_t *window; /**< Window specifications.*/ + ltdc_color_t def_color; /**< Default color, ARGB-8888.*/ + uint8_t const_alpha; /**< Constant alpha factor.*/ + ltdc_color_t key_color; /**< Color key.*/ + const ltdc_color_t *pal_colors; /**< Palette colors, or @p NULL.*/ + uint16_t pal_length; /**< Palette length, or @p 0.*/ + ltdc_blendf_t blending; /**< Blending factors.*/ + ltdc_flags_t flags; /**< Layer configuration flags.*/ +} ltdc_laycfg_t; + +/** + * @brief LTDC driver configuration. + */ +typedef struct LTDCConfig { + /* Display specifications.*/ + uint16_t screen_width; /**< Screen pixel width.*/ + uint16_t screen_height; /**< Screen pixel height.*/ + uint16_t hsync_width; /**< Horizontal sync pixel width.*/ + uint16_t vsync_height; /**< Vertical sync pixel height.*/ + uint16_t hbp_width; /**< Horizontal back porch pixel width.*/ + uint16_t vbp_height; /**< Vertical back porch pixel height.*/ + uint16_t hfp_width; /**< Horizontal front porch pixel width.*/ + uint16_t vfp_height; /**< Vertical front porch pixel height.*/ + ltdc_flags_t flags; /**< Driver configuration flags.*/ + + /* ISR callbacks.*/ + ltdc_isrcb_t line_isr; /**< Line Interrupt ISR, or @p NULL.*/ + ltdc_isrcb_t rr_isr; /**< Register Reload ISR, or @p NULL.*/ + ltdc_isrcb_t fuerr_isr; /**< FIFO Underrun ISR, or @p NULL.*/ + ltdc_isrcb_t terr_isr; /**< Transfer Error ISR, or @p NULL.*/ + + /* Layer and color settings.*/ + ltdc_color_t clear_color; /**< Clear screen color, RGB-888.*/ + const ltdc_laycfg_t *bg_laycfg; /**< Background layer specs, or @p NULL.*/ + const ltdc_laycfg_t *fg_laycfg; /**< Foreground layer specs, or @p NULL.*/ +} LTDCConfig; + +/** + * @brief LTDC driver state. + */ +typedef enum ltdc_state_t { + LTDC_UNINIT = 0, /**< Not initialized.*/ + LTDC_STOP = 1, /**< Stopped.*/ + LTDC_READY = 2, /**< Ready.*/ + LTDC_ACTIVE = 3, /**< Executing commands.*/ +} ltdc_state_t; + +/** + * @brief LTDC driver. + */ +typedef struct LTDCDriver { + ltdc_state_t state; /**< Driver state.*/ + const LTDCConfig *config; /**< Driver configuration.*/ + + /* Handy computations.*/ + ltdc_window_t active_window; /**< Active window coordinates.*/ + + /* Multithreading stuff.*/ +#if (TRUE == LTDC_USE_WAIT) || defined(__DOXYGEN__) + thread_t *thread; /**< Waiting thread.*/ +#endif /* LTDC_USE_WAIT */ +#if (TRUE == LTDC_USE_MUTUAL_EXCLUSION) +#if (TRUE == CH_CFG_USE_MUTEXES) + mutex_t lock; /**< Multithreading lock.*/ +#elif (TRUE == CH_CFG_USE_SEMAPHORES) + semaphore_t lock; /**< Multithreading lock.*/ +#endif +#endif /* LTDC_USE_MUTUAL_EXCLUSION */ +} LTDCDriver; + +/** @} */ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Makes an ARGB-8888 value from byte components. + * + * @param[in] a alpha byte component + * @param[in] r red byte component + * @param[in] g green byte component + * @param[in] b blue byte component + * + * @return color in ARGB-8888 format + * + * @api + */ +#define ltdcMakeARGB8888(a, r, g, b) \ + ((((ltdc_color_t)(a) & 0xFF) << 24) | \ + (((ltdc_color_t)(r) & 0xFF) << 16) | \ + (((ltdc_color_t)(g) & 0xFF) << 8) | \ + (((ltdc_color_t)(b) & 0xFF) << 0)) + +/** + * @brief Compute bytes per pixel. + * @details Computes the bytes per pixel for the specified pixel format. + * Rounds to the ceiling. + * + * @param[in] fmt pixel format + * + * @return bytes per pixel + * + * @api + */ +#define ltdcBytesPerPixel(fmt) \ + ((ltdcBitsPerPixel(fmt) + 7) >> 3) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern LTDCDriver LTDCD1; + +#ifdef __cplusplus +extern "C" { +#endif + /* Driver methods.*/ + void ltdcInit(void); + void ltdcObjectInit(LTDCDriver *ltdcp); + ltdc_state_t ltdcGetStateI(LTDCDriver *ltdcp); + ltdc_state_t ltdcGetState(LTDCDriver *ltdcp); + void ltdcStart(LTDCDriver *ltdcp, const LTDCConfig *configp); + void ltdcStop(LTDCDriver *ltdcp); +#if (TRUE == LTDC_USE_MUTUAL_EXCLUSION) + void ltdcAcquireBusS(LTDCDriver *ltdcp); + void ltdcAcquireBus(LTDCDriver *ltdcp); + void ltdcReleaseBusS(LTDCDriver *ltdcp); + void ltdcReleaseBus(LTDCDriver *ltdcp); +#endif /* LTDC_USE_MUTUAL_EXCLUSION */ + + /* Global methods.*/ + ltdc_flags_t ltdcGetEnableFlagsI(LTDCDriver *ltdcp); + ltdc_flags_t ltdcGetEnableFlags(LTDCDriver *ltdcp); + void ltdcSetEnableFlagsI(LTDCDriver *ltdcp, ltdc_flags_t flags); + void ltdcSetEnableFlags(LTDCDriver *ltdcp, ltdc_flags_t flags); + bool ltdcIsReloadingI(LTDCDriver *ltdcp); + bool ltdcIsReloading(LTDCDriver *ltdcp); + void ltdcStartReloadI(LTDCDriver *ltdcp, bool immediately); + void ltdcStartReload(LTDCDriver *ltdcp, bool immediately); + void ltdcReloadS(LTDCDriver *ltdcp, bool immediately); + void ltdcReload(LTDCDriver *ltdcp, bool immediately); + bool ltdcIsDitheringEnabledI(LTDCDriver *ltdcp); + bool ltdcIsDitheringEnabled(LTDCDriver *ltdcp); + void ltdcEnableDitheringI(LTDCDriver *ltdcp); + void ltdcEnableDithering(LTDCDriver *ltdcp); + void ltdcDisableDitheringI(LTDCDriver *ltdcp); + void ltdcDisableDithering(LTDCDriver *ltdcp); + ltdc_color_t ltdcGetClearColorI(LTDCDriver *ltdcp); + ltdc_color_t ltdcGetClearColor(LTDCDriver *ltdcp); + void ltdcSetClearColorI(LTDCDriver *ltdcp, ltdc_color_t c); + void ltdcSetClearColor(LTDCDriver *ltdcp, ltdc_color_t c); + uint16_t ltdcGetLineInterruptPosI(LTDCDriver *ltdcp); + uint16_t ltdcGetLineInterruptPos(LTDCDriver *ltdcp); + void ltdcSetLineInterruptPosI(LTDCDriver *ltdcp, uint16_t line); + void ltdcSetLineInterruptPos(LTDCDriver *ltdcp, uint16_t line); + bool ltdcIsLineInterruptEnabledI(LTDCDriver *ltdcp); + bool ltdcIsLineInterruptEnabled(LTDCDriver *ltdcp); + void ltdcEnableLineInterruptI(LTDCDriver *ltdcp); + void ltdcEnableLineInterrupt(LTDCDriver *ltdcp); + void ltdcDisableLineInterruptI(LTDCDriver *ltdcp); + void ltdcDisableLineInterrupt(LTDCDriver *ltdcp); + void ltdcGetCurrentPosI(LTDCDriver *ltdcp, uint16_t *xp, uint16_t *yp); + void ltdcGetCurrentPos(LTDCDriver *ltdcp, uint16_t *xp, uint16_t *yp); + + /* Background layer methods.*/ + ltdc_flags_t ltdcBgGetEnableFlagsI(LTDCDriver *ltdcp); + ltdc_flags_t ltdcBgGetEnableFlags(LTDCDriver *ltdcp); + void ltdcBgSetEnableFlagsI(LTDCDriver *ltdcp, ltdc_flags_t flags); + void ltdcBgSetEnableFlags(LTDCDriver *ltdcp, ltdc_flags_t flags); + bool ltdcBgIsEnabledI(LTDCDriver *ltdcp); + bool ltdcBgIsEnabled(LTDCDriver *ltdcp); + void ltdcBgEnableI(LTDCDriver *ltdcp); + void ltdcBgEnable(LTDCDriver *ltdcp); + void ltdcBgDisableI(LTDCDriver *ltdcp); + void ltdcBgDisable(LTDCDriver *ltdcp); + bool ltdcBgIsPaletteEnabledI(LTDCDriver *ltdcp); + bool ltdcBgIsPaletteEnabled(LTDCDriver *ltdcp); + void ltdcBgEnablePaletteI(LTDCDriver *ltdcp); + void ltdcBgEnablePalette(LTDCDriver *ltdcp); + void ltdcBgDisablePaletteI(LTDCDriver *ltdcp); + void ltdcBgDisablePalette(LTDCDriver *ltdcp); + void ltdcBgSetPaletteColorI(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c); + void ltdcBgSetPaletteColor(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c); + void ltdcBgSetPaletteI(LTDCDriver *ltdcp, const ltdc_color_t colors[], + uint16_t length); + void ltdcBgSetPalette(LTDCDriver *ltdcp, const ltdc_color_t colors[], + uint16_t length); + ltdc_pixfmt_t ltdcBgGetPixelFormatI(LTDCDriver *ltdcp); + ltdc_pixfmt_t ltdcBgGetPixelFormat(LTDCDriver *ltdcp); + void ltdcBgSetPixelFormatI(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt); + void ltdcBgSetPixelFormat(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt); + bool ltdcBgIsKeyingEnabledI(LTDCDriver *ltdcp); + bool ltdcBgIsKeyingEnabled(LTDCDriver *ltdcp); + void ltdcBgEnableKeyingI(LTDCDriver *ltdcp); + void ltdcBgEnableKeying(LTDCDriver *ltdcp); + void ltdcBgDisableKeyingI(LTDCDriver *ltdcp); + void ltdcBgDisableKeying(LTDCDriver *ltdcp); + ltdc_color_t ltdcBgGetKeyingColorI(LTDCDriver *ltdcp); + ltdc_color_t ltdcBgGetKeyingColor(LTDCDriver *ltdcp); + void ltdcBgSetKeyingColorI(LTDCDriver *ltdcp, ltdc_color_t c); + void ltdcBgSetKeyingColor(LTDCDriver *ltdcp, ltdc_color_t c); + uint8_t ltdcBgGetConstantAlphaI(LTDCDriver *ltdcp); + uint8_t ltdcBgGetConstantAlpha(LTDCDriver *ltdcp); + void ltdcBgSetConstantAlphaI(LTDCDriver *ltdcp, uint8_t a); + void ltdcBgSetConstantAlpha(LTDCDriver *ltdcp, uint8_t a); + ltdc_color_t ltdcBgGetDefaultColorI(LTDCDriver *ltdcp); + ltdc_color_t ltdcBgGetDefaultColor(LTDCDriver *ltdcp); + void ltdcBgSetDefaultColorI(LTDCDriver *ltdcp, ltdc_color_t c); + void ltdcBgSetDefaultColor(LTDCDriver *ltdcp, ltdc_color_t c); + ltdc_blendf_t ltdcBgGetBlendingFactorsI(LTDCDriver *ltdcp); + ltdc_blendf_t ltdcBgGetBlendingFactors(LTDCDriver *ltdcp); + void ltdcBgSetBlendingFactorsI(LTDCDriver *ltdcp, ltdc_blendf_t bf); + void ltdcBgSetBlendingFactors(LTDCDriver *ltdcp, ltdc_blendf_t bf); + void ltdcBgGetWindowI(LTDCDriver *ltdcp, ltdc_window_t *windowp); + void ltdcBgGetWindow(LTDCDriver *ltdcp, ltdc_window_t *windowp); + void ltdcBgSetWindowI(LTDCDriver *ltdcp, const ltdc_window_t *windowp); + void ltdcBgSetWindow(LTDCDriver *ltdcp, const ltdc_window_t *windowp); + void ltdcBgSetInvalidWindowI(LTDCDriver *ltdcp); + void ltdcBgSetInvalidWindow(LTDCDriver *ltdcp); + void ltdcBgGetFrameI(LTDCDriver *ltdcp, ltdc_frame_t *framep); + void ltdcBgGetFrame(LTDCDriver *ltdcp, ltdc_frame_t *framep); + void ltdcBgSetFrameI(LTDCDriver *ltdcp, const ltdc_frame_t *framep); + void ltdcBgSetFrame(LTDCDriver *ltdcp, const ltdc_frame_t *framep); + void *ltdcBgGetFrameAddressI(LTDCDriver *ltdcp); + void *ltdcBgGetFrameAddress(LTDCDriver *ltdcp); + void ltdcBgSetFrameAddressI(LTDCDriver *ltdcp, void *bufferp); + void ltdcBgSetFrameAddress(LTDCDriver *ltdcp, void *bufferp); + void ltdcBgGetLayerI(LTDCDriver *ltdcp, ltdc_laycfg_t *cfgp); + void ltdcBgGetLayer(LTDCDriver *ltdcp, ltdc_laycfg_t *cfgp); + void ltdcBgSetConfigI(LTDCDriver *ltdcp, const ltdc_laycfg_t *cfgp); + void ltdcBgSetConfig(LTDCDriver *ltdcp, const ltdc_laycfg_t *cfgp); + + /* Foreground layer methods.*/ + ltdc_flags_t ltdcFgGetEnableFlagsI(LTDCDriver *ltdcp); + ltdc_flags_t ltdcFgGetEnableFlags(LTDCDriver *ltdcp); + void ltdcFgSetEnableFlagsI(LTDCDriver *ltdcp, ltdc_flags_t flags); + void ltdcFgSetEnableFlags(LTDCDriver *ltdcp, ltdc_flags_t flags); + bool ltdcFgIsEnabledI(LTDCDriver *ltdcp); + bool ltdcFgIsEnabled(LTDCDriver *ltdcp); + void ltdcFgEnableI(LTDCDriver *ltdcp); + void ltdcFgEnable(LTDCDriver *ltdcp); + void ltdcFgDisableI(LTDCDriver *ltdcp); + void ltdcFgDisable(LTDCDriver *ltdcp); + bool ltdcFgIsPaletteEnabledI(LTDCDriver *ltdcp); + bool ltdcFgIsPaletteEnabled(LTDCDriver *ltdcp); + void ltdcFgEnablePaletteI(LTDCDriver *ltdcp); + void ltdcFgEnablePalette(LTDCDriver *ltdcp); + void ltdcFgDisablePaletteI(LTDCDriver *ltdcp); + void ltdcFgDisablePalette(LTDCDriver *ltdcp); + void ltdcFgSetPaletteColorI(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c); + void ltdcFgSetPaletteColor(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c); + void ltdcFgSetPaletteI(LTDCDriver *ltdcp, const ltdc_color_t colors[], + uint16_t length); + void ltdcFgSetPalette(LTDCDriver *ltdcp, const ltdc_color_t colors[], + uint16_t length); + ltdc_pixfmt_t ltdcFgGetPixelFormatI(LTDCDriver *ltdcp); + ltdc_pixfmt_t ltdcFgGetPixelFormat(LTDCDriver *ltdcp); + void ltdcFgSetPixelFormatI(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt); + void ltdcFgSetPixelFormat(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt); + bool ltdcFgIsKeyingEnabledI(LTDCDriver *ltdcp); + bool ltdcFgIsKeyingEnabled(LTDCDriver *ltdcp); + void ltdcFgEnableKeyingI(LTDCDriver *ltdcp); + void ltdcFgEnableKeying(LTDCDriver *ltdcp); + void ltdcFgDisableKeyingI(LTDCDriver *ltdcp); + void ltdcFgDisableKeying(LTDCDriver *ltdcp); + ltdc_color_t ltdcFgGetKeyingColorI(LTDCDriver *ltdcp); + ltdc_color_t ltdcFgGetKeyingColor(LTDCDriver *ltdcp); + void ltdcFgSetKeyingColorI(LTDCDriver *ltdcp, ltdc_color_t c); + void ltdcFgSetKeyingColor(LTDCDriver *ltdcp, ltdc_color_t c); + uint8_t ltdcFgGetConstantAlphaI(LTDCDriver *ltdcp); + uint8_t ltdcFgGetConstantAlpha(LTDCDriver *ltdcp); + void ltdcFgSetConstantAlphaI(LTDCDriver *ltdcp, uint8_t a); + void ltdcFgSetConstantAlpha(LTDCDriver *ltdcp, uint8_t a); + ltdc_color_t ltdcFgGetDefaultColorI(LTDCDriver *ltdcp); + ltdc_color_t ltdcFgGetDefaultColor(LTDCDriver *ltdcp); + void ltdcFgSetDefaultColorI(LTDCDriver *ltdcp, ltdc_color_t c); + void ltdcFgSetDefaultColor(LTDCDriver *ltdcp, ltdc_color_t c); + ltdc_blendf_t ltdcFgGetBlendingFactorsI(LTDCDriver *ltdcp); + ltdc_blendf_t ltdcFgGetBlendingFactors(LTDCDriver *ltdcp); + void ltdcFgSetBlendingFactorsI(LTDCDriver *ltdcp, ltdc_blendf_t bf); + void ltdcFgSetBlendingFactors(LTDCDriver *ltdcp, ltdc_blendf_t bf); + void ltdcFgGetWindowI(LTDCDriver *ltdcp, ltdc_window_t *windowp); + void ltdcFgGetWindow(LTDCDriver *ltdcp, ltdc_window_t *windowp); + void ltdcFgSetWindowI(LTDCDriver *ltdcp, const ltdc_window_t *windowp); + void ltdcFgSetWindow(LTDCDriver *ltdcp, const ltdc_window_t *windowp); + void ltdcFgSetInvalidWindowI(LTDCDriver *ltdcp); + void ltdcFgSetInvalidWindow(LTDCDriver *ltdcp); + void ltdcFgGetFrameI(LTDCDriver *ltdcp, ltdc_frame_t *framep); + void ltdcFgGetFrame(LTDCDriver *ltdcp, ltdc_frame_t *framep); + void ltdcFgSetFrameI(LTDCDriver *ltdcp, const ltdc_frame_t *framep); + void ltdcFgSetFrame(LTDCDriver *ltdcp, const ltdc_frame_t *framep); + void *ltdcFgGetFrameAddressI(LTDCDriver *ltdcp); + void *ltdcFgGetFrameAddress(LTDCDriver *ltdcp); + void ltdcFgSetFrameAddressI(LTDCDriver *ltdcp, void *bufferp); + void ltdcFgSetFrameAddress(LTDCDriver *ltdcp, void *bufferp); + void ltdcFgGetLayerI(LTDCDriver *ltdcp, ltdc_laycfg_t *cfgp); + void ltdcFgGetLayer(LTDCDriver *ltdcp, ltdc_laycfg_t *cfgp); + void ltdcFgSetConfigI(LTDCDriver *ltdcp, const ltdc_laycfg_t *cfgp); + void ltdcFgSetConfig(LTDCDriver *ltdcp, const ltdc_laycfg_t *cfgp); + + /* Helper functions.*/ + size_t ltdcBitsPerPixel(ltdc_pixfmt_t fmt); +#if (TRUE == LTDC_USE_SOFTWARE_CONVERSIONS) || defined(__DOXYGEN__) + ltdc_color_t ltdcFromARGB8888(ltdc_color_t c, ltdc_pixfmt_t fmt); + ltdc_color_t ltdcToARGB8888(ltdc_color_t c, ltdc_pixfmt_t fmt); +#endif /* LTDC_USE_SOFTWARE_CONVERSIONS */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32_LTDC_USE_LTDC */ + +#endif /* _STM32_LTDC_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/STM32F4xx/platform.mk b/os/hal/ports/STM32/STM32F4xx/platform.mk index 598807e..022ff91 100644 --- a/os/hal/ports/STM32/STM32F4xx/platform.mk +++ b/os/hal/ports/STM32/STM32F4xx/platform.mk @@ -1,11 +1,15 @@ include ${CHIBIOS}/os/hal/ports/STM32/STM32F4xx/platform.mk -PLATFORMSRC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c \ +PLATFORMSRC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c \ + ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc.c \ ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/nand_lld.c \ ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1/fsmc_sram.c \ + ${CHIBIOS}/community/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c \ ${CHIBIOS}/community/os/hal/ports/STM32/LLD/TIMv1/eicu_lld.c \ ${CHIBIOS}/community/os/hal/src/fsmc_sdram.c -PLATFORMINC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1 \ +PLATFORMINC += ${CHIBIOS}/community/os/hal/ports/STM32/LLD/DMA2Dv1 \ + ${CHIBIOS}/community/os/hal/ports/STM32/LLD/FSMCv1 \ + ${CHIBIOS}/community/os/hal/ports/STM32/LLD/LTDCv1 \ ${CHIBIOS}/community/os/hal/ports/STM32/LLD/TIMv1 \ ${CHIBIOS}/community/os/hal/ports/STM32/LLD -- cgit v1.2.3 From ee1353a305ea6620a36e59469881566105827a03 Mon Sep 17 00:00:00 2001 From: Andrea Zoppi Date: Sat, 27 Jun 2015 18:32:58 +0200 Subject: Old definitions removed --- os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c | 2 +- os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h | 26 --------------------- os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h | 34 ---------------------------- 3 files changed, 1 insertion(+), 61 deletions(-) (limited to 'os') diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c index 9bef3d2..d964008 100644 --- a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c +++ b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c @@ -86,7 +86,7 @@ static const uint8_t dma2d_bpp[DMA2D_MAX_PIXFMT_ID + 1] = { * * @isr */ -OSAL_IRQ_HANDLER(DMA2D_IRQHandler) { +OSAL_IRQ_HANDLER(STM32_DMA2D_HANDLER) { DMA2DDriver *const dma2dp = &DMA2DD1; bool job_done = false; diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h index c118be2..c5aa159 100644 --- a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h +++ b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h @@ -171,28 +171,6 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/* - * These definitions should already be defined by stm32_isr.h - */ -#if !defined(STM32_DMA2D_NUMBER) && !defined(__DOXYGEN__) -#define STM32_DMA2D_NUMBER (DMA2D_IRQn) -#endif - -/* - * These definitions should already be defined by hal_lld.h - */ -#if !defined(DMA2D_IRQHandler) && !defined(__DOXYGEN__) -#define DMA2D_IRQHandler Vector1A8 -#endif - -#if !defined(STM32_HAS_DMA2D) && !defined(__DOXYGEN__) -#ifdef STM32F429_439xx -#define STM32_HAS_DMA2D (TRUE) -#else -#define STM32_HAS_DMA2D (FALSE) -#endif -#endif - /** * @name DMA2D configuration options * @{ @@ -244,10 +222,6 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -#ifndef STM32F429_439xx -#error "Currently only STM32F429xx and STM32F439xx are supported" -#endif - #if (TRUE != STM32_HAS_DMA2D) #error "DMA2D must be present when using the DMA2D subsystem" #endif diff --git a/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h index a221c79..00af038 100644 --- a/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h +++ b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h @@ -203,36 +203,6 @@ /* Driver pre-compile time settings. */ /*===========================================================================*/ -/* - * These definitions should already be defined by stm32_isr.h - */ -#if !defined(STM32_LTDC_EV_NUMBER) && !defined(__DOXYGEN__) -#define STM32_LTDC_EV_NUMBER LTDC_IRQn -#endif - -#if !defined(STM32_LTDC_ER_NUMBER) && !defined(__DOXYGEN__) -#define STM32_LTDC_ER_NUMBER LTDC_ER_IRQn -#endif - -/* - * These definitions should already be defined by hal_lld.h - */ -#if !defined(STM32_LTDC_EV_HANDLER) && !defined(__DOXYGEN__) -#define STM32_LTDC_EV_HANDLER Vector1A0 -#endif - -#if !defined(STM32_LTDC_ER_HANDLER) && !defined(__DOXYGEN__) -#define STM32_LTDC_ER_HANDLER Vector1A4 -#endif - -#if !defined(STM32_HAS_LTDC) && !defined(__DOXYGEN__) -#ifdef STM32F429_439xx -#define STM32_HAS_LTDC TRUE -#else -#define STM32_HAS_LTDC FALSE -#endif -#endif - /** * @name LTDC configuration options * @{ @@ -291,10 +261,6 @@ /* Derived constants and error checks. */ /*===========================================================================*/ -#ifndef STM32F429_439xx -#error "Currently only STM32F429xx and STM32F439xx are supported" -#endif - #if (TRUE != STM32_HAS_LTDC) #error "LTDC must be present when using the LTDC subsystem" #endif -- cgit v1.2.3 From 0229440fba26f4f1d1d34f6ff28e5a4b1b92a281 Mon Sep 17 00:00:00 2001 From: Andrea Zoppi Date: Sat, 27 Jun 2015 18:34:23 +0200 Subject: ILI9341 driver moved to devices_lib --- os/hal/hal.mk | 6 +- os/various/devices_lib/others/ili9341.c | 418 ++++++++++++++++++++++ os/various/devices_lib/others/ili9341.h | 593 ++++++++++++++++++++++++++++++++ 3 files changed, 1014 insertions(+), 3 deletions(-) create mode 100644 os/various/devices_lib/others/ili9341.c create mode 100644 os/various/devices_lib/others/ili9341.h (limited to 'os') diff --git a/os/hal/hal.mk b/os/hal/hal.mk index 2508c90..51cda56 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -1,8 +1,8 @@ include ${CHIBIOS}/os/hal/hal.mk HALSRC += ${CHIBIOS}/community/os/hal/src/hal_community.c \ - ${CHIBIOS}/community/os/hal/src/nand.c \ - ${CHIBIOS}/community/os/hal/src/onewire.c \ - ${CHIBIOS}/community/os/hal/src/eicu.c + ${CHIBIOS}/community/os/hal/src/nand.c \ + ${CHIBIOS}/community/os/hal/src/onewire.c \ + ${CHIBIOS}/community/os/hal/src/eicu.c HALINC += ${CHIBIOS}/community/os/hal/include diff --git a/os/various/devices_lib/others/ili9341.c b/os/various/devices_lib/others/ili9341.c new file mode 100644 index 0000000..979e502 --- /dev/null +++ b/os/various/devices_lib/others/ili9341.c @@ -0,0 +1,418 @@ +/* + Copyright (C) 2013-2015 Andrea Zoppi + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file ili9341.c + * @brief ILI9341 TFT LCD diaplay controller driver. + * @note Does not support multiple calling threads natively. + */ + +#include "ch.h" +#include "hal.h" +#include "ili9341.h" + +/** + * @addtogroup ili9341 + * @{ + */ + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#if !ILI9341_USE_CHECKS && !defined(__DOXYGEN__) +/* Disable checks as needed.*/ + +#ifdef osalDbgCheck +#undef osalDbgCheck +#endif +#define osalDbgCheck(c, func) { \ + (void)(c), (void)__QUOTE_THIS(func)"()"; \ +} + +#ifdef osalDbgAssert +#undef osalDbgAssert +#endif +#define osalDbgAssert(c, m, r) { \ + (void)(c); \ +} + +#ifdef osalDbgCheckClassS +#undef osalDbgCheckClassS +#endif +#define osalDbgCheckClassS() {} + +#ifdef osalDbgCheckClassS +#undef osalDbgCheckClassS +#endif +#define osalDbgCheckClassI() {} + +#endif /* ILI9341_USE_CHECKS */ + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** @brief ILI9341D1 driver identifier.*/ +ILI9341Driver ILI9341D1; + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the standard part of a @p ILI9341Driver structure. + * + * @param[out] driverp pointer to the @p ILI9341Driver object + * + * @init + */ +void ili9341ObjectInit(ILI9341Driver *driverp) { + + osalDbgCheck(driverp != NULL); + + driverp->state = ILI9341_STOP; + driverp->config = NULL; +#if (TRUE == ILI9341_USE_MUTUAL_EXCLUSION) +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxObjectInit(&driverp->lock); +#else + chSemObjectInit(&driverp->lock, 1); +#endif +#endif /* (TRUE == ILI9341_USE_MUTUAL_EXCLUSION) */ +} + +/** + * @brief Configures and activates the ILI9341 peripheral. + * @pre ILI9341 is stopped. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * @param[in] configp pointer to the @p ILI9341Config object + * + * @api + */ +void ili9341Start(ILI9341Driver *driverp, const ILI9341Config *configp) { + + chSysLock(); + osalDbgCheck(driverp != NULL); + osalDbgCheck(configp != NULL); + osalDbgCheck(configp->spi != NULL); + osalDbgAssert(driverp->state == ILI9341_STOP, "invalid state"); + + spiSelectI(configp->spi); + spiUnselectI(configp->spi); + driverp->config = configp; + driverp->state = ILI9341_READY; + chSysUnlock(); +} + +/** + * @brief Deactivates the ILI9341 peripheral. + * @pre ILI9341 is ready. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @api + */ +void ili9341Stop(ILI9341Driver *driverp) { + + chSysLock(); + osalDbgCheck(driverp != NULL); + osalDbgAssert(driverp->state == ILI9341_READY, "invalid state"); + + driverp->state = ILI9341_STOP; + chSysUnlock(); +} + +#if ILI9341_USE_MUTUAL_EXCLUSION + +/** + * @brief Gains exclusive access to the ILI9341 module. + * @details This function tries to gain ownership to the ILI9341 module, if the + * module is already being used then the invoking thread is queued. + * @pre In order to use this function the option + * @p ILI9341_USE_MUTUAL_EXCLUSION must be enabled. + * @pre ILI9341 is ready. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @sclass + */ +void ili9341AcquireBusS(ILI9341Driver *driverp) { + + osalDbgCheckClassS(); + osalDbgCheck(driverp == &ILI9341D1); + osalDbgAssert(driverp->state == ILI9341_READY, "not ready"); + +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxLockS(&driverp->lock); +#else + chSemWaitS(&driverp->lock); +#endif +} + +/** + * @brief Gains exclusive access to the ILI9341 module. + * @details This function tries to gain ownership to the ILI9341 module, if the + * module is already being used then the invoking thread is queued. + * @pre In order to use this function the option + * @p ILI9341_USE_MUTUAL_EXCLUSION must be enabled. + * @pre ILI9341 is ready. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @api + */ +void ili9341AcquireBus(ILI9341Driver *driverp) { + + chSysLock(); + ili9341AcquireBusS(driverp); + chSysUnlock(); +} + +/** + * @brief Releases exclusive access to the ILI9341 module. + * @pre In order to use this function the option + * @p ILI9341_USE_MUTUAL_EXCLUSION must be enabled. + * @pre ILI9341 is ready. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @sclass + */ +void ili9341ReleaseBusS(ILI9341Driver *driverp) { + + osalDbgCheckClassS(); + osalDbgCheck(driverp == &ILI9341D1); + osalDbgAssert(driverp->state == ILI9341_READY, "not ready"); + +#if (TRUE == CH_CFG_USE_MUTEXES) + chMtxUnlockS(&driverp->lock); +#else + chSemSignalI(&driverp->lock); +#endif +} + +/** + * @brief Releases exclusive access to the ILI9341 module. + * @pre In order to use this function the option + * @p ILI9341_USE_MUTUAL_EXCLUSION must be enabled. + * @pre ILI9341 is ready. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @api + */ +void ili9341ReleaseBus(ILI9341Driver *driverp) { + + chSysLock(); + ili9341ReleaseBusS(driverp); + chSysUnlock(); +} + +#endif /* ILI9341_USE_MUTUAL_EXCLUSION */ + +#if ILI9341_IM == ILI9341_IM_4LSI_1 /* 4-wire, half-duplex */ + +/** + * @brief Asserts the slave select signal and prepares for transfers. + * @pre ILI9341 is ready. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @iclass + */ +void ili9341SelectI(ILI9341Driver *driverp) { + + osalDbgCheckClassI(); + osalDbgCheck(driverp != NULL); + osalDbgAssert(driverp->state == ILI9341_READY, "invalid state"); + + driverp->state = ILI9341_ACTIVE; + spiSelectI(driverp->config->spi); +} + +/** + * @brief Asserts the slave select signal and prepares for transfers. + * @pre ILI9341 is ready. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @api + */ +void ili9341Select(ILI9341Driver *driverp) { + + chSysLock(); + ili9341SelectI(driverp); + chSysUnlock(); +} + +/** + * @brief Deasserts the slave select signal. + * @details The previously selected peripheral is unselected. + * @pre ILI9341 is active. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @iclass + */ +void ili9341UnselectI(ILI9341Driver *driverp) { + + osalDbgCheckClassI(); + osalDbgCheck(driverp != NULL); + osalDbgAssert(driverp->state == ILI9341_ACTIVE, "invalid state"); + + spiUnselectI(driverp->config->spi); + driverp->state = ILI9341_READY; +} + +/** + * @brief Deasserts the slave select signal. + * @details The previously selected peripheral is unselected. + * @pre ILI9341 is active. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @iclass + */ +void ili9341Unselect(ILI9341Driver *driverp) { + + chSysLock(); + ili9341UnselectI(driverp); + chSysUnlock(); +} + +/** + * @brief Write command byte. + * @details Sends a command byte via SPI. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * @param[in] cmd command byte + * + * @api + */ +void ili9341WriteCommand(ILI9341Driver *driverp, uint8_t cmd) { + + osalDbgCheck(driverp != NULL); + osalDbgAssert(driverp->state == ILI9341_ACTIVE, "invalid state"); + + driverp->value = cmd; + palClearPad(driverp->config->dcx_port, driverp->config->dcx_pad); /* !Cmd */ + spiSend(driverp->config->spi, 1, &driverp->value); +} + +/** + * @brief Write data byte. + * @details Sends a data byte via SPI. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * @param[in] value data byte + * + * @api + */ +void ili9341WriteByte(ILI9341Driver *driverp, uint8_t value) { + + osalDbgCheck(driverp != NULL); + osalDbgAssert(driverp->state == ILI9341_ACTIVE, "invalid state"); + + driverp->value = value; + palSetPad(driverp->config->dcx_port, driverp->config->dcx_pad); /* Data */ + spiSend(driverp->config->spi, 1, &driverp->value); +} + +/** + * @brief Read data byte. + * @details Receives a data byte via SPI. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * + * @return data byte + * + * @api + */ +uint8_t ili9341ReadByte(ILI9341Driver *driverp) { + + osalDbgAssert(FALSE, "should not be used"); + + osalDbgCheck(driverp != NULL); + osalDbgAssert(driverp->state == ILI9341_ACTIVE, "invalid state"); + + palSetPad(driverp->config->dcx_port, driverp->config->dcx_pad); /* Data */ + spiReceive(driverp->config->spi, 1, &driverp->value); + return driverp->value; +} + +/** + * @brief Write data chunk. + * @details Sends a data chunk via SPI. + * @pre The chunk must be accessed by DMA. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * @param[in] chunk chunk bytes + * @param[in] length chunk length + * + * @api + */ +void ili9341WriteChunk(ILI9341Driver *driverp, const uint8_t chunk[], + size_t length) { + + osalDbgCheck(driverp != NULL); + osalDbgCheck(chunk != NULL); + osalDbgAssert(driverp->state == ILI9341_ACTIVE, "invalid state"); + + if (length != 0) { + palSetPad(driverp->config->dcx_port, driverp->config->dcx_pad); /* Data */ + spiSend(driverp->config->spi, length, chunk); + } +} + +/** + * @brief Read data chunk. + * @details Receives a data chunk via SPI. + * @pre The chunk must be accessed by DMA. + * + * @param[in] driverp pointer to the @p ILI9341Driver object + * @param[out] chunk chunk bytes + * @param[in] length chunk length + * + * @api + */ +void ili9341ReadChunk(ILI9341Driver *driverp, uint8_t chunk[], + size_t length) { + + osalDbgCheck(driverp != NULL); + osalDbgCheck(chunk != NULL); + osalDbgAssert(driverp->state == ILI9341_ACTIVE, "invalid state"); + + if (length != 0) { + palSetPad(driverp->config->dcx_port, driverp->config->dcx_pad); /* Data */ + spiReceive(driverp->config->spi, length, chunk); + } +} + +#else /* ILI9341_IM == * */ +#error "Only the ILI9341_IM_4LSI_1 interface mode is currently supported" +#endif /* ILI9341_IM == * */ + +/** @} */ diff --git a/os/various/devices_lib/others/ili9341.h b/os/various/devices_lib/others/ili9341.h new file mode 100644 index 0000000..007c4fd --- /dev/null +++ b/os/various/devices_lib/others/ili9341.h @@ -0,0 +1,593 @@ +/* + Copyright (C) 2013-2015 Andrea Zoppi + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file ili9341.h + * @brief ILI9341 TFT LCD diaplay controller driver. + */ + +#ifndef _ILI9341_H_ +#define _ILI9341_H_ + +/** + * @addtogroup ili9341 + * @{ + */ + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @name ILI9341 regulative commands + * @{ + */ +#define ILI9341_CMD_NOP (0x00) /**< No operation.*/ +#define ILI9341_CMD_RESET (0x01) /**< Software reset.*/ +#define ILI9341_GET_ID_INFO (0x04) /**< Get ID information.*/ +#define ILI9341_GET_STATUS (0x09) /**< Get status.*/ +#define ILI9341_GET_PWR_MODE (0x0A) /**< Get power mode.*/ +#define ILI9341_GET_MADCTL (0x0B) /**< Get MADCTL.*/ +#define ILI9341_GET_PIX_FMT (0x0C) /**< Get pixel format.*/ +#define ILI9341_GET_IMG_FMT (0x0D) /**< Get image format.*/ +#define ILI9341_GET_SIG_MODE (0x0E) /**< Get signal mode.*/ +#define ILI9341_GET_SELF_DIAG (0x0F) /**< Get self-diagnostics.*/ +#define ILI9341_CMD_SLEEP_ON (0x10) /**< Enter sleep mode.*/ +#define ILI9341_CMD_SLEEP_OFF (0x11) /**< Exist sleep mode.*/ +#define ILI9341_CMD_PARTIAL_ON (0x12) /**< Enter partial mode.*/ +#define ILI9341_CMD_PARTIAL_OFF (0x13) /**< Exit partial mode.*/ +#define ILI9341_CMD_INVERT_ON (0x20) /**< Enter inverted mode.*/ +#define ILI9341_CMD_INVERT_OFF (0x21) /**< Exit inverted mode.*/ +#define ILI9341_SET_GAMMA (0x26) /**< Set gamma params.*/ +#define ILI9341_CMD_DISPLAY_OFF (0x28) /**< Disable display.*/ +#define ILI9341_CMD_DISPLAY_ON (0x29) /**< Enable display.*/ +#define ILI9341_SET_COL_ADDR (0x2A) /**< Set column address.*/ +#define ILI9341_SET_PAGE_ADDR (0x2B) /**< Set page address.*/ +#define ILI9341_SET_MEM (0x2C) /**< Set memory.*/ +#define ILI9341_SET_COLOR (0x2D) /**< Set color.*/ +#define ILI9341_GET_MEM (0x2E) /**< Get memory.*/ +#define ILI9341_SET_PARTIAL_AREA (0x30) /**< Set partial area.*/ +#define ILI9341_SET_VSCROLL (0x33) /**< Set vertical scroll def.*/ +#define ILI9341_CMD_TEARING_ON (0x34) /**< Tearing line enabled.*/ +#define ILI9341_CMD_TEARING_OFF (0x35) /**< Tearing line disabled.*/ +#define ILI9341_SET_MEM_ACS_CTL (0x36) /**< Set mem access ctl.*/ +#define ILI9341_SET_VSCROLL_ADDR (0x37) /**< Set vscroll start addr.*/ +#define ILI9341_CMD_IDLE_OFF (0x38) /**< Exit idle mode.*/ +#define ILI9341_CMD_IDLE_ON (0x39) /**< Enter idle mode.*/ +#define ILI9341_SET_PIX_FMT (0x3A) /**< Set pixel format.*/ +#define ILI9341_SET_MEM_CONT (0x3C) /**< Set memory continue.*/ +#define ILI9341_GET_MEM_CONT (0x3E) /**< Get memory continue.*/ +#define ILI9341_SET_TEAR_SCANLINE (0x44) /**< Set tearing scanline.*/ +#define ILI9341_GET_TEAR_SCANLINE (0x45) /**< Get tearing scanline.*/ +#define ILI9341_SET_BRIGHTNESS (0x51) /**< Set brightness.*/ +#define ILI9341_GET_BRIGHTNESS (0x52) /**< Get brightness.*/ +#define ILI9341_SET_DISPLAY_CTL (0x53) /**< Set display ctl.*/ +#define ILI9341_GET_DISPLAY_CTL (0x54) /**< Get display ctl.*/ +#define ILI9341_SET_CABC (0x55) /**< Set CABC.*/ +#define ILI9341_GET_CABC (0x56) /**< Get CABC.*/ +#define ILI9341_SET_CABC_MIN (0x5E) /**< Set CABC min.*/ +#define ILI9341_GET_CABC_MIN (0x5F) /**< Set CABC max.*/ +#define ILI9341_GET_ID1 (0xDA) /**< Get ID1.*/ +#define ILI9341_GET_ID2 (0xDB) /**< Get ID2.*/ +#define ILI9341_GET_ID3 (0xDC) /**< Get ID3.*/ +/** @} */ + +/** + * @name ILI9341 extended commands + * @{ + */ +#define ILI9341_SET_RGB_IF_SIG_CTL (0xB0) /**< RGB IF signal ctl.*/ +#define ILI9341_SET_FRAME_CTL_NORMAL (0xB1) /**< Set frame ctl (normal).*/ +#define ILI9341_SET_FRAME_CTL_IDLE (0xB2) /**< Set frame ctl (idle).*/ +#define ILI9341_SET_FRAME_CTL_PARTIAL (0xB3) /**< Set frame ctl (partial).*/ +#define ILI9341_SET_INVERSION_CTL (0xB4) /**< Set inversion ctl.*/ +#define ILI9341_SET_BLANKING_PORCH_CTL (0xB5) /**< Set blanking porch ctl.*/ +#define ILI9341_SET_FUNCTION_CTL (0xB6) /**< Set function ctl.*/ +#define ILI9341_SET_ENTRY_MODE (0xB7) /**< Set entry mode.*/ +#define ILI9341_SET_LIGHT_CTL_1 (0xB8) /**< Set backlight ctl 1.*/ +#define ILI9341_SET_LIGHT_CTL_2 (0xB9) /**< Set backlight ctl 2.*/ +#define ILI9341_SET_LIGHT_CTL_3 (0xBA) /**< Set backlight ctl 3.*/ +#define ILI9341_SET_LIGHT_CTL_4 (0xBB) /**< Set backlight ctl 4.*/ +#define ILI9341_SET_LIGHT_CTL_5 (0xBC) /**< Set backlight ctl 5.*/ +#define ILI9341_SET_LIGHT_CTL_7 (0xBE) /**< Set backlight ctl 7.*/ +#define ILI9341_SET_LIGHT_CTL_8 (0xBF) /**< Set backlight ctl 8.*/ +#define ILI9341_SET_POWER_CTL_1 (0xC0) /**< Set power ctl 1.*/ +#define ILI9341_SET_POWER_CTL_2 (0xC1) /**< Set power ctl 2.*/ +#define ILI9341_SET_VCOM_CTL_1 (0xC5) /**< Set VCOM ctl 1.*/ +#define ILI9341_SET_VCOM_CTL_2 (0xC6) /**< Set VCOM ctl 2.*/ +#define ILI9341_SET_NVMEM (0xD0) /**< Set NVMEM data.*/ +#define ILI9341_GET_NVMEM_KEY (0xD1) /**< Get NVMEM protect key.*/ +#define ILI9341_GET_NVMEM_STATUS (0xD2) /**< Get NVMEM status.*/ +#define ILI9341_GET_ID4 (0xD3) /**< Get ID4.*/ +#define ILI9341_SET_PGAMMA (0xE0) /**< Set positive gamma.*/ +#define ILI9341_SET_NGAMMA (0xE1) /**< Set negative gamma.*/ +#define ILI9341_SET_DGAMMA_CTL_1 (0xE2) /**< Set digital gamma ctl 1.*/ +#define ILI9341_SET_DGAMMA_CTL_2 (0xE3) /**< Set digital gamma ctl 2.*/ +#define ILI9341_SET_IF_CTL (0xF6) /**< Set interface control.*/ +/** @} */ + +/** + * @name ILI9341 interface modes + * @{ + */ +#define ILI9341_IM_3LSI_1 (0x5) /**< 3-line serial, mode 1.*/ +#define ILI9341_IM_3LSI_2 (0xD) /**< 3-line serial, mode 2.*/ +#define ILI9341_IM_4LSI_1 (0x6) /**< 4-line serial, mode 1.*/ +#define ILI9341_IM_4LSI_2 (0xE) /**< 4-line serial, mode 2.*/ +/** @} */ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name ILI9341 configuration options + * @{ + */ + +/** + * @brief Enables the @p ili9341AcquireBus() and @p ili9341ReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ILI9341_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ILI9341_USE_MUTUAL_EXCLUSION TRUE +#endif + +/** + * @brief ILI9341 Interface Mode. + */ +#if !defined(ILI9341_IM) || defined(__DOXYGEN__) +#define ILI9341_IM (ILI9341_IM_4LSI_1) +#endif + +/** + * @brief Enables checks for ILI9341 functions. + * @note Disabling this option saves both code and data space. + * @note Disabling checks by ChibiOS will automatically disable ILI9341 + * checks. + */ +#if !defined(ILI9341_USE_CHECKS) || defined(__DOXYGEN__) +#define ILI9341_USE_CHECKS TRUE +#endif + +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if ((TRUE == ILI9341_USE_MUTUAL_EXCLUSION) && \ + (TRUE != CH_CFG_USE_MUTEXES) && \ + (TRUE != CH_CFG_USE_SEMAPHORES)) +#error "ILI9341_USE_MUTUAL_EXCLUSION requires CH_CFG_USE_MUTEXES and/or CH_CFG_USE_SEMAPHORES" +#endif + +/* TODO: Add the remaining modes.*/ +#if (ILI9341_IM != ILI9341_IM_4LSI_1) +#error "Only ILI9341_IM_4LSI_1 interface mode is supported currently" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/* Complex types forwarding.*/ +typedef struct ILI9341Config ILI9341Config; +typedef enum ili9341state_t ili9341state_t; +typedef struct ILI9341Driver ILI9341Driver; + +/** + * @brief ILI9341 driver configuration. + */ +typedef struct ILI9341Config { + SPIDriver *spi; /**< SPI driver used by ILI9341.*/ +#if (ILI9341_IM == ILI9341_IM_4LSI_1) + ioportid_t dcx_port; /**< D/!C signal port.*/ + uint16_t dcx_pad; /**< D/!C signal pad.*/ +#endif /* ILI9341_IM == * */ /* TODO: Add all modes.*/ +} ILI9341Config; + +/** + * @brief ILI9341 driver state. + */ +typedef enum ili9341state_t { + ILI9341_UNINIT = (0), /**< Not initialized.*/ + ILI9341_STOP = (1), /**< Stopped.*/ + ILI9341_READY = (2), /**< Ready.*/ + ILI9341_ACTIVE = (3), /**< Exchanging data.*/ +} ili9341state_t; + +/** + * @brief ILI9341 driver. + */ +typedef struct ILI9341Driver { + ili9341state_t state; /**< Driver state.*/ + const ILI9341Config *config; /**< Driver configuration.*/ + + /* Multithreading stuff.*/ +#if (TRUE == ILI9341_USE_MUTUAL_EXCLUSION) +#if (TRUE == CH_CFG_USE_MUTEXES) + mutex_t lock; /**< Multithreading lock.*/ +#elif (TRUE == CH_CFG_USE_SEMAPHORES) + semaphore_t lock; /**< Multithreading lock.*/ +#endif +#endif /* (TRUE == ILI9341_USE_MUTUAL_EXCLUSION) */ + + /* Temporary variables.*/ + uint8_t value; /**< Non-stacked value, for SPI with CCM.*/ +} ILI9341Driver; + +/** + * @name ILI9341 command params (little endian) + * @{ + */ +#pragma pack(push, 1) + +typedef union { + struct ILI9341ParamBits_GET_ID_INFO { + uint8_t reserved_; + uint8_t ID1; + uint8_t ID2; + uint8_t ID3; + } bits; + uint8_t bytes[4]; +} ILI9341Params_GET_ID_INFO; + +typedef union { + struct ILI9341ParamBits_GET_STATUS { + unsigned _reserved_1 : 5; /* D[ 4: 0] */ + unsigned tearing_mode : 1; /* D[ 5] */ + unsigned gamma_curve : 3; /* D[ 8: 6] */ + unsigned tearing : 1; /* D[ 9] */ + unsigned display : 1; /* D[10] */ + unsigned all_on : 1; /* D[11] */ + unsigned all_off : 1; /* D[12] */ + unsigned invert : 1; /* D[13] */ + unsigned _reserved_2 : 1; /* D[14] */ + unsigned vscroll : 1; /* D[15] */ + unsigned normal : 1; /* D[16] */ + unsigned sleep : 1; /* D[17] */ + unsigned partial : 1; /* D[18] */ + unsigned idle : 1; /* D[19] */ + unsigned pixel_format : 3; /* D[22:20] */ + unsigned _reserved_3 : 2; /* D[24:23] */ + unsigned hrefr_rtl_nltr : 1; /* D[25] */ + unsigned bgr_nrgb : 1; /* D[26] */ + unsigned vrefr_btt_nttb : 1; /* D[27] */ + unsigned transpose : 1; /* D[28] */ + unsigned coladr_rtl_nltr : 1; /* D[29] */ + unsigned rowadr_btt_nttb : 1; /* D[30] */ + unsigned booster : 1; /* D[31] */ + } bits; + uint8_t bytes[4]; +} ILI9341Params_GET_STATUS; + +typedef union { + struct ILI9341ParamBits_GET_PWR_MODE { + unsigned _reserved_1 : 2; /* D[1:0] */ + unsigned display : 1; /* D[2] */ + unsigned normal : 1; /* D[3] */ + unsigned sleep : 1; /* D[4] */ + unsigned partial : 1; /* D[5] */ + unsigned idle : 1; /* D[6] */ + unsigned booster : 1; /* D[7] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_PWR_MODE; + +typedef union { + struct ILI9341ParamBits_GET_MADCTL { + unsigned _reserved_1 : 2; /* D[1:0] */ + unsigned refr_rtl_nltr : 1; /* D[2] */ + unsigned bgr_nrgb : 1; /* D[3] */ + unsigned refr_btt_nttb : 1; /* D[4] */ + unsigned invert : 1; /* D[5] */ + unsigned rtl_nltr : 1; /* D[6] */ + unsigned btt_nttb : 1; /* D[7] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_MADCTL; + +typedef union { + struct ILI9341ParamBits_GET_PIX_FMT { + unsigned DBI : 3; /* D[2:0] */ + unsigned _reserved_1 : 1; /* D[3] */ + unsigned DPI : 3; /* D[6:4] */ + unsigned RIM : 1; /* D[7] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_PIX_FMT; + +typedef union { + struct ILI9341ParamBits_GET_IMG_FMT { + unsigned gamma_curve : 3; /* D[2:0] */ + unsigned _reserved_1 : 5; /* D[7:3] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_IMG_FMT; + +typedef union { + struct ILI9341ParamBits_GET_SIG_MODE { + unsigned _reserved_1 : 2; /* D[1:0] */ + unsigned data_enable : 1; /* D[2] */ + unsigned pixel_clock : 1; /* D[3] */ + unsigned vsync : 1; /* D[4] */ + unsigned hsync : 1; /* D[5] */ + unsigned tearing_mode : 1; /* D[6] */ + unsigned tearing : 1; /* D[7] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_SIG_MODE; + +typedef union { + struct ILI9341ParamBits_GET_SELF_DIAG { + unsigned _reserved_1 : 6; /* D[5:0] */ + unsigned func_err : 1; /* D[6] */ + unsigned reg_err : 1; /* D[7] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_SELF_DIAG; + +typedef union { + struct ILI9341ParamBits_SET_GAMMA { + uint8_t gamma_curve; /* D[7:0] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_SET_GAMMA; + +typedef union { + struct ILI9341ParamBits_SET_COL_ADDR { + uint8_t SC_15_8; /* D[ 7: 0] */ + uint8_t SC_7_0; /* D[15: 8] */ + uint8_t EC_15_8; /* D[23:16] */ + uint8_t EC_7_0; /* D[31:24] */ + } bits; + uint8_t bytes[4]; +} ILI9341Params_SET_COL_ADDR; + +typedef union { + struct ILI9341ParamBits_SET_PAGE_ADDR { + uint8_t SP_15_8; /* D[ 7: 0] */ + uint8_t SP_7_0; /* D[15: 8] */ + uint8_t EP_15_8; /* D[23:16] */ + uint8_t EP_7_0; /* D[31:24] */ + } bits; + uint8_t bytes[4]; +} ILI9341Params_SET_PAGE_ADDR; + +typedef union { + struct ILI9341ParamBits_SET_PARTIAL_AREA { + uint8_t SR_15_8; /* D[ 7: 0] */ + uint8_t SR_7_0; /* D[15: 8] */ + uint8_t ER_15_8; /* D[23:16] */ + uint8_t ER_7_0; /* D[31:24] */ + } bits; + uint8_t bytes[4]; +} ILI9341Params_SET_PARTIAL_AREA; + +typedef union { + struct ILI9341ParamBits_SET_VSCROLL { + uint8_t TFA_15_8; /* D[ 7: 0] */ + uint8_t TFA_7_0; /* D[15: 8] */ + uint8_t VSA_15_8; /* D[23:16] */ + uint8_t VSA_7_0; /* D[31:24] */ + uint8_t BFA_15_8; /* D[39:32] */ + uint8_t BFA_7_0; /* D[47:40] */ + } bits; + uint8_t bytes[6]; +} ILI9341Params_SET_VSCROLL; + +typedef union { + struct ILI9341ParamBits_CMD_TEARING_ON { + unsigned M : 1; /* D[0] */ + unsigned _reserved_1 : 7; /* D[7:1] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_CMD_TEARING_ON; + +typedef union { + struct ILI9341ParamBits_SET_MEM_ACS_CTL { + unsigned _reserved_1 : 2; /* D[1:0] */ + unsigned MH : 1; /* D[2] */ + unsigned BGR : 1; /* D[3] */ + unsigned ML : 1; /* D[4] */ + unsigned MV : 1; /* D[5] */ + unsigned MX : 1; /* D[6] */ + unsigned MY : 1; /* D[7] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_SET_MEM_ACS_CTL; + +typedef union { + struct ILI9341ParamBits_SET_VSCROLL_ADDR { + uint8_t VSP_15_8; /* D[ 7: 0] */ + uint8_t VSP_7_0; /* D[15: 8] */ + } bits; + uint8_t bytes[2]; +} ILI9341Params_SET_VSCROLL_ADDR; + +typedef union { + struct ILI9341ParamBits_SET_PIX_FMT { + unsigned DBI : 3; /* D[2:0] */ + unsigned _reserved_1 : 1; /* D[3] */ + unsigned DPI : 3; /* D[4:6] */ + unsigned _reserved_2 : 1; /* D[7] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_SET_PIX_FMT; + +typedef union { + struct ILI9341ParamBits_SET_TEAR_SCANLINE { + uint8_t STS_8; /* D[ 7: 0] */ + uint8_t STS_7_0; /* D[15: 8] */ + } bits; + uint8_t bytes[4]; +} ILI9341Params_SET_TEAR_SCANLINE; + +typedef union { + struct ILI9341ParamBits_GET_TEAR_SCANLINE { + uint8_t GTS_9_8; /* D[ 7: 0] */ + uint8_t GTS_7_0; /* D[15: 8] */ + } bits; + uint8_t bytes[2]; +} ILI9341Params_GET_TEAR_SCANLINE; + +typedef union { + struct ILI9341ParamBits_SET_BRIGHTNESS { + uint8_t DBV; /* D[7:0] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_SET_BRIGHTNESS; + +typedef union { + struct ILI9341ParamBits_GET_BRIGHTNESS { + uint8_t DBV; /* D[7:0] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_BRIGHTNESS; + +typedef union { + struct ILI9341ParamBits_SET_DISPLAY_CTL { + unsigned _reserved_1 : 2; /* D[1:0] */ + unsigned BL : 1; /* D[2] */ + unsigned DD : 1; /* D[3] */ + unsigned _reserved_2 : 1; /* D[4] */ + unsigned BCTRL : 1; /* D[5] */ + unsigned _reserved_3 : 1; /* D[7:6] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_SET_DISPLAY_CTL; + +typedef union { + struct ILI9341ParamBits_GET_DISPLAY_CTL { + unsigned _reserved_1 : 2; /* D[1:0] */ + unsigned BL : 1; /* D[2] */ + unsigned DD : 1; /* D[3] */ + unsigned _reserved_2 : 1; /* D[4] */ + unsigned BCTRL : 1; /* D[5] */ + unsigned _reserved_3 : 1; /* D[7:6] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_DISPLAY_CTL; + +typedef union { + struct ILI9341ParamBits_SET_CABC { + unsigned C : 2; /* D[1:0] */ + unsigned _reserved_1 : 6; /* D[7:2] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_SET_CABC; + +typedef union { + struct ILI9341ParamBits_GET_CABC { + unsigned C : 2; /* D[1:0] */ + unsigned _reserved_1 : 6; /* D[7:2] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_CABC; + +typedef union { + struct ILI9341ParamBits_SET_CABC_MIN { + uint8_t CMB; /* D[7:0] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_SET_CABC_MIN; + +typedef union { + struct ILI9341ParamBits_GET_CABC_MIN { + uint8_t CMB; /* D[7:0] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_GET_CABC_MIN; + +#if 0 /* TODO: Extended command structs.*/ + +typedef union { + struct ILI9341ParamBits { + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_; + +typedef union { + struct ILI9341ParamBits { + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + unsigned : 1; /* D[] */ + } bits; + uint8_t bytes[1]; +} ILI9341Params_; + +#endif /*0*/ + +#pragma pack(pop) + +/** @} */ + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +extern ILI9341Driver ILI9341D1; + +#ifdef __cplusplus +extern "C" { +#endif + + void ili9341ObjectInit(ILI9341Driver *driverp); + void ili9341Start(ILI9341Driver *driverp, const ILI9341Config *configp); + void ili9341Stop(ILI9341Driver *driverp); +#if (ILI9341_USE_MUTUAL_EXCLUSION == TRUE) + void ili9341AcquireBusS(ILI9341Driver *driverp); + void ili9341AcquireBus(ILI9341Driver *driverp); + void ili9341ReleaseBusS(ILI9341Driver *driverp); + void ili9341ReleaseBus(ILI9341Driver *driverp); +#endif /* (ILI9341_USE_MUTUAL_EXCLUSION == TRUE) */ + void ili9341SelectI(ILI9341Driver *driverp); + void ili9341Select(ILI9341Driver *driverp); + void ili9341UnselectI(ILI9341Driver *driverp); + void ili9341Unselect(ILI9341Driver *driverp); + void ili9341WriteCommand(ILI9341Driver *driverp, uint8_t cmd); + void ili9341WriteByte(ILI9341Driver *driverp, uint8_t value); + uint8_t ili9341ReadByte(ILI9341Driver *driverp); + void ili9341WriteChunk(ILI9341Driver *driverp, const uint8_t chunk[], + size_t length); + void ili9341ReadChunk(ILI9341Driver *driverp, uint8_t chunk[], + size_t length); + +#ifdef __cplusplus +} +#endif + +/** @} */ + +#endif /* _ILI9341_H_ */ -- cgit v1.2.3 From b872d9409ce5527125b2a313166ff3e301d76269 Mon Sep 17 00:00:00 2001 From: Andrea Zoppi Date: Sat, 27 Jun 2015 18:34:33 +0200 Subject: Minor changes --- os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c | 151 +++++++++++++------------- os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h | 4 +- os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c | 154 +++++++++++++-------------- os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h | 154 +++++++++++++-------------- 4 files changed, 234 insertions(+), 229 deletions(-) (limited to 'os') diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c index d964008..75643d6 100644 --- a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c +++ b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.c @@ -274,8 +274,8 @@ void dma2dStart(DMA2DDriver *dma2dp, const DMA2DConfig *configp) { /* Enable interrupts, except Line Watermark.*/ nvicEnableVector(STM32_DMA2D_NUMBER, STM32_DMA2D_IRQ_PRIORITY); - DMA2D->CR = DMA2D_CR_CEIE | DMA2D_CR_CTCIE | DMA2D_CR_CAEIE | - DMA2D_CR_TCIE | DMA2D_CR_TEIE; + DMA2D->CR = (DMA2D_CR_CEIE | DMA2D_CR_CTCIE | DMA2D_CR_CAEIE | + DMA2D_CR_TCIE | DMA2D_CR_TEIE); dma2dp->state = DMA2D_READY; chSysUnlock(); @@ -453,8 +453,8 @@ void dma2dSetWatermarkPosI(DMA2DDriver *dma2dp, uint16_t line) { osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); (void)dma2dp; - DMA2D->LWR = (DMA2D->LWR & ~DMA2D_LWR_LW) | - ((uint32_t)line & DMA2D_LWR_LW); + DMA2D->LWR = ((DMA2D->LWR & ~DMA2D_LWR_LW) | + ((uint32_t)line & DMA2D_LWR_LW)); } /** @@ -637,8 +637,8 @@ void dma2dSetDeadTimeI(DMA2DDriver *dma2dp, uint32_t cycles) { osalDbgAssert(cycles <= DMA2D_MAX_DEADTIME_CYCLES, "bounds"); (void)dma2dp; - DMA2D->AMTCR = (DMA2D->AMTCR & ~DMA2D_AMTCR_DT) | - ((cycles << 8) & DMA2D_AMTCR_DT); + DMA2D->AMTCR = ((DMA2D->AMTCR & ~DMA2D_AMTCR_DT) | + ((cycles << 8) & DMA2D_AMTCR_DT)); } /** @@ -823,7 +823,8 @@ void dma2dJobSetModeI(DMA2DDriver *dma2dp, dma2d_jobmode_t mode) { osalDbgAssert((mode & ~DMA2D_CR_MODE) == 0, "bounds"); (void)dma2dp; - DMA2D->CR = (DMA2D->CR & ~DMA2D_CR_MODE) | ((uint32_t)mode & DMA2D_CR_MODE); + DMA2D->CR = ((DMA2D->CR & ~DMA2D_CR_MODE) | + ((uint32_t)mode & DMA2D_CR_MODE)); } /** @@ -907,8 +908,8 @@ void dma2dJobSetSizeI(DMA2DDriver *dma2dp, uint16_t width, uint16_t height) { osalDbgAssert(height <= DMA2D_MAX_HEIGHT, "bounds"); (void)dma2dp; - DMA2D->NLR = (((uint32_t)width << 16) & DMA2D_NLR_PL) | - (((uint32_t)height << 0) & DMA2D_NLR_NL); + DMA2D->NLR = ((((uint32_t)width << 16) & DMA2D_NLR_PL) | + (((uint32_t)height << 0) & DMA2D_NLR_NL)); } /** @@ -1290,8 +1291,8 @@ void dma2dBgSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset) { osalDbgAssert(offset <= DMA2D_MAX_OFFSET, "bounds"); (void)dma2dp; - DMA2D->BGOR = (DMA2D->BGOR & ~DMA2D_BGOR_LO) | - ((uint32_t)offset & DMA2D_BGOR_LO); + DMA2D->BGOR = ((DMA2D->BGOR & ~DMA2D_BGOR_LO) | + ((uint32_t)offset & DMA2D_BGOR_LO)); } /** @@ -1366,8 +1367,8 @@ void dma2dBgSetConstantAlphaI(DMA2DDriver *dma2dp, uint8_t a) { osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); (void)dma2dp; - DMA2D->BGPFCCR = (DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_ALPHA) | - (((uint32_t)a << 24) & DMA2D_BGPFCCR_ALPHA); + DMA2D->BGPFCCR = ((DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_ALPHA) | + (((uint32_t)a << 24) & DMA2D_BGPFCCR_ALPHA)); } /** @@ -1444,8 +1445,8 @@ void dma2dBgSetAlphaModeI(DMA2DDriver *dma2dp, dma2d_amode_t mode) { osalDbgAssert((mode & DMA2D_BGPFCCR_AM) != DMA2D_BGPFCCR_AM, "bounds"); (void)dma2dp; - DMA2D->BGPFCCR = (DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_AM) | - ((uint32_t)mode & DMA2D_BGPFCCR_AM); + DMA2D->BGPFCCR = ((DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_AM) | + ((uint32_t)mode & DMA2D_BGPFCCR_AM)); } /** @@ -1521,8 +1522,8 @@ void dma2dBgSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { osalDbgAssert(fmt <= DMA2D_MAX_PIXFMT_ID, "bounds"); (void)dma2dp; - DMA2D->BGPFCCR = (DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_CM) | - ((uint32_t)fmt & DMA2D_BGPFCCR_CM); + DMA2D->BGPFCCR = ((DMA2D->BGPFCCR & ~DMA2D_BGPFCCR_CM) | + ((uint32_t)fmt & DMA2D_BGPFCCR_CM)); } /** @@ -1687,9 +1688,11 @@ void dma2dBgSetPaletteS(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep) { (palettep->fmt == DMA2D_FMT_RGB888)), "invalid format"); DMA2D->BGCMAR = (uint32_t)palettep->colorsp; - DMA2D->BGPFCCR = (DMA2D->BGPFCCR & ~(DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM)) | - ((((uint32_t)palettep->length - 1) << 8) & DMA2D_BGPFCCR_CS) - | ((uint32_t)palettep->fmt << 4); + DMA2D->BGPFCCR = ( + (DMA2D->BGPFCCR & ~(DMA2D_BGPFCCR_CS | DMA2D_BGPFCCR_CCM)) | + ((((uint32_t)palettep->length - 1) << 8) & DMA2D_BGPFCCR_CS) | + ((uint32_t)palettep->fmt << 4) + ); dma2dp->state = DMA2D_ACTIVE; DMA2D->BGPFCCR |= DMA2D_BGPFCCR_START; @@ -1953,8 +1956,8 @@ void dma2dFgSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset) { osalDbgAssert(offset <= DMA2D_MAX_OFFSET, "bounds"); (void)dma2dp; - DMA2D->FGOR = (DMA2D->FGOR & ~DMA2D_FGOR_LO) | - ((uint32_t)offset & DMA2D_FGOR_LO); + DMA2D->FGOR = ((DMA2D->FGOR & ~DMA2D_FGOR_LO) | + ((uint32_t)offset & DMA2D_FGOR_LO)); } /** @@ -2029,8 +2032,8 @@ void dma2dFgSetConstantAlphaI(DMA2DDriver *dma2dp, uint8_t a) { osalDbgAssert(dma2dp->state == DMA2D_READY, "not ready"); (void)dma2dp; - DMA2D->FGPFCCR = (DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_ALPHA) | - (((uint32_t)a << 24) & DMA2D_FGPFCCR_ALPHA); + DMA2D->FGPFCCR = ((DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_ALPHA) | + (((uint32_t)a << 24) & DMA2D_FGPFCCR_ALPHA)); } /** @@ -2107,8 +2110,8 @@ void dma2dFgSetAlphaModeI(DMA2DDriver *dma2dp, dma2d_amode_t mode) { osalDbgAssert((mode & DMA2D_FGPFCCR_AM) != DMA2D_FGPFCCR_AM, "bounds"); (void)dma2dp; - DMA2D->FGPFCCR = (DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_AM) | - ((uint32_t)mode & DMA2D_FGPFCCR_AM); + DMA2D->FGPFCCR = ((DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_AM) | + ((uint32_t)mode & DMA2D_FGPFCCR_AM)); } /** @@ -2184,8 +2187,8 @@ void dma2dFgSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { osalDbgAssert(fmt <= DMA2D_MAX_PIXFMT_ID, "bounds"); (void)dma2dp; - DMA2D->FGPFCCR = (DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_CM) | - ((uint32_t)fmt & DMA2D_FGPFCCR_CM); + DMA2D->FGPFCCR = ((DMA2D->FGPFCCR & ~DMA2D_FGPFCCR_CM) | + ((uint32_t)fmt & DMA2D_FGPFCCR_CM)); } /** @@ -2350,9 +2353,11 @@ void dma2dFgSetPaletteS(DMA2DDriver *dma2dp, const dma2d_palcfg_t *palettep) { (palettep->fmt == DMA2D_FMT_RGB888)), "invalid format"); DMA2D->FGCMAR = (uint32_t)palettep->colorsp; - DMA2D->FGPFCCR = (DMA2D->FGPFCCR & ~(DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM)) | - ((((uint32_t)palettep->length - 1) << 8) & DMA2D_FGPFCCR_CS) - | ((uint32_t)palettep->fmt << 4); + DMA2D->FGPFCCR = ( + (DMA2D->FGPFCCR & ~(DMA2D_FGPFCCR_CS | DMA2D_FGPFCCR_CCM)) | + ((((uint32_t)palettep->length - 1) << 8) & DMA2D_FGPFCCR_CS) | + ((uint32_t)palettep->fmt << 4) + ); dma2dp->state = DMA2D_ACTIVE; DMA2D->FGPFCCR |= DMA2D_FGPFCCR_START; @@ -2616,8 +2621,8 @@ void dma2dOutSetWrapOffsetI(DMA2DDriver *dma2dp, size_t offset) { osalDbgAssert(offset <= DMA2D_MAX_OFFSET, "bounds"); (void)dma2dp; - DMA2D->OOR = (DMA2D->OOR & ~DMA2D_OOR_LO) | - ((uint32_t)offset & DMA2D_OOR_LO); + DMA2D->OOR = ((DMA2D->OOR & ~DMA2D_OOR_LO) | + ((uint32_t)offset & DMA2D_OOR_LO)); } /** @@ -2693,8 +2698,8 @@ void dma2dOutSetPixelFormatI(DMA2DDriver *dma2dp, dma2d_pixfmt_t fmt) { osalDbgAssert(fmt <= DMA2D_MAX_OUTPIXFMT_ID, "bounds"); (void)dma2dp; - DMA2D->OPFCCR = (DMA2D->OPFCCR & ~DMA2D_OPFCCR_CM) | - ((uint32_t)fmt & DMA2D_OPFCCR_CM); + DMA2D->OPFCCR = ((DMA2D->OPFCCR & ~DMA2D_OPFCCR_CM) | + ((uint32_t)fmt & DMA2D_OPFCCR_CM)); } /** @@ -2999,44 +3004,44 @@ dma2d_color_t dma2dFromARGB8888(dma2d_color_t c, dma2d_pixfmt_t fmt) { return c; } case DMA2D_FMT_RGB888: { - return c & 0x00FFFFFF; + return (c & 0x00FFFFFF); } case DMA2D_FMT_RGB565: { - return ((c & 0x000000F8) >> ( 8 - 5)) | - ((c & 0x0000FC00) >> (16 - 11)) | - ((c & 0x00F80000) >> (24 - 16)); + return (((c & 0x000000F8) >> ( 8 - 5)) | + ((c & 0x0000FC00) >> (16 - 11)) | + ((c & 0x00F80000) >> (24 - 16))); } case DMA2D_FMT_ARGB1555: { - return ((c & 0x000000F8) >> ( 8 - 5)) | - ((c & 0x0000F800) >> (16 - 10)) | - ((c & 0x00F80000) >> (24 - 15)) | - ((c & 0x80000000) >> (32 - 16)); + return (((c & 0x000000F8) >> ( 8 - 5)) | + ((c & 0x0000F800) >> (16 - 10)) | + ((c & 0x00F80000) >> (24 - 15)) | + ((c & 0x80000000) >> (32 - 16))); } case DMA2D_FMT_ARGB4444: { - return ((c & 0x000000F0) >> ( 8 - 4)) | - ((c & 0x0000F000) >> (16 - 8)) | - ((c & 0x00F00000) >> (24 - 12)) | - ((c & 0xF0000000) >> (32 - 16)); + return (((c & 0x000000F0) >> ( 8 - 4)) | + ((c & 0x0000F000) >> (16 - 8)) | + ((c & 0x00F00000) >> (24 - 12)) | + ((c & 0xF0000000) >> (32 - 16))); } case DMA2D_FMT_L8: { - return c & 0x000000FF; + return (c & 0x000000FF); } case DMA2D_FMT_AL44: { - return ((c & 0x000000F0) >> ( 8 - 4)) | - ((c & 0xF0000000) >> (32 - 8)); + return (((c & 0x000000F0) >> ( 8 - 4)) | + ((c & 0xF0000000) >> (32 - 8))); } case DMA2D_FMT_AL88: { - return ((c & 0x000000FF) >> ( 8 - 8)) | - ((c & 0xFF000000) >> (32 - 16)); + return (((c & 0x000000FF) >> ( 8 - 8)) | + ((c & 0xFF000000) >> (32 - 16))); } case DMA2D_FMT_L4: { - return c & 0x0000000F; + return (c & 0x0000000F); } case DMA2D_FMT_A8: { - return (c & 0xFF000000) >> (32 - 8); + return ((c & 0xFF000000) >> (32 - 8)); } case DMA2D_FMT_A4: { - return (c & 0xF0000000) >> (32 - 4); + return ((c & 0xF0000000) >> (32 - 4)); } default: osalDbgAssert(false, "invalid format"); @@ -3063,29 +3068,29 @@ dma2d_color_t dma2dToARGB8888(dma2d_color_t c, dma2d_pixfmt_t fmt) { return c; } case DMA2D_FMT_RGB888: { - return (c & 0x00FFFFFF) | 0xFF000000; + return ((c & 0x00FFFFFF) | 0xFF000000); } case DMA2D_FMT_RGB565: { register dma2d_color_t output = 0xFF000000; - if (c & 0x001F) output |= ((c & 0x001F) << ( 8 - 5)) | 0x00000007; - if (c & 0x07E0) output |= ((c & 0x07E0) << (16 - 11)) | 0x00000300; - if (c & 0xF800) output |= ((c & 0xF800) << (24 - 16)) | 0x00070000; + if (c & 0x001F) output |= (((c & 0x001F) << ( 8 - 5)) | 0x00000007); + if (c & 0x07E0) output |= (((c & 0x07E0) << (16 - 11)) | 0x00000300); + if (c & 0xF800) output |= (((c & 0xF800) << (24 - 16)) | 0x00070000); return output; } case DMA2D_FMT_ARGB1555: { register dma2d_color_t output = 0x00000000; - if (c & 0x001F) output |= ((c & 0x001F) << ( 8 - 5)) | 0x00000007; - if (c & 0x03E0) output |= ((c & 0x03E0) << (16 - 10)) | 0x00000700; - if (c & 0x7C00) output |= ((c & 0x7C00) << (24 - 15)) | 0x00070000; + if (c & 0x001F) output |= (((c & 0x001F) << ( 8 - 5)) | 0x00000007); + if (c & 0x03E0) output |= (((c & 0x03E0) << (16 - 10)) | 0x00000700); + if (c & 0x7C00) output |= (((c & 0x7C00) << (24 - 15)) | 0x00070000); if (c & 0x8000) output |= 0xFF000000; return output; } case DMA2D_FMT_ARGB4444: { register dma2d_color_t output = 0x00000000; - if (c & 0x000F) output |= ((c & 0x000F) << ( 8 - 4)) | 0x0000000F; - if (c & 0x00F0) output |= ((c & 0x00F0) << (16 - 8)) | 0x00000F00; - if (c & 0x0F00) output |= ((c & 0x0F00) << (24 - 12)) | 0x000F0000; - if (c & 0xF000) output |= ((c & 0xF000) << (32 - 16)) | 0x0F000000; + if (c & 0x000F) output |= (((c & 0x000F) << ( 8 - 4)) | 0x0000000F); + if (c & 0x00F0) output |= (((c & 0x00F0) << (16 - 8)) | 0x00000F00); + if (c & 0x0F00) output |= (((c & 0x0F00) << (24 - 12)) | 0x000F0000); + if (c & 0xF000) output |= (((c & 0xF000) << (32 - 16)) | 0x0F000000); return output; } case DMA2D_FMT_L8: { @@ -3093,22 +3098,22 @@ dma2d_color_t dma2dToARGB8888(dma2d_color_t c, dma2d_pixfmt_t fmt) { } case DMA2D_FMT_AL44: { register dma2d_color_t output = 0x00000000; - if (c & 0x0F) output |= ((c & 0x0F) << ( 8 - 4)) | 0x0000000F; - if (c & 0xF0) output |= ((c & 0xF0) << (32 - 8)) | 0x0F000000; + if (c & 0x0F) output |= (((c & 0x0F) << ( 8 - 4)) | 0x0000000F); + if (c & 0xF0) output |= (((c & 0xF0) << (32 - 8)) | 0x0F000000); return output; } case DMA2D_FMT_AL88: { - return ((c & 0x00FF) << ( 8 - 8)) | - ((c & 0xFF00) << (32 - 16)); + return (((c & 0x00FF) << ( 8 - 8)) | + ((c & 0xFF00) << (32 - 16))); } case DMA2D_FMT_L4: { - return (c & 0x0F) | 0xFF000000; + return ((c & 0x0F) | 0xFF000000); } case DMA2D_FMT_A8: { - return (c & 0xFF) << (32 - 8); + return ((c & 0xFF) << (32 - 8)); } case DMA2D_FMT_A4: { - return (c & 0x0F) << (32 - 4); + return ((c & 0x0F) << (32 - 4)); } default: osalDbgAssert(false, "invalid format"); diff --git a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h index c5aa159..29efa71 100644 --- a/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h +++ b/os/hal/ports/STM32/LLD/DMA2Dv1/stm32_dma2d.h @@ -29,7 +29,7 @@ * @brief Using the DMA2D driver. */ #if !defined(STM32_DMA2D_USE_DMA2D) || defined(__DOXYGEN__) -#define STM32_DMA2D_USE_DMA2D FALSE +#define STM32_DMA2D_USE_DMA2D (FALSE) #endif #if (TRUE == STM32_DMA2D_USE_DMA2D) || defined(__DOXYGEN__) @@ -261,7 +261,7 @@ typedef uint32_t dma2d_color_t; /** * @brief DMA2D color aliases. * @detail Mapped with ARGB-8888, except for luminance (L mapped onto B). - * Padding fields prefixed with 'x', which should be clear + * Padding fields are prefixed with 'x', and should be clear * (all 0) before compression and set (all 1) after expansion. */ typedef union dma2d_coloralias_t { diff --git a/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c index c7cabfc..72c9d06 100644 --- a/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c +++ b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.c @@ -337,8 +337,8 @@ void ltdcStart(LTDCDriver *ltdcp, const LTDCConfig *configp) { hacc = configp->hsync_width - 1; vacc = configp->vsync_height - 1; - LTDC->SSCR = ((hacc << 16) & LTDC_SSCR_HSW) | - ((vacc << 0) & LTDC_SSCR_VSH); + LTDC->SSCR = (((hacc << 16) & LTDC_SSCR_HSW) | + ((vacc << 0) & LTDC_SSCR_VSH)); /* Set accumulated back porch params.*/ osalDbgAssert(configp->hbp_width >= LTDC_MIN_HBP_WIDTH, "bounds"); @@ -354,8 +354,8 @@ void ltdcStart(LTDCDriver *ltdcp, const LTDCConfig *configp) { osalDbgAssert(vacc + 1 >= LTDC_MIN_ACC_VBP_HEIGHT, "bounds"); osalDbgAssert(vacc + 1 <= LTDC_MAX_ACC_VBP_HEIGHT, "bounds"); - LTDC->BPCR = ((hacc << 16) & LTDC_BPCR_AHBP) | - ((vacc << 0) & LTDC_BPCR_AVBP); + LTDC->BPCR = (((hacc << 16) & LTDC_BPCR_AHBP) | + ((vacc << 0) & LTDC_BPCR_AVBP)); ltdcp->active_window.hstart = hacc + 1; ltdcp->active_window.vstart = vacc + 1; @@ -374,8 +374,8 @@ void ltdcStart(LTDCDriver *ltdcp, const LTDCConfig *configp) { osalDbgAssert(vacc + 1 >= LTDC_MIN_ACC_ACTIVE_HEIGHT, "bounds"); osalDbgAssert(vacc + 1 <= LTDC_MAX_ACC_ACTIVE_HEIGHT, "bounds"); - LTDC->AWCR = ((hacc << 16) & LTDC_AWCR_AAW) | - ((vacc << 0) & LTDC_AWCR_AAH); + LTDC->AWCR = (((hacc << 16) & LTDC_AWCR_AAW) | + ((vacc << 0) & LTDC_AWCR_AAH)); ltdcp->active_window.hstop = hacc; ltdcp->active_window.vstop = vacc; @@ -394,8 +394,8 @@ void ltdcStart(LTDCDriver *ltdcp, const LTDCConfig *configp) { osalDbgAssert(vacc + 1 >= LTDC_MIN_ACC_TOTAL_HEIGHT, "bounds"); osalDbgAssert(vacc + 1 <= LTDC_MAX_ACC_TOTAL_HEIGHT, "bounds"); - LTDC->TWCR = ((hacc << 16) & LTDC_TWCR_TOTALW) | - ((vacc << 0) & LTDC_TWCR_TOTALH); + LTDC->TWCR = (((hacc << 16) & LTDC_TWCR_TOTALW) | + ((vacc << 0) & LTDC_TWCR_TOTALH)); /* Set signal polarities and other flags.*/ ltdcSetEnableFlagsI(ltdcp, configp->flags & ~LTDC_EF_ENABLE); @@ -980,8 +980,8 @@ void ltdcSetLineInterruptPosI(LTDCDriver *ltdcp, uint16_t line) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC->LIPCR = (LTDC->LIPCR & ~LTDC_LIPCR_LIPOS) | - ((uint32_t)line & LTDC_LIPCR_LIPOS); + LTDC->LIPCR = ((LTDC->LIPCR & ~LTDC_LIPCR_LIPOS) | + ((uint32_t)line & LTDC_LIPCR_LIPOS)); } /** @@ -1203,8 +1203,8 @@ void ltdcBgSetEnableFlagsI(LTDCDriver *ltdcp, ltdc_flags_t flags) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC_Layer1->CR = (LTDC_Layer1->CR & ~LTDC_LEF_MASK) | - ((uint32_t)flags & LTDC_LEF_MASK); + LTDC_Layer1->CR = ((LTDC_Layer1->CR & ~LTDC_LEF_MASK) | + ((uint32_t)flags & LTDC_LEF_MASK)); } /** @@ -1453,7 +1453,7 @@ void ltdcBgSetPaletteColorI(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c) { osalDbgAssert(!ltdcBgIsEnabledI(ltdcp), "invalid state"); (void)ltdcp; - LTDC_Layer1->CLUTWR = ((uint32_t)slot << 24) | (c & 0x00FFFFFF); + LTDC_Layer1->CLUTWR = (((uint32_t)slot << 24) | (c & 0x00FFFFFF)); } /** @@ -1499,7 +1499,7 @@ void ltdcBgSetPaletteI(LTDCDriver *ltdcp, const ltdc_color_t colors[], (void)ltdcp; for (i = 0; i < length; ++i) - LTDC_Layer1->CLUTWR = ((uint32_t)i << 24) | (colors[i] & 0x00FFFFFF); + LTDC_Layer1->CLUTWR = (((uint32_t)i << 24) | (colors[i] & 0x00FFFFFF)); } /** @@ -1576,8 +1576,8 @@ void ltdcBgSetPixelFormatI(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt) { osalDbgAssert(fmt <= LTDC_MAX_PIXFMT_ID, "bounds"); (void)ltdcp; - LTDC_Layer1->PFCR = (LTDC_Layer1->PFCR & ~LTDC_LxPFCR_PF) | - ((uint32_t)fmt & LTDC_LxPFCR_PF); + LTDC_Layer1->PFCR = ((LTDC_Layer1->PFCR & ~LTDC_LxPFCR_PF) | + ((uint32_t)fmt & LTDC_LxPFCR_PF)); } /** @@ -1755,8 +1755,8 @@ void ltdcBgSetKeyingColorI(LTDCDriver *ltdcp, ltdc_color_t c) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC_Layer1->CKCR = (LTDC_Layer1->CKCR & ~0x00FFFFFF) | - ((uint32_t)c & 0x00FFFFFF); + LTDC_Layer1->CKCR = ((LTDC_Layer1->CKCR & ~0x00FFFFFF) | + ((uint32_t)c & 0x00FFFFFF)); } /** @@ -1828,8 +1828,8 @@ void ltdcBgSetConstantAlphaI(LTDCDriver *ltdcp, uint8_t a) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC_Layer1->CACR = (LTDC_Layer1->CACR & ~LTDC_LxCACR_CONSTA) | - ((uint32_t)a & LTDC_LxCACR_CONSTA); + LTDC_Layer1->CACR = ((LTDC_Layer1->CACR & ~LTDC_LxCACR_CONSTA) | + ((uint32_t)a & LTDC_LxCACR_CONSTA)); } /** @@ -1973,8 +1973,8 @@ void ltdcBgSetBlendingFactorsI(LTDCDriver *ltdcp, ltdc_blendf_t bf) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC_Layer1->BFCR = (LTDC_Layer1->BFCR & ~LTDC_LxBFCR_BF) | - ((uint32_t)bf & LTDC_LxBFCR_BF); + LTDC_Layer1->BFCR = ((LTDC_Layer1->BFCR & ~LTDC_LxBFCR_BF) | + ((uint32_t)bf & LTDC_LxBFCR_BF)); } /** @@ -2063,8 +2063,8 @@ void ltdcBgSetWindowI(LTDCDriver *ltdcp, const ltdc_window_t *windowp) { osalDbgAssert(start >= ltdcp->active_window.hstart, "bounds"); osalDbgAssert(stop <= ltdcp->active_window.hstop, "bounds"); - LTDC_Layer1->WHPCR = ((start << 0) & LTDC_LxWHPCR_WHSTPOS) | - ((stop << 16) & LTDC_LxWHPCR_WHSPPOS); + LTDC_Layer1->WHPCR = (((start << 0) & LTDC_LxWHPCR_WHSTPOS) | + ((stop << 16) & LTDC_LxWHPCR_WHSPPOS)); /* Vertical boundaries.*/ start = (uint32_t)windowp->vstart + ltdcp->active_window.vstart; @@ -2073,8 +2073,8 @@ void ltdcBgSetWindowI(LTDCDriver *ltdcp, const ltdc_window_t *windowp) { osalDbgAssert(start >= ltdcp->active_window.vstart, "bounds"); osalDbgAssert(stop <= ltdcp->active_window.vstop, "bounds"); - LTDC_Layer1->WVPCR = ((start << 0) & LTDC_LxWVPCR_WVSTPOS) | - ((stop << 16) & LTDC_LxWVPCR_WVSPPOS); + LTDC_Layer1->WVPCR = (((start << 0) & LTDC_LxWVPCR_WVSTPOS) | + ((stop << 16) & LTDC_LxWVPCR_WVSPPOS)); } /** @@ -2199,7 +2199,7 @@ void ltdcBgSetFrameI(LTDCDriver *ltdcp, const ltdc_frame_t *framep) { LTDC_Layer1->CFBAR = (uint32_t)framep->bufferp & LTDC_LxCFBAR_CFBADD; LTDC_Layer1->CFBLR = ((((uint32_t)framep->pitch << 16) & LTDC_LxCFBLR_CFBP) | - ((linesize + 3) & LTDC_LxCFBLR_CFBLL)); + ((linesize + 3) & LTDC_LxCFBLR_CFBLL)); LTDC_Layer1->CFBLNR = (uint32_t)framep->height & LTDC_LxCFBLNR_CFBLNBR; } @@ -2453,8 +2453,8 @@ void ltdcFgSetEnableFlagsI(LTDCDriver *ltdcp, ltdc_flags_t flags) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC_Layer2->CR = (LTDC_Layer2->CR & ~LTDC_LEF_MASK) | - ((uint32_t)flags & LTDC_LEF_MASK); + LTDC_Layer2->CR = ((LTDC_Layer2->CR & ~LTDC_LEF_MASK) | + ((uint32_t)flags & LTDC_LEF_MASK)); } /** @@ -2703,7 +2703,7 @@ void ltdcFgSetPaletteColorI(LTDCDriver *ltdcp, uint8_t slot, ltdc_color_t c) { osalDbgAssert(!ltdcFgIsEnabledI(ltdcp), "invalid state"); (void)ltdcp; - LTDC_Layer2->CLUTWR = ((uint32_t)slot << 24) | (c & 0x00FFFFFF); + LTDC_Layer2->CLUTWR = (((uint32_t)slot << 24) | (c & 0x00FFFFFF)); } /** @@ -2749,7 +2749,7 @@ void ltdcFgSetPaletteI(LTDCDriver *ltdcp, const ltdc_color_t colors[], (void)ltdcp; for (i = 0; i < length; ++i) - LTDC_Layer2->CLUTWR = ((uint32_t)i << 24) | (colors[i] & 0x00FFFFFF); + LTDC_Layer2->CLUTWR = (((uint32_t)i << 24) | (colors[i] & 0x00FFFFFF)); } /** @@ -2826,8 +2826,8 @@ void ltdcFgSetPixelFormatI(LTDCDriver *ltdcp, ltdc_pixfmt_t fmt) { osalDbgAssert(fmt <= LTDC_MAX_PIXFMT_ID, "bounds"); (void)ltdcp; - LTDC_Layer2->PFCR = (LTDC_Layer2->PFCR & ~LTDC_LxPFCR_PF) | - ((uint32_t)fmt & LTDC_LxPFCR_PF); + LTDC_Layer2->PFCR = ((LTDC_Layer2->PFCR & ~LTDC_LxPFCR_PF) | + ((uint32_t)fmt & LTDC_LxPFCR_PF)); } /** @@ -3005,8 +3005,8 @@ void ltdcFgSetKeyingColorI(LTDCDriver *ltdcp, ltdc_color_t c) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC_Layer2->CKCR = (LTDC_Layer2->CKCR & ~0x00FFFFFF) | - ((uint32_t)c & 0x00FFFFFF); + LTDC_Layer2->CKCR = ((LTDC_Layer2->CKCR & ~0x00FFFFFF) | + ((uint32_t)c & 0x00FFFFFF)); } /** @@ -3078,8 +3078,8 @@ void ltdcFgSetConstantAlphaI(LTDCDriver *ltdcp, uint8_t a) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC_Layer2->CACR = (LTDC_Layer2->CACR & ~LTDC_LxCACR_CONSTA) | - ((uint32_t)a & LTDC_LxCACR_CONSTA); + LTDC_Layer2->CACR = ((LTDC_Layer2->CACR & ~LTDC_LxCACR_CONSTA) | + ((uint32_t)a & LTDC_LxCACR_CONSTA)); } /** @@ -3223,8 +3223,8 @@ void ltdcFgSetBlendingFactorsI(LTDCDriver *ltdcp, ltdc_blendf_t bf) { osalDbgCheck(ltdcp == <DCD1); (void)ltdcp; - LTDC_Layer2->BFCR = (LTDC_Layer2->BFCR & ~LTDC_LxBFCR_BF) | - ((uint32_t)bf & LTDC_LxBFCR_BF); + LTDC_Layer2->BFCR = ((LTDC_Layer2->BFCR & ~LTDC_LxBFCR_BF) | + ((uint32_t)bf & LTDC_LxBFCR_BF)); } /** @@ -3313,8 +3313,8 @@ void ltdcFgSetWindowI(LTDCDriver *ltdcp, const ltdc_window_t *windowp) { osalDbgAssert(start >= ltdcp->active_window.hstart, "bounds"); osalDbgAssert(stop <= ltdcp->active_window.hstop, "bounds"); - LTDC_Layer2->WHPCR = ((start << 0) & LTDC_LxWHPCR_WHSTPOS) | - ((stop << 16) & LTDC_LxWHPCR_WHSPPOS); + LTDC_Layer2->WHPCR = (((start << 0) & LTDC_LxWHPCR_WHSTPOS) | + ((stop << 16) & LTDC_LxWHPCR_WHSPPOS)); /* Vertical boundaries.*/ start = (uint32_t)windowp->vstart + ltdcp->active_window.vstart; @@ -3323,8 +3323,8 @@ void ltdcFgSetWindowI(LTDCDriver *ltdcp, const ltdc_window_t *windowp) { osalDbgAssert(start >= ltdcp->active_window.vstart, "bounds"); osalDbgAssert(stop <= ltdcp->active_window.vstop, "bounds"); - LTDC_Layer2->WVPCR = ((start << 0) & LTDC_LxWVPCR_WVSTPOS) | - ((stop << 16) & LTDC_LxWVPCR_WVSPPOS); + LTDC_Layer2->WVPCR = (((start << 0) & LTDC_LxWVPCR_WVSTPOS) | + ((stop << 16) & LTDC_LxWVPCR_WVSPPOS)); } /** @@ -3449,7 +3449,7 @@ void ltdcFgSetFrameI(LTDCDriver *ltdcp, const ltdc_frame_t *framep) { LTDC_Layer2->CFBAR = (uint32_t)framep->bufferp & LTDC_LxCFBAR_CFBADD; LTDC_Layer2->CFBLR = ((((uint32_t)framep->pitch << 16) & LTDC_LxCFBLR_CFBP) | - ((linesize + 3) & LTDC_LxCFBLR_CFBLL)); + ((linesize + 3) & LTDC_LxCFBLR_CFBLL)); LTDC_Layer2->CFBLNR = (uint32_t)framep->height & LTDC_LxCFBLNR_CFBLNBR; } @@ -3684,35 +3684,35 @@ ltdc_color_t ltdcFromARGB8888(ltdc_color_t c, ltdc_pixfmt_t fmt) { return c; } case LTDC_FMT_RGB888: { - return c & 0x00FFFFFF; + return (c & 0x00FFFFFF); } case LTDC_FMT_RGB565: { - return ((c & 0x000000F8) >> ( 8 - 5)) | - ((c & 0x0000FC00) >> (16 - 11)) | - ((c & 0x00F80000) >> (24 - 16)); + return (((c & 0x000000F8) >> ( 8 - 5)) | + ((c & 0x0000FC00) >> (16 - 11)) | + ((c & 0x00F80000) >> (24 - 16))); } case LTDC_FMT_ARGB1555: { - return ((c & 0x000000F8) >> ( 8 - 5)) | - ((c & 0x0000F800) >> (16 - 10)) | - ((c & 0x00F80000) >> (24 - 15)) | - ((c & 0x80000000) >> (32 - 16)); + return (((c & 0x000000F8) >> ( 8 - 5)) | + ((c & 0x0000F800) >> (16 - 10)) | + ((c & 0x00F80000) >> (24 - 15)) | + ((c & 0x80000000) >> (32 - 16))); } case LTDC_FMT_ARGB4444: { - return ((c & 0x000000F0) >> ( 8 - 4)) | - ((c & 0x0000F000) >> (16 - 8)) | - ((c & 0x00F00000) >> (24 - 12)) | - ((c & 0xF0000000) >> (32 - 16)); + return (((c & 0x000000F0) >> ( 8 - 4)) | + ((c & 0x0000F000) >> (16 - 8)) | + ((c & 0x00F00000) >> (24 - 12)) | + ((c & 0xF0000000) >> (32 - 16))); } case LTDC_FMT_L8: { - return c & 0x000000FF; + return (c & 0x000000FF); } case LTDC_FMT_AL44: { - return ((c & 0x000000F0) >> ( 8 - 4)) | - ((c & 0xF0000000) >> (32 - 8)); + return (((c & 0x000000F0) >> ( 8 - 4)) | + ((c & 0xF0000000) >> (32 - 8))); } case LTDC_FMT_AL88: { - return ((c & 0x000000FF) >> ( 8 - 8)) | - ((c & 0xFF000000) >> (32 - 16)); + return (((c & 0x000000FF) >> ( 8 - 8)) | + ((c & 0xFF000000) >> (32 - 16))); } default: osalDbgAssert(false, "invalid format"); @@ -3739,43 +3739,43 @@ ltdc_color_t ltdcToARGB8888(ltdc_color_t c, ltdc_pixfmt_t fmt) { return c; } case LTDC_FMT_RGB888: { - return (c & 0x00FFFFFF) | 0xFF000000; + return ((c & 0x00FFFFFF) | 0xFF000000); } case LTDC_FMT_RGB565: { register ltdc_color_t output = 0xFF000000; - if (c & 0x001F) output |= ((c & 0x001F) << ( 8 - 5)) | 0x00000007; - if (c & 0x07E0) output |= ((c & 0x07E0) << (16 - 11)) | 0x00000300; - if (c & 0xF800) output |= ((c & 0xF800) << (24 - 16)) | 0x00070000; + if (c & 0x001F) output |= (((c & 0x001F) << ( 8 - 5)) | 0x00000007); + if (c & 0x07E0) output |= (((c & 0x07E0) << (16 - 11)) | 0x00000300); + if (c & 0xF800) output |= (((c & 0xF800) << (24 - 16)) | 0x00070000); return output; } case LTDC_FMT_ARGB1555: { register ltdc_color_t output = 0x00000000; - if (c & 0x001F) output |= ((c & 0x001F) << ( 8 - 5)) | 0x00000007; - if (c & 0x03E0) output |= ((c & 0x03E0) << (16 - 10)) | 0x00000700; - if (c & 0x7C00) output |= ((c & 0x7C00) << (24 - 15)) | 0x00070000; + if (c & 0x001F) output |= (((c & 0x001F) << ( 8 - 5)) | 0x00000007); + if (c & 0x03E0) output |= (((c & 0x03E0) << (16 - 10)) | 0x00000700); + if (c & 0x7C00) output |= (((c & 0x7C00) << (24 - 15)) | 0x00070000); if (c & 0x8000) output |= 0xFF000000; return output; } case LTDC_FMT_ARGB4444: { register ltdc_color_t output = 0x00000000; - if (c & 0x000F) output |= ((c & 0x000F) << ( 8 - 4)) | 0x0000000F; - if (c & 0x00F0) output |= ((c & 0x00F0) << (16 - 8)) | 0x00000F00; - if (c & 0x0F00) output |= ((c & 0x0F00) << (24 - 12)) | 0x000F0000; - if (c & 0xF000) output |= ((c & 0xF000) << (32 - 16)) | 0x0F000000; + if (c & 0x000F) output |= (((c & 0x000F) << ( 8 - 4)) | 0x0000000F); + if (c & 0x00F0) output |= (((c & 0x00F0) << (16 - 8)) | 0x00000F00); + if (c & 0x0F00) output |= (((c & 0x0F00) << (24 - 12)) | 0x000F0000); + if (c & 0xF000) output |= (((c & 0xF000) << (32 - 16)) | 0x0F000000); return output; } case LTDC_FMT_L8: { - return (c & 0xFF) | 0xFF000000; + return ((c & 0xFF) | 0xFF000000); } case LTDC_FMT_AL44: { register ltdc_color_t output = 0x00000000; - if (c & 0x0F) output |= ((c & 0x0F) << ( 8 - 4)) | 0x0000000F; - if (c & 0xF0) output |= ((c & 0xF0) << (32 - 8)) | 0x0F000000; + if (c & 0x0F) output |= (((c & 0x0F) << ( 8 - 4)) | 0x0000000F); + if (c & 0xF0) output |= (((c & 0xF0) << (32 - 8)) | 0x0F000000); return output; } case LTDC_FMT_AL88: { - return ((c & 0x00FF) << ( 8 - 8)) | - ((c & 0xFF00) << (32 - 16)); + return (((c & 0x00FF) << ( 8 - 8)) | + ((c & 0xFF00) << (32 - 16))); } default: osalDbgAssert(false, "invalid format"); diff --git a/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h index 00af038..fdf1f5b 100644 --- a/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h +++ b/os/hal/ports/STM32/LLD/LTDCv1/stm32_ltdc.h @@ -29,7 +29,7 @@ * @brief Using the LTDC driver. */ #if !defined(STM32_LTDC_USE_LTDC) || defined(__DOXYGEN__) -#define STM32_LTDC_USE_LTDC FALSE +#define STM32_LTDC_USE_LTDC (FALSE) #endif #if (TRUE == STM32_LTDC_USE_LTDC) || defined(__DOXYGEN__) @@ -70,38 +70,38 @@ * @name LTDC pixel formats * @{ */ -#define LTDC_FMT_ARGB8888 0 /**< ARGB-8888 format.*/ -#define LTDC_FMT_RGB888 1 /**< RGB-888 format.*/ -#define LTDC_FMT_RGB565 2 /**< RGB-565 format.*/ -#define LTDC_FMT_ARGB1555 3 /**< ARGB-1555 format.*/ -#define LTDC_FMT_ARGB4444 4 /**< ARGB-4444 format.*/ -#define LTDC_FMT_L8 5 /**< L-8 format.*/ -#define LTDC_FMT_AL44 6 /**< AL-44 format.*/ -#define LTDC_FMT_AL88 7 /**< AL-88 format.*/ +#define LTDC_FMT_ARGB8888 (0) /**< ARGB-8888 format.*/ +#define LTDC_FMT_RGB888 (1) /**< RGB-888 format.*/ +#define LTDC_FMT_RGB565 (2) /**< RGB-565 format.*/ +#define LTDC_FMT_ARGB1555 (3) /**< ARGB-1555 format.*/ +#define LTDC_FMT_ARGB4444 (4) /**< ARGB-4444 format.*/ +#define LTDC_FMT_L8 (5) /**< L-8 format.*/ +#define LTDC_FMT_AL44 (6) /**< AL-44 format.*/ +#define LTDC_FMT_AL88 (7) /**< AL-88 format.*/ /** @} */ /** * @name LTDC pixel format aliased raw masks * @{ */ -#define LTDC_XMASK_ARGB8888 0xFFFFFFFF /**< ARGB-8888 aliased mask.*/ -#define LTDC_XMASK_RGB888 0x00FFFFFF /**< RGB-888 aliased mask.*/ -#define LTDC_XMASK_RGB565 0x00F8FCF8 /**< RGB-565 aliased mask.*/ -#define LTDC_XMASK_ARGB1555 0x80F8F8F8 /**< ARGB-1555 aliased mask.*/ -#define LTDC_XMASK_ARGB4444 0xF0F0F0F0 /**< ARGB-4444 aliased mask.*/ -#define LTDC_XMASK_L8 0x000000FF /**< L-8 aliased mask.*/ -#define LTDC_XMASK_AL44 0xF00000F0 /**< AL-44 aliased mask.*/ -#define LTDC_XMASK_AL88 0xFF0000FF /**< AL-88 aliased mask.*/ +#define LTDC_XMASK_ARGB8888 (0xFFFFFFFF) /**< ARGB-8888 aliased mask.*/ +#define LTDC_XMASK_RGB888 (0x00FFFFFF) /**< RGB-888 aliased mask.*/ +#define LTDC_XMASK_RGB565 (0x00F8FCF8) /**< RGB-565 aliased mask.*/ +#define LTDC_XMASK_ARGB1555 (0x80F8F8F8) /**< ARGB-1555 aliased mask.*/ +#define LTDC_XMASK_ARGB4444 (0xF0F0F0F0) /**< ARGB-4444 aliased mask.*/ +#define LTDC_XMASK_L8 (0x000000FF) /**< L-8 aliased mask.*/ +#define LTDC_XMASK_AL44 (0xF00000F0) /**< AL-44 aliased mask.*/ +#define LTDC_XMASK_AL88 (0xFF0000FF) /**< AL-88 aliased mask.*/ /** @} */ /** * @name LTDC blending factors * @{ */ -#define LTDC_BLEND_FIX1_FIX2 0x0405 /**< cnst1; 1 - cnst2 */ -#define LTDC_BLEND_FIX1_MOD2 0x0407 /**< cnst1; 1 - a2 * cnst2 */ -#define LTDC_BLEND_MOD1_FIX2 0x0605 /**< a1 * cnst1; 1 - cnst2 */ -#define LTDC_BLEND_MOD1_MOD2 0x0607 /**< a1 * cnst1; 1 - a2 * cnst2 */ +#define LTDC_BLEND_FIX1_FIX2 (0x0405) /**< cnst1; 1 - cnst2 */ +#define LTDC_BLEND_FIX1_MOD2 (0x0407) /**< cnst1; 1 - a2 * cnst2 */ +#define LTDC_BLEND_MOD1_FIX2 (0x0605) /**< a1 * cnst1; 1 - cnst2 */ +#define LTDC_BLEND_MOD1_MOD2 (0x0607) /**< a1 * cnst1; 1 - a2 * cnst2 */ /** @} */ /** @@ -109,70 +109,70 @@ * @{ */ -#define LTDC_MIN_SCREEN_WIDTH 1 -#define LTDC_MIN_SCREEN_HEIGHT 1 -#define LTDC_MAX_SCREEN_WIDTH 800 -#define LTDC_MAX_SCREEN_HEIGHT 600 +#define LTDC_MIN_SCREEN_WIDTH (1) +#define LTDC_MIN_SCREEN_HEIGHT (1) +#define LTDC_MAX_SCREEN_WIDTH (800) +#define LTDC_MAX_SCREEN_HEIGHT (600) -#define LTDC_MIN_HSYNC_WIDTH 1 -#define LTDC_MIN_VSYNC_HEIGHT 1 +#define LTDC_MIN_HSYNC_WIDTH (1) +#define LTDC_MIN_VSYNC_HEIGHT (1) #define LTDC_MAX_HSYNC_WIDTH (1 << 12) #define LTDC_MAX_VSYNC_HEIGHT (1 << 11) -#define LTDC_MIN_HBP_WIDTH 0 -#define LTDC_MIN_VBP_HEIGHT 0 +#define LTDC_MIN_HBP_WIDTH (0) +#define LTDC_MIN_VBP_HEIGHT (0) #define LTDC_MAX_HBP_WIDTH (1 << 12) #define LTDC_MAX_VBP_HEIGHT (1 << 11) -#define LTDC_MIN_ACC_HBP_WIDTH 1 -#define LTDC_MIN_ACC_VBP_HEIGHT 1 +#define LTDC_MIN_ACC_HBP_WIDTH (1) +#define LTDC_MIN_ACC_VBP_HEIGHT (1) #define LTDC_MAX_ACC_HBP_WIDTH (1 << 12) #define LTDC_MAX_ACC_VBP_HEIGHT (1 << 11) -#define LTDC_MIN_HFP_WIDTH 0 -#define LTDC_MIN_VFP_HEIGHT 0 +#define LTDC_MIN_HFP_WIDTH (0) +#define LTDC_MIN_VFP_HEIGHT (0) #define LTDC_MAX_HFP_WIDTH (1 << 12) #define LTDC_MAX_VFP_HEIGHT (1 << 11) -#define LTDC_MIN_ACTIVE_WIDTH 0 -#define LTDC_MIN_ACTIVE_HEIGHT 0 +#define LTDC_MIN_ACTIVE_WIDTH (0) +#define LTDC_MIN_ACTIVE_HEIGHT (0) #define LTDC_MAX_ACTIVE_WIDTH (1 << 12) #define LTDC_MAX_ACTIVE_HEIGHT (1 << 11) -#define LTDC_MIN_ACC_ACTIVE_WIDTH 1 -#define LTDC_MIN_ACC_ACTIVE_HEIGHT 1 +#define LTDC_MIN_ACC_ACTIVE_WIDTH (1) +#define LTDC_MIN_ACC_ACTIVE_HEIGHT (1) #define LTDC_MAX_ACC_ACTIVE_WIDTH (1 << 12) #define LTDC_MAX_ACC_ACTIVE_HEIGHT (1 << 11) -#define LTDC_MIN_ACC_TOTAL_WIDTH 1 -#define LTDC_MIN_ACC_TOTAL_HEIGHT 1 +#define LTDC_MIN_ACC_TOTAL_WIDTH (1) +#define LTDC_MIN_ACC_TOTAL_HEIGHT (1) #define LTDC_MAX_ACC_TOTAL_WIDTH (1 << 12) #define LTDC_MAX_ACC_TOTAL_HEIGHT (1 << 11) -#define LTDC_MIN_LINE_INTERRUPT_POS 0 +#define LTDC_MIN_LINE_INTERRUPT_POS (0) #define LTDC_MAX_LINE_INTERRUPT_POS ((1 << 11) - 1) -#define LTDC_MIN_WINDOW_HSTART 0 -#define LTDC_MIN_WINDOW_HSTART 0 +#define LTDC_MIN_WINDOW_HSTART (0) +#define LTDC_MIN_WINDOW_HSTART (0) #define LTDC_MAX_WINDOW_HSTOP ((1 << 12) - 1) #define LTDC_MAX_WINDOW_HSTOP ((1 << 12) - 1) -#define LTDC_MIN_WINDOW_VSTART 0 -#define LTDC_MIN_WINDOW_VSTART 0 +#define LTDC_MIN_WINDOW_VSTART (0) +#define LTDC_MIN_WINDOW_VSTART (0) #define LTDC_MAX_WINDOW_VSTOP ((1 << 11) - 1) #define LTDC_MAX_WINDOW_VSTOP ((1 << 11) - 1) -#define LTDC_MIN_FRAME_WIDTH_BYTES 0 -#define LTDC_MIN_FRAME_HEIGHT_LINES 0 -#define LTDC_MIN_FRAME_PITCH_BYTES 0 +#define LTDC_MIN_FRAME_WIDTH_BYTES (0) +#define LTDC_MIN_FRAME_HEIGHT_LINES (0) +#define LTDC_MIN_FRAME_PITCH_BYTES (0) #define LTDC_MAX_FRAME_WIDTH_BYTES ((1 << 13) - 1 - 3) #define LTDC_MAX_FRAME_HEIGHT_LINES ((1 << 11) - 1) #define LTDC_MAX_FRAME_PITCH_BYTES ((1 << 13) - 1) -#define LTDC_MIN_PIXFMT_ID 0 -#define LTDC_MAX_PIXFMT_ID 7 +#define LTDC_MIN_PIXFMT_ID (0) +#define LTDC_MAX_PIXFMT_ID (7) -#define LTDC_MAX_PALETTE_LENGTH 256 +#define LTDC_MAX_PALETTE_LENGTH (256) /** @} */ @@ -181,22 +181,22 @@ * @{ */ /* Microsoft Windows default 16-color palette.*/ -#define LTDC_COLOR_BLACK 0xFF000000 -#define LTDC_COLOR_MAROON 0xFF800000 -#define LTDC_COLOR_GREEN 0xFF008000 -#define LTDC_COLOR_OLIVE 0xFF808000 -#define LTDC_COLOR_NAVY 0xFF000080 -#define LTDC_COLOR_PURPLE 0xFF800080 -#define LTDC_COLOR_TEAL 0xFF008080 -#define LTDC_COLOR_SILVER 0xFFC0C0C0 -#define LTDC_COLOR_GRAY 0xFF808080 -#define LTDC_COLOR_RED 0xFFFF0000 -#define LTDC_COLOR_LIME 0xFF00FF00 -#define LTDC_COLOR_YELLOW 0xFFFFFF00 -#define LTDC_COLOR_BLUE 0xFF0000FF -#define LTDC_COLOR_FUCHSIA 0xFFFF00FF -#define LTDC_COLOR_AQUA 0xFF00FFFF -#define LTDC_COLOR_WHITE 0xFFFFFFFF +#define LTDC_COLOR_BLACK (0xFF000000) +#define LTDC_COLOR_MAROON (0xFF800000) +#define LTDC_COLOR_GREEN (0xFF008000) +#define LTDC_COLOR_OLIVE (0xFF808000) +#define LTDC_COLOR_NAVY (0xFF000080) +#define LTDC_COLOR_PURPLE (0xFF800080) +#define LTDC_COLOR_TEAL (0xFF008080) +#define LTDC_COLOR_SILVER (0xFFC0C0C0) +#define LTDC_COLOR_GRAY (0xFF808080) +#define LTDC_COLOR_RED (0xFFFF0000) +#define LTDC_COLOR_LIME (0xFF00FF00) +#define LTDC_COLOR_YELLOW (0xFFFFFF00) +#define LTDC_COLOR_BLUE (0xFF0000FF) +#define LTDC_COLOR_FUCHSIA (0xFFFF00FF) +#define LTDC_COLOR_AQUA (0xFF00FFFF) +#define LTDC_COLOR_WHITE (0xFFFFFFFF) /** @} */ /*===========================================================================*/ @@ -212,14 +212,14 @@ * @brief LTDC event interrupt priority level setting. */ #if !defined(STM32_LTDC_EV_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_LTDC_EV_IRQ_PRIORITY 11 +#define STM32_LTDC_EV_IRQ_PRIORITY (11) #endif /** * @brief LTDC error interrupt priority level setting. */ #if !defined(STM32_LTDC_ER_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define STM32_LTDC_ER_IRQ_PRIORITY 11 +#define STM32_LTDC_ER_IRQ_PRIORITY (11) #endif /** @@ -227,7 +227,7 @@ * @note Disabling this option saves both code and data space. */ #if !defined(LTDC_USE_WAIT) || defined(__DOXYGEN__) -#define LTDC_USE_WAIT TRUE +#define LTDC_USE_WAIT (TRUE) #endif /** @@ -235,7 +235,7 @@ * @note Disabling this option saves both code and data space. */ #if !defined(LTDC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) -#define LTDC_USE_MUTUAL_EXCLUSION TRUE +#define LTDC_USE_MUTUAL_EXCLUSION (TRUE) #endif /** @@ -243,7 +243,7 @@ * @note Disabling this option saves both code and data space. */ #if !defined(LTDC_USE_SOFTWARE_CONVERSIONS) || defined(__DOXYGEN__) -#define LTDC_USE_SOFTWARE_CONVERSIONS TRUE +#define LTDC_USE_SOFTWARE_CONVERSIONS (TRUE) #endif /** @@ -252,7 +252,7 @@ * @note Disabling checks by ChibiOS will automatically disable LTDC checks. */ #if !defined(LTDC_USE_CHECKS) || defined(__DOXYGEN__) -#define LTDC_USE_CHECKS TRUE +#define LTDC_USE_CHECKS (TRUE) #endif /** @} */ @@ -301,7 +301,7 @@ typedef uint32_t ltdc_color_t; /** * @brief LTDC color aliases. * @detail Mapped with ARGB-8888, except for luminance (L mapped onto B). - * Padding fields prefixed with 'x', which should be clear + * Padding fields are prefixed with 'x', and should be clear * (all 0) before compression and set (all 1) after expansion. */ typedef union ltdc_coloralias_t { @@ -458,10 +458,10 @@ typedef struct LTDCConfig { * @brief LTDC driver state. */ typedef enum ltdc_state_t { - LTDC_UNINIT = 0, /**< Not initialized.*/ - LTDC_STOP = 1, /**< Stopped.*/ - LTDC_READY = 2, /**< Ready.*/ - LTDC_ACTIVE = 3, /**< Executing commands.*/ + LTDC_UNINIT = (0), /**< Not initialized.*/ + LTDC_STOP = (1), /**< Stopped.*/ + LTDC_READY = (2), /**< Ready.*/ + LTDC_ACTIVE = (3), /**< Executing commands.*/ } ltdc_state_t; /** -- cgit v1.2.3