Kinetis SDK v.1.3 API Reference Manual  Rev. 0
Freescale Semiconductor, Inc.
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
FlexIO_Camera_EDMA Peripheral Driver

This section describes the programming interface of the FlexIO Camera with eDMA Peripheral driver.

FlexIO Camera with eDMA Peripheral Driver description

FlexIO Camera with eDMA provides a use case that shows how to map the image data from the camera's sensor matrix to the indicated memory area. In this module, a DMA channel inside the driver syncs the data from the camera to memory automatically in the background. The DMA channel is triggered after the FlexIO Camera's buffer is filled and updates the data for every trigger. In this instance, the the internal DMA and camera's data stream are not relevant to the application. The application reads the mapped image data as soon as possible with no blocking. Reading the memory corresponds to reading the camera's sensor matrix directly.

Note that, when using DMA to transfer data, because of the cache for memory, the data mist be consistent. This means that, when reading data from memory, the application must ensure that data from or to the memory device is not cached.

Usage of FlexIO Camera with eDMA Peripheral Driver

#include "fsl_edma_driver.h"
#include "fsl_flexio_camera_edma_driver.h"
#include "fsl_flexio_driver.h"
static volatile uint16_t u16CameraFrameBuffer[OV7670_FRAME_PIXELS];
//------------------------------------------------------------------------------
// DMA0 channel for LCD configuration structure.
// details This DMA channel ensure 16-bit (2 bytes) data transfers from the
// camera frame buffer to Flexbus (LCD SSD1289), which means
// 4800 (major loop) x 16 x 16-bit data transfers (32 bytes minor loops).
// These transfers ensure frame displaying.
// Data is transferred based on the shifter 0 status flag
// (all shifter full-filled by appropriate data).
//------------------------------------------------------------------------------
#define eDMA_LCD_CONFIG \
{ \
.srcAddr = (uint32_t)u16CameraFrameBuffer, \
.destAddr = (uint32_t)FLEX_BASE_ADDRESS, \
.srcTransferSize = kEDMATransferSize_2Bytes, \
.destTransferSize = kEDMATransferSize_2Bytes, \
.srcOffset = 2, \
.destOffset = 0, \
.srcLastAddrAdjust = -((sizeof(u16CameraFrameBuffer))), \
.destLastAddrAdjust = 0, \
.srcModulo = kEDMAModuloDisable, \
.destModulo = kEDMAModuloDisable, \
.minorLoopCount = 32, \
.majorLoopCount = ((sizeof(u16CameraFrameBuffer)>>5)), \
}
// eDMA configuration structure
edma_state_t edmaState;
// eDMA for LCD.
edma_chn_state_t lcdEdmaChnState;
edma_software_tcd_t lcdEdmaChnStcd[2];
edma_transfer_config_t lcdEdmeConfigStruct = eDMA_LCD_CONFIG;
volatile flexio_camera_edma_handler_t gFlexioCameraHandlerStruct;
static void port_vsync_callback(uint32_t pin);
int main(void)
{
ov7670_status_t ov7670_status;
uint32_t ret;
flexio_user_config_t flexioUserConfig =
{
.useInt = false,
.onDozeEnable = true,
.onDebugEnable = true,
.fastAccessEnable = true
};
edma_user_config_t edmaUserConfig =
{
.notHaltOnError = false
};
flexio_camera_user_config_t UserFlexioCameraConfigStruct =
{
.flexioInstance = 0U,
.datPinStartIdx = 24U, // fxio_pin 24-31 is used as data pin.
.pclkPinIdx = 1U, // fxio_pin 1 is used as PCLK pin.
.hrefPinIdx = 18U, // flexio_pin 18 is used as HREF pin.
.shifterStartIdx = 0U, // Shifters 0-7 are used as data buffers.
.timerIdx = 0U
};
camera_edma_user_config_t UserCameraEdmaConfigStruct =
{
.userEdmaChn = APP_EDMA_CHN_FOR_CAMERA,
.userBufAddr = (uint32_t)(u16CameraFrameBuffer),
.userBufLenByte = (uint32_t)(sizeof(u16CameraFrameBuffer))
};
// Initialize the hardware.
// ...
//-----------------------------------------------------------------------------
// Initialize the LCD (SSD1289) and the CAMERA (OV7670)
// ...
//-----------------------------------------------------------------------------
// Configure the FlexIO and eDMA
FLEXIO_DRV_Init(0U, &flexioUserConfig);
EDMA_DRV_Init(&edmaState, &edmaUserConfig);
//-----------------------------------------------------------------------------
// Configure the flexio_camera with eDMA.
ret = FLEXIO_Camera_DRV_InitEdmaRx(
(flexio_camera_edma_handler_t *)&gFlexioCameraHandlerStruct,
&UserFlexioCameraConfigStruct,
&UserCameraEdmaConfigStruct );
if (ret != kStatus_FlexIO_Camera_Success)
{
while (1); // The program would be dead here if error.
}
//-----------------------------------------------------------------------------
// Configure the flexio_camera's sync trigger for the LCD eDMA.
FLEXIO_Camera_DRV_SetBufferTriggerForExtEdma(
(flexio_camera_edma_handler_t *)&gFlexioCameraHandlerStruct,
0x03, true);
//-----------------------------------------------------------------------------
// Configure the eDMA for LCD.
APP_EDMA_CHN_FOR_LCD,
(dma_request_source_t)(kDmaRequestMux0Group1FlexIO0Channel0 + UserFlexioCameraConfigStruct.shifterStartIdx + 1U),
&lcdEdmaChnState);
if (ret == kEDMAInvalidChannel)
{
// The program crashes if the indicated channel is not available.
// Try to use a different eDMA channel.
while (1);
}
&lcdEdmaChnState,
lcdEdmaChnStcd,
&lcdEdmeConfigStruct,
false, // always disable eDMA transfer done interrupt.
false // always disable auto shut down register when transfer is done.
);
if (ret == kEDMAInvalidChannel)
{
while (1);
}
ret = EDMA_DRV_PushDescriptorToReg( &lcdEdmaChnState, lcdEdmaChnStcd);
if (ret == kEDMAInvalidChannel)
{
while (1);
}
ret = EDMA_DRV_StartChannel( &lcdEdmaChnState );
if (ret == kEDMAInvalidChannel)
{
while (1);
}
//-----------------------------------------------------------------------------
// Finally, start the camera transfer
FLEXIO_Camera_DRV_StartEdmaRx(
(flexio_camera_edma_handler_t *)&gFlexioCameraHandlerStruct);
FLEXIO_DRV_Start(0U);
// Start the sync signal.
PORTA_InstallCallback(1, port_vsync_callback); // vsync pin in PTA13 with priority value 1.
configure_app_gpio_pins(); // Enable the interrupt of OV7670's vsync pins.
while(1) {}
}
//------------------------------------------------------------------------------
// porta_callback function
// Function provided handling of porta IRQ. Rising edge interrupt.
// pin - pin mask
//------------------------------------------------------------------------------
static void port_vsync_callback(uint32_t pin)
{
if (pin == (1<<13)) // vsyhc pin.
{
// Reset eDMA for LCD.
EDMA_DRV_PushDescriptorToReg( &lcdEdmaChnState, lcdEdmaChnStcd);
// Reset eDMA for camera.
FLEXIO_Camera_DRV_ResetEdmaRx(
(flexio_camera_edma_handler_t *)&gFlexioCameraHandlerStruct);
// Reset the LCD.
// ...
}
}