Merge pull request #1380 from openmv/rename_sensor_functions

Rename sensor functions for consistency across ports.
This commit is contained in:
Ibrahim Abd Elkader 2021-06-29 14:49:18 +02:00 committed by GitHub
commit 9ae8d061f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 219 additions and 210 deletions

View File

@ -73,7 +73,7 @@ PIXEL_LOOP:
.wrap
% c-sdk {
static inline int dcmi_config(uint32_t pixformat)
int sensor_config(uint32_t pixformat)
{
uint offset;
pio_sm_config config;

View File

@ -57,7 +57,7 @@ PIXEL_LOOP:
.wrap
% c-sdk {
static inline int dcmi_config(uint32_t pixformat)
int sensor_config(uint32_t pixformat)
{
uint offset;
pio_sm_config config;

View File

@ -232,6 +232,9 @@ void sensor_init0();
// Initialize the sensor hardware and probe the image sensor.
int sensor_init();
// Configure DCMI hardware interface.
int sensor_config(uint32_t pixformat);
// Abort frame capture and disable IRQs, DMA etc..
int sensor_abort();
@ -242,7 +245,10 @@ int sensor_reset();
int sensor_get_id();
// Returns the xclk freq in hz.
int sensor_xclk_freq();
uint32_t sensor_get_xclk_frequency();
// Returns the xclk freq in hz.
int sensor_set_xclk_frequency(uint32_t frequency);
// Return true if the sensor was detected and initialized.
bool sensor_is_detected();

View File

@ -100,60 +100,6 @@ const int resolution[][2] = {
{2592, 1944}, /* WQXGA2 */
};
static int extclk_config(int frequency)
{
#ifndef I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2
// Note this define is out of spec and has been removed from hal.
#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2 (0x80000000UL) /*!< 32 MHz / 2 = 16.0 MHz */
#endif
nrf_gpio_cfg_output(DCMI_XCLK_PIN);
// Generates 16 MHz signal using I2S peripheral
NRF_I2S->CONFIG.MCKEN = (I2S_CONFIG_MCKEN_MCKEN_ENABLE << I2S_CONFIG_MCKEN_MCKEN_Pos);
NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
NRF_I2S->CONFIG.MODE = I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos;
NRF_I2S->PSEL.MCK = (DCMI_XCLK_PIN << I2S_PSEL_MCK_PIN_Pos);
NRF_I2S->ENABLE = 1;
NRF_I2S->TASKS_START = 1;
return 0;
}
static int dcmi_config()
{
uint32_t dcmi_pins[] = {
DCMI_D0_PIN,
DCMI_D1_PIN,
DCMI_D2_PIN,
DCMI_D3_PIN,
DCMI_D4_PIN,
DCMI_D5_PIN,
DCMI_D6_PIN,
DCMI_D7_PIN,
DCMI_VSYNC_PIN,
DCMI_HSYNC_PIN,
DCMI_PXCLK_PIN,
};
// Configure DCMI input pins
for (int i=0; i<sizeof(dcmi_pins)/sizeof(dcmi_pins[0]); i++) {
nrf_gpio_cfg_input(dcmi_pins[i], NRF_GPIO_PIN_PULLUP);
}
_vsyncMask = digitalPinToBitMask(DCMI_VSYNC_PIN);
_hrefMask = digitalPinToBitMask(DCMI_HSYNC_PIN);
_pclkMask = digitalPinToBitMask(DCMI_PXCLK_PIN);
_vsyncPort = portInputRegister(digitalPinToPort(DCMI_VSYNC_PIN));
_hrefPort = portInputRegister(digitalPinToPort(DCMI_HSYNC_PIN));
_pclkPort = portInputRegister(digitalPinToPort(DCMI_PXCLK_PIN));
return 0;
}
int sensor_init()
{
int init_ret = 0;
@ -178,7 +124,7 @@ int sensor_init()
// Configure the sensor external clock (XCLK) to XCLK_FREQ.
#if (OMV_XCLK_SOURCE == OMV_XCLK_TIM)
// Configure external clock timer.
if (extclk_config(OMV_XCLK_FREQUENCY) != 0) {
if (sensor_set_xclk_frequency(OMV_XCLK_FREQUENCY) != 0) {
// Timer problem
return -1;
}
@ -300,7 +246,7 @@ int sensor_init()
switch (sensor.chip_id) {
#if (OMV_ENABLE_OV2640 == 1)
case OV2640_ID:
if (extclk_config(OV2640_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV2640_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov2640_init(&sensor);
@ -309,7 +255,7 @@ int sensor_init()
#if (OMV_ENABLE_OV5640 == 1)
case OV5640_ID:
if (extclk_config(OV5640_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV5640_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov5640_init(&sensor);
@ -318,7 +264,7 @@ int sensor_init()
#if (OMV_ENABLE_OV7670 == 1)
case OV7670_ID:
if (extclk_config(OV7670_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV7670_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov7670_init(&sensor);
@ -327,7 +273,7 @@ int sensor_init()
#if (OMV_ENABLE_OV7690 == 1)
case OV7690_ID:
if (extclk_config(OV7690_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV7690_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov7690_init(&sensor);
@ -348,7 +294,7 @@ int sensor_init()
#if (OMV_ENABLE_MT9V034 == 1)
case MT9V034_ID:
if (extclk_config(MT9V034_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(MT9V034_XCLK_FREQ) != 0) {
return -3;
}
init_ret = mt9v034_init(&sensor);
@ -357,7 +303,7 @@ int sensor_init()
#if (OMV_ENABLE_MT9M114 == 1)
case MT9M114_ID:
if (extclk_config(MT9M114_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(MT9M114_XCLK_FREQ) != 0) {
return -3;
}
init_ret = mt9m114_init(&sensor);
@ -366,7 +312,7 @@ int sensor_init()
#if (OMV_ENABLE_LEPTON == 1)
case LEPTON_ID:
if (extclk_config(LEPTON_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(LEPTON_XCLK_FREQ) != 0) {
return -3;
}
init_ret = lepton_init(&sensor);
@ -389,8 +335,8 @@ int sensor_init()
return -4;
}
/* Configure the DCMI interface. */
if (dcmi_config() != 0){
// Configure the DCMI interface.
if (sensor_config(PIXFORMAT_INVALID) != 0){
// DCMI config failed
return -6;
}
@ -412,6 +358,38 @@ int sensor_init()
return 0;
}
int sensor_config(uint32_t pixformat)
{
uint32_t dcmi_pins[] = {
DCMI_D0_PIN,
DCMI_D1_PIN,
DCMI_D2_PIN,
DCMI_D3_PIN,
DCMI_D4_PIN,
DCMI_D5_PIN,
DCMI_D6_PIN,
DCMI_D7_PIN,
DCMI_VSYNC_PIN,
DCMI_HSYNC_PIN,
DCMI_PXCLK_PIN,
};
// Configure DCMI input pins
for (int i=0; i<sizeof(dcmi_pins)/sizeof(dcmi_pins[0]); i++) {
nrf_gpio_cfg_input(dcmi_pins[i], NRF_GPIO_PIN_PULLUP);
}
_vsyncMask = digitalPinToBitMask(DCMI_VSYNC_PIN);
_hrefMask = digitalPinToBitMask(DCMI_HSYNC_PIN);
_pclkMask = digitalPinToBitMask(DCMI_PXCLK_PIN);
_vsyncPort = portInputRegister(digitalPinToPort(DCMI_VSYNC_PIN));
_hrefPort = portInputRegister(digitalPinToPort(DCMI_HSYNC_PIN));
_pclkPort = portInputRegister(digitalPinToPort(DCMI_PXCLK_PIN));
return 0;
}
int sensor_reset()
{
framebuffer_reset_buffers();
@ -468,6 +446,32 @@ int sensor_get_id()
return sensor.chip_id;
}
uint32_t sensor_get_xclk_frequency()
{
return OMV_XCLK_FREQUENCY;
}
int sensor_set_xclk_frequency(uint32_t frequency)
{
#ifndef I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2
// Note this define is out of spec and has been removed from hal.
#define I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2 (0x80000000UL) /*!< 32 MHz / 2 = 16.0 MHz */
#endif
nrf_gpio_cfg_output(DCMI_XCLK_PIN);
// Generates 16 MHz signal using I2S peripheral
NRF_I2S->CONFIG.MCKEN = (I2S_CONFIG_MCKEN_MCKEN_ENABLE << I2S_CONFIG_MCKEN_MCKEN_Pos);
NRF_I2S->CONFIG.MCKFREQ = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2 << I2S_CONFIG_MCKFREQ_MCKFREQ_Pos;
NRF_I2S->CONFIG.MODE = I2S_CONFIG_MODE_MODE_MASTER << I2S_CONFIG_MODE_MODE_Pos;
NRF_I2S->PSEL.MCK = (DCMI_XCLK_PIN << I2S_PSEL_MCK_PIN_Pos);
NRF_I2S->ENABLE = 1;
NRF_I2S->TASKS_START = 1;
return 0;
}
bool sensor_is_detected()
{
return sensor.detected;

View File

@ -89,32 +89,6 @@ const int resolution[][2] = {
{2592, 1944}, /* WQXGA2 */
};
static int extclk_config(int frequency)
{
uint32_t p = 4;
// Allocate pin to the PWM
gpio_set_function(DCMI_XCLK_PIN, GPIO_FUNC_PWM);
// Find out which PWM slice is connected to the GPIO
uint slice_num = pwm_gpio_to_slice_num(DCMI_XCLK_PIN);
// Set period to p cycles
pwm_set_wrap(slice_num, p-1);
// Set channel A 50% duty cycle.
pwm_set_chan_level(slice_num, PWM_CHAN_A, p/2);
// Set sysclk divider
// f = 125000000 / (p * (1 + (p/16)))
pwm_set_clkdiv_int_frac(slice_num, 1, p);
// Set the PWM running
pwm_set_enabled(slice_num, true);
return 0;
}
static void dma_config(int w, int h, int bpp, uint32_t *capture_buf, bool rev_bytes)
{
dma_channel_abort(DCMI_DMA_CHANNEL);
@ -177,7 +151,7 @@ int sensor_init()
// Configure the sensor external clock (XCLK) to XCLK_FREQ.
#if (OMV_XCLK_SOURCE == OMV_XCLK_TIM)
// Configure external clock timer.
if (extclk_config(OMV_XCLK_FREQUENCY) != 0) {
if (sensor_set_xclk_frequency(OMV_XCLK_FREQUENCY) != 0) {
// Timer problem
return -1;
}
@ -299,7 +273,7 @@ int sensor_init()
switch (sensor.chip_id) {
#if (OMV_ENABLE_OV2640 == 1)
case OV2640_ID:
if (extclk_config(OV2640_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV2640_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov2640_init(&sensor);
@ -308,7 +282,7 @@ int sensor_init()
#if (OMV_ENABLE_OV5640 == 1)
case OV5640_ID:
if (extclk_config(OV5640_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV5640_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov5640_init(&sensor);
@ -323,7 +297,7 @@ int sensor_init()
#if (OMV_ENABLE_OV7690 == 1)
case OV7690_ID:
if (extclk_config(OV7690_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV7690_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov7690_init(&sensor);
@ -344,7 +318,7 @@ int sensor_init()
#if (OMV_ENABLE_MT9V034 == 1)
case MT9V034_ID:
if (extclk_config(MT9V034_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(MT9V034_XCLK_FREQ) != 0) {
return -3;
}
init_ret = mt9v034_init(&sensor);
@ -353,7 +327,7 @@ int sensor_init()
#if (OMV_ENABLE_MT9M114 == 1)
case MT9M114_ID:
if (extclk_config(MT9M114_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(MT9M114_XCLK_FREQ) != 0) {
return -3;
}
init_ret = mt9m114_init(&sensor);
@ -362,7 +336,7 @@ int sensor_init()
#if (OMV_ENABLE_LEPTON == 1)
case LEPTON_ID:
if (extclk_config(LEPTON_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(LEPTON_XCLK_FREQ) != 0) {
return -3;
}
init_ret = lepton_init(&sensor);
@ -487,6 +461,32 @@ int sensor_get_id()
return sensor.chip_id;
}
int sensor_set_xclk_frequency(uint32_t frequency)
{
uint32_t p = 4;
// Allocate pin to the PWM
gpio_set_function(DCMI_XCLK_PIN, GPIO_FUNC_PWM);
// Find out which PWM slice is connected to the GPIO
uint slice_num = pwm_gpio_to_slice_num(DCMI_XCLK_PIN);
// Set period to p cycles
pwm_set_wrap(slice_num, p-1);
// Set channel A 50% duty cycle.
pwm_set_chan_level(slice_num, PWM_CHAN_A, p/2);
// Set sysclk divider
// f = 125000000 / (p * (1 + (p/16)))
pwm_set_clkdiv_int_frac(slice_num, 1, p);
// Set the PWM running
pwm_set_enabled(slice_num, true);
return 0;
}
bool sensor_is_detected()
{
return sensor.detected;
@ -567,9 +567,7 @@ int sensor_set_pixformat(pixformat_t pixformat)
MAIN_FB()->bpp = -1;
// Reconfigure PIO DCMI program.
dcmi_config(pixformat);
return 0;
return sensor_config(pixformat);
}
int sensor_set_framesize(framesize_t framesize)

View File

@ -132,56 +132,6 @@ void ISC_SPI_DMA_IRQHandler(void)
}
#endif // ISC_SPI
int sensor_xclk_freq()
{
return (DCMI_TIM_PCLK_FREQ() * 2) / (TIMHandle.Init.Period + 1);
}
static int extclk_config(int frequency)
{
#if (OMV_XCLK_SOURCE == OMV_XCLK_TIM)
/* TCLK (PCLK * 2) */
int tclk = DCMI_TIM_PCLK_FREQ() * 2;
/* Period should be even */
int period = (tclk / frequency) - 1;
int pulse = period / 2;
if (TIMHandle.Init.Period && (TIMHandle.Init.Period != period)) {
// __HAL_TIM_SET_AUTORELOAD sets TIMHandle.Init.Period...
__HAL_TIM_SET_AUTORELOAD(&TIMHandle, period);
__HAL_TIM_SET_COMPARE(&TIMHandle, DCMI_TIM_CHANNEL, pulse);
return 0;
}
/* Timer base configuration */
TIMHandle.Init.Period = period;
TIMHandle.Init.Prescaler = 0;
TIMHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TIMHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
TIMHandle.Init.RepetitionCounter = 0;
TIMHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
/* Timer channel configuration */
TIM_OC_InitTypeDef TIMOCHandle;
TIMOCHandle.Pulse = pulse;
TIMOCHandle.OCMode = TIM_OCMODE_PWM1;
TIMOCHandle.OCPolarity = TIM_OCPOLARITY_HIGH;
TIMOCHandle.OCNPolarity = TIM_OCNPOLARITY_HIGH;
TIMOCHandle.OCFastMode = TIM_OCFAST_DISABLE;
TIMOCHandle.OCIdleState = TIM_OCIDLESTATE_RESET;
TIMOCHandle.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if ((HAL_TIM_PWM_Init(&TIMHandle) != HAL_OK)
|| (HAL_TIM_PWM_ConfigChannel(&TIMHandle, &TIMOCHandle, DCMI_TIM_CHANNEL) != HAL_OK)
|| (HAL_TIM_PWM_Start(&TIMHandle, DCMI_TIM_CHANNEL) != HAL_OK)) {
return -1;
}
#endif // (OMV_XCLK_SOURCE == OMV_XCLK_TIM)
return 0;
}
static int dma_config()
{
// DMA Stream configuration
@ -215,45 +165,6 @@ static int dma_config()
return 0;
}
static int dcmi_config(uint32_t jpeg_mode)
{
// VSYNC clock polarity
DCMIHandle.Init.VSPolarity = SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_VSYNC) ?
DCMI_VSPOLARITY_HIGH : DCMI_VSPOLARITY_LOW;
// HSYNC clock polarity
DCMIHandle.Init.HSPolarity = SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_HSYNC) ?
DCMI_HSPOLARITY_HIGH : DCMI_HSPOLARITY_LOW;
// PXCLK clock polarity
DCMIHandle.Init.PCKPolarity = SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_PIXCK) ?
DCMI_PCKPOLARITY_RISING : DCMI_PCKPOLARITY_FALLING;
// Setup capture parameters.
DCMIHandle.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; // Enable Hardware synchronization
DCMIHandle.Init.CaptureRate = DCMI_CR_ALL_FRAME; // Capture rate all frames
DCMIHandle.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; // Capture 8 bits on every pixel clock
DCMIHandle.Init.JPEGMode = jpeg_mode; // Set JPEG Mode
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
DCMIHandle.Init.ByteSelectMode = DCMI_BSM_ALL; // Capture all received bytes
DCMIHandle.Init.ByteSelectStart = DCMI_OEBS_ODD; // Ignored
DCMIHandle.Init.LineSelectMode = DCMI_LSM_ALL; // Capture all received lines
DCMIHandle.Init.LineSelectStart = DCMI_OELS_ODD; // Ignored
#endif
// Associate the DMA handle to the DCMI handle
__HAL_LINKDMA(&DCMIHandle, DMA_Handle, DMAHandle);
// Initialize the DCMI
HAL_DCMI_DeInit(&DCMIHandle);
if (HAL_DCMI_Init(&DCMIHandle) != HAL_OK) {
// Initialization Error
return -1;
}
// Configure and enable DCMI IRQ Channel
NVIC_SetPriority(DCMI_IRQn, IRQ_PRI_DCMI);
HAL_NVIC_EnableIRQ(DCMI_IRQn);
return 0;
}
// Returns true if a crop is being applied to the frame buffer.
static bool cropped()
{
@ -311,7 +222,7 @@ int sensor_init()
//
#if (OMV_XCLK_SOURCE == OMV_XCLK_TIM)
// Configure external clock timer.
if (extclk_config(OMV_XCLK_FREQUENCY) != 0) {
if (sensor_set_xclk_frequency(OMV_XCLK_FREQUENCY) != 0) {
// Timer problem
return -1;
}
@ -458,7 +369,7 @@ int sensor_init()
switch (sensor.chip_id_w) {
#if (OMV_ENABLE_OV2640 == 1)
case OV2640_ID:
if (extclk_config(OV2640_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV2640_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov2640_init(&sensor);
@ -467,7 +378,7 @@ int sensor_init()
#if (OMV_ENABLE_OV5640 == 1)
case OV5640_ID:
if (extclk_config(OV5640_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV5640_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov5640_init(&sensor);
@ -476,7 +387,7 @@ int sensor_init()
#if (OMV_ENABLE_OV7670 == 1)
case OV7670_ID:
if (extclk_config(OV7670_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV7670_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov7670_init(&sensor);
@ -485,7 +396,7 @@ int sensor_init()
#if (OMV_ENABLE_OV7690 == 1)
case OV7690_ID:
if (extclk_config(OV7690_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(OV7690_XCLK_FREQ) != 0) {
return -3;
}
init_ret = ov7690_init(&sensor);
@ -506,7 +417,7 @@ int sensor_init()
#if (OMV_ENABLE_MT9V034 == 1)
case MT9V034_ID:
if (extclk_config(MT9V034_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(MT9V034_XCLK_FREQ) != 0) {
return -3;
}
init_ret = mt9v034_init(&sensor);
@ -515,7 +426,7 @@ int sensor_init()
#if (OMV_ENABLE_MT9M114 == 1)
case MT9M114_ID:
if (extclk_config(MT9M114_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(MT9M114_XCLK_FREQ) != 0) {
return -3;
}
init_ret = mt9m114_init(&sensor);
@ -524,7 +435,7 @@ int sensor_init()
#if (OMV_ENABLE_LEPTON == 1)
case LEPTON_ID:
if (extclk_config(LEPTON_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(LEPTON_XCLK_FREQ) != 0) {
return -3;
}
init_ret = lepton_init(&sensor);
@ -539,7 +450,7 @@ int sensor_init()
#if (OMV_ENABLE_GC2145 == 1)
case GC2145_ID:
if (extclk_config(GC2145_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(GC2145_XCLK_FREQ) != 0) {
return -3;
}
init_ret = gc2145_init(&sensor);
@ -548,7 +459,7 @@ int sensor_init()
#if (OMV_ENABLE_PAJ6100 == 1)
case PAJ6100_ID:
if (extclk_config(PAJ6100_XCLK_FREQ) != 0) {
if (sensor_set_xclk_frequency(PAJ6100_XCLK_FREQ) != 0) {
return -3;
}
init_ret = paj6100_init(&sensor);
@ -571,9 +482,8 @@ int sensor_init()
return -5;
}
/* Configure the DCMI interface. This should be called
after ovxxx_init to set VSYNC/HSYNC/PCLK polarities */
if (dcmi_config(DCMI_JPEG_DISABLE) != 0){
// Configure the DCMI interface.
if (sensor_config(PIXFORMAT_INVALID) != 0){
// DCMI config failed
return -6;
}
@ -594,6 +504,47 @@ int sensor_init()
return 0;
}
int sensor_config(uint32_t pixformat)
{
// VSYNC clock polarity
DCMIHandle.Init.VSPolarity = SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_VSYNC) ?
DCMI_VSPOLARITY_HIGH : DCMI_VSPOLARITY_LOW;
// HSYNC clock polarity
DCMIHandle.Init.HSPolarity = SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_HSYNC) ?
DCMI_HSPOLARITY_HIGH : DCMI_HSPOLARITY_LOW;
// PXCLK clock polarity
DCMIHandle.Init.PCKPolarity = SENSOR_HW_FLAGS_GET(&sensor, SENSOR_HW_FLAGS_PIXCK) ?
DCMI_PCKPOLARITY_RISING : DCMI_PCKPOLARITY_FALLING;
// Setup capture parameters.
DCMIHandle.Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; // Enable Hardware synchronization
DCMIHandle.Init.CaptureRate = DCMI_CR_ALL_FRAME; // Capture rate all frames
DCMIHandle.Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; // Capture 8 bits on every pixel clock
// Set JPEG Mode
DCMIHandle.Init.JPEGMode = (pixformat == PIXFORMAT_JPEG) ?
DCMI_JPEG_ENABLE : DCMI_JPEG_DISABLE;
#if defined(MCU_SERIES_F7) || defined(MCU_SERIES_H7)
DCMIHandle.Init.ByteSelectMode = DCMI_BSM_ALL; // Capture all received bytes
DCMIHandle.Init.ByteSelectStart = DCMI_OEBS_ODD; // Ignored
DCMIHandle.Init.LineSelectMode = DCMI_LSM_ALL; // Capture all received lines
DCMIHandle.Init.LineSelectStart = DCMI_OELS_ODD; // Ignored
#endif
// Associate the DMA handle to the DCMI handle
__HAL_LINKDMA(&DCMIHandle, DMA_Handle, DMAHandle);
// Initialize the DCMI
HAL_DCMI_DeInit(&DCMIHandle);
if (HAL_DCMI_Init(&DCMIHandle) != HAL_OK) {
// Initialization Error
return -1;
}
// Configure and enable DCMI IRQ Channel
NVIC_SetPriority(DCMI_IRQn, IRQ_PRI_DCMI);
HAL_NVIC_EnableIRQ(DCMI_IRQn);
return 0;
}
int sensor_abort()
{
// This stops the DCMI hardware from generating DMA requests immediately and then stops the DMA
@ -680,6 +631,56 @@ int sensor_get_id()
return sensor.chip_id_w;
}
uint32_t sensor_get_xclk_frequency()
{
return (DCMI_TIM_PCLK_FREQ() * 2) / (TIMHandle.Init.Period + 1);
}
int sensor_set_xclk_frequency(uint32_t frequency)
{
#if (OMV_XCLK_SOURCE == OMV_XCLK_TIM)
/* TCLK (PCLK * 2) */
int tclk = DCMI_TIM_PCLK_FREQ() * 2;
/* Period should be even */
int period = (tclk / frequency) - 1;
int pulse = period / 2;
if (TIMHandle.Init.Period && (TIMHandle.Init.Period != period)) {
// __HAL_TIM_SET_AUTORELOAD sets TIMHandle.Init.Period...
__HAL_TIM_SET_AUTORELOAD(&TIMHandle, period);
__HAL_TIM_SET_COMPARE(&TIMHandle, DCMI_TIM_CHANNEL, pulse);
return 0;
}
/* Timer base configuration */
TIMHandle.Init.Period = period;
TIMHandle.Init.Prescaler = 0;
TIMHandle.Init.CounterMode = TIM_COUNTERMODE_UP;
TIMHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
TIMHandle.Init.RepetitionCounter = 0;
TIMHandle.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
/* Timer channel configuration */
TIM_OC_InitTypeDef TIMOCHandle;
TIMOCHandle.Pulse = pulse;
TIMOCHandle.OCMode = TIM_OCMODE_PWM1;
TIMOCHandle.OCPolarity = TIM_OCPOLARITY_HIGH;
TIMOCHandle.OCNPolarity = TIM_OCNPOLARITY_HIGH;
TIMOCHandle.OCFastMode = TIM_OCFAST_DISABLE;
TIMOCHandle.OCIdleState = TIM_OCIDLESTATE_RESET;
TIMOCHandle.OCNIdleState = TIM_OCNIDLESTATE_RESET;
if ((HAL_TIM_PWM_Init(&TIMHandle) != HAL_OK)
|| (HAL_TIM_PWM_ConfigChannel(&TIMHandle, &TIMOCHandle, DCMI_TIM_CHANNEL) != HAL_OK)
|| (HAL_TIM_PWM_Start(&TIMHandle, DCMI_TIM_CHANNEL) != HAL_OK)) {
return -1;
}
#endif // (OMV_XCLK_SOURCE == OMV_XCLK_TIM)
return 0;
}
bool sensor_is_detected()
{
return sensor.detected;
@ -716,7 +717,7 @@ int sensor_shutdown(int enable)
} else {
DCMI_PWDN_HIGH();
}
ret = dcmi_config(DCMI_JPEG_DISABLE);
ret = sensor_config(sensor.pixformat);
}
systick_sleep(10);
@ -793,8 +794,8 @@ int sensor_set_pixformat(pixformat_t pixformat)
// Pickout a good buffer count for the user.
framebuffer_auto_adjust_buffers();
// Change the JPEG mode.
return dcmi_config((pixformat == PIXFORMAT_JPEG) ? DCMI_JPEG_ENABLE : DCMI_JPEG_DISABLE);
// Re-configure DCMI.
return sensor_config(pixformat);
}
int sensor_set_framesize(framesize_t framesize)

View File

@ -467,7 +467,7 @@ static int reset(sensor_t *sensor)
ret |= cambus_writew2(&sensor->bus, sensor->slv_addr, 0x301A, reg | (1 << 9));
ret |= cambus_writew2(&sensor->bus, sensor->slv_addr, MT9M114_REG_CAM_SYSCTL_PLL_DIVIDER_M_N,
(sensor_xclk_freq() == MT9M114_XCLK_FREQ)
(sensor_get_xclk_frequency() == MT9M114_XCLK_FREQ)
? 0x120 // xclk=24MHz, m=32, n=1, sensor=48MHz, bus=76.8MHz
: 0x448); // xclk=25MHz, m=72, n=4, sensor=45MHz, bus=72MHz
@ -666,7 +666,7 @@ static int set_framesize(sensor_t *sensor, framesize_t framesize)
ret |= cambus_writew2(&sensor->bus, sensor->slv_addr, MT9M114_REG_SENSOR_CFG_Y_ADDR_END, sensor_he);
ret |= cambus_writew2(&sensor->bus, sensor->slv_addr, MT9M114_REG_SENSOR_CFG_X_ADDR_END, sensor_we);
int pixclk = (sensor_xclk_freq() == MT9M114_XCLK_FREQ) ? 48000000 : 45000000;
int pixclk = (sensor_get_xclk_frequency() == MT9M114_XCLK_FREQ) ? 48000000 : 45000000;
ret |= cambus_writew2(&sensor->bus, sensor->slv_addr, MT9M114_REG_SENSOR_CFG_PIXCLK, pixclk >> 16);
ret |= cambus_writew2(&sensor->bus, sensor->slv_addr, MT9M114_REG_SENSOR_CFG_PIXCLK + 2, pixclk);