3126 lines
80 KiB
C
3126 lines
80 KiB
C
/*
|
|
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 */
|