Fataris 0 28 августа, 2015 Опубликовано 28 августа, 2015 (изменено) · Жалоба Уже куда только не писал, пытаюсь запустить камеру OV7670 на STM32F429 Работаю с халом, ибо приходится. При попытки забрать данных с буфера он оказывается пустым, на дисплее черный экран Для теста записал в первую ячейку белый пиксель - выводиться, но остальны ячейки по нулям, DMA даже не прикосается к массиву Прерывания работают, DMA2_Stream1_IRQHandler срабатывает один раз сразу после вызова HAL_DCMI_Start_DMA(). DCMI_IRQHandler срабатывает просто очень часто, если вынуть камеру - все перестает работаеть (значит, данные то идут?) Думаю, не стоит говорить о том, что инициализация по I2C тоже проходит успешно Код инициализации для ленивых: // Настрока DCMI и DMA uint8_t DCMI_DMA_init(void){ GPIO_InitTypeDef GPIO_InitStruct; DCMI_HandleTypeDef *hdcmi = &OV7670_hdcmi_eval; // Тактирование __GPIOE_CLK_ENABLE(); __GPIOA_CLK_ENABLE(); __GPIOC_CLK_ENABLE(); __GPIOB_CLK_ENABLE(); __DCMI_CLK_ENABLE(); __DMA2_CLK_ENABLE(); // .... DCMI порты (обрезано, чтоб не грузить читателя) .... // DMA ( - изначально) OV7670_hdma.Init.Direction = DMA_PERIPH_TO_MEMORY; OV7670_hdma.Init.PeriphInc = DMA_PINC_DISABLE; OV7670_hdma.Init.MemInc = DMA_MINC_ENABLE; OV7670_hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; OV7670_hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; // DMA_MDATAALIGN_WORD - DMA_MDATAALIGN_HALFWORD OV7670_hdma.Init.Mode = DMA_NORMAL; // DMA_CIRCULAR - DMA_NORMAL OV7670_hdma.Init.Priority = DMA_PRIORITY_HIGH; OV7670_hdma.Init.FIFOMode = DMA_FIFOMODE_ENABLE; // DMA_FIFOMODE_DISABLE - DMA_FIFOMODE_ENABLE OV7670_hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; OV7670_hdma.Init.MemBurst = DMA_MBURST_SINGLE; OV7670_hdma.Init.PeriphBurst = DMA_PBURST_SINGLE; OV7670_hdma.Instance = DMA2_Stream1; // DCMI hdcmi->Init.SynchroMode = DCMI_SYNCHRO_HARDWARE; hdcmi->Init.CaptureRate = DCMI_CR_ALL_FRAME; hdcmi->Init.HSPolarity = DCMI_HSPOLARITY_LOW; hdcmi->Init.VSPolarity = DCMI_VSPOLARITY_HIGH; hdcmi->Init.ExtendedDataMode = DCMI_EXTEND_DATA_8B; hdcmi->Init.PCKPolarity = DCMI_PCKPOLARITY_RISING; hdcmi->Init.JPEGMode = DCMI_JPEG_DISABLE; hdcmi->Instance = DCMI; // Прерывание по завершении передачи HAL_NVIC_SetPriority(DCMI_IRQn, 5, 1); HAL_NVIC_EnableIRQ(DCMI_IRQn); // Прерывание при полном приеме HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 5, 0); HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn); // Связываем DMA с DCMI __HAL_LINKDMA(hdcmi, DMA_Handle, OV7670_hdma); // Инициализация DCMI if(HAL_DCMI_Init(hdcmi) != HAL_OK){ return 0; } // Инициализация DMA if(HAL_DMA_Init(hdcmi->DMA_Handle) != HAL_OK){ return 0; } return 1; } Пытаюсь получить картинку так: if(HAL_DCMI_Start_DMA(&OV7670_hdcmi_eval, DCMI_MODE_SNAPSHOT, &OV7670_buffer, (uint32_t)((IMG_ROWS * IMG_COLUMNS * 2) / 4)) != HAL_OK){ LCD_ILI9341_Puts(100, 165, "Error DMA", &LCD_Font_16x26, ILI9341_COLOR_WHITE, ILI9341_COLOR_BLACK); } HAL_Delay(100); LCD_ILI9341_DisplayImage((uint16_t*)OV7670_buffer); А вот файлы для того, кому не лень: main.c: http://code.re/8fG OV7670.c: http://code.re/8fF OV7670.h: http://code.re/8fE Меня волнуют слейдущие моменты: - Подтяжка портов к плюсу - DMA_FIFOMODE_ENABLE - DMA_MDATAALIGN_HALFWORD - мод DMA - DMA_NORMAL - клок камеры настроеный на 16МГц Изменено 28 августа, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KSN 0 28 августа, 2015 Опубликовано 28 августа, 2015 · Жалоба Парсить ваш код времени нет, сорри. Вот рабочий пример: void OV7670_Snapshot2RAMBuffer(void) { DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Включение тактирования RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // DMA деинициализация DMA_Cmd(DMA2_Stream1, DISABLE); DMA_DeInit(DMA2_Stream1); DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1); /* Enable the DMA Stream IRQ Channel */ NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); /* Enable the DMA Stream IRQ Channel */ NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); dma2Stream0 = 0; dma2Stream1 = 0; DMA_DoubleBufferModeConfig(DMA2_Stream1,(uint32_t)&ov7670_ram1[0],DMA_Memory_0); DMA_DoubleBufferModeCmd(DMA2_Stream1, ENABLE); // DMA инициализация DMA_InitStructure.DMA_Channel = DMA_Channel_1; DMA_InitStructure.DMA_PeripheralBaseAddr = DCMI_DR_ADDRESS; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ov7670_ram0; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE_WORD; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_Priority = DMA_Priority_High; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream1, &DMA_InitStructure); DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1); /* Enable DMA Stream Transfer Complete interrupt */ DMA_ITConfig(DMA2_Stream1, DMA_IT_TC, ENABLE); // DMA деинициализация DMA_Cmd(DMA2_Stream0, DISABLE); DMA_DeInit(DMA2_Stream0); DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); // DMA инициализация DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ov7670_ram0[0]; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(SDRAM_BANK_ADDR); DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; DMA_InitStructure.DMA_BufferSize = BUFFER_SIZE_WORD; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_INC4; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_INC4; DMA_Init(DMA2_Stream0, &DMA_InitStructure); DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); /* Enable DMA Stream Transfer Complete interrupt */ DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); // DMA включен DMA_Cmd(DMA2_Stream1, ENABLE); // DCMI инициализация OV7670_InitDCMI(1); // DCMI включен DCMI_Cmd(ENABLE); // Capture включен DCMI_CaptureCmd(ENABLE); } void DMA2_Stream1_IRQHandler(void) { /* Test on DMA Stream Transfer Complete interrupt */ if(DMA_GetITStatus(DMA2_Stream1, DMA_IT_TCIF1)) { /* Clear DMA Stream Transfer Complete interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream1, DMA_IT_TCIF1); if (DMA2_Stream1->CR&0x00080000) { /* ram1*/ DMA2_Stream0->PAR = (uint32_t)&ov7670_ram0[0]; DMA2_Stream0->M0AR = (uint32_t)(SDRAM_BANK_ADDR + dma2Stream1*76800); } else { /* ram0 */ DMA2_Stream0->PAR = (uint32_t)&ov7670_ram1[0]; DMA2_Stream0->M0AR = (uint32_t)(SDRAM_BANK_ADDR + dma2Stream1*76800); } DMA2_Stream0->CR |= (uint32_t)DMA_SxCR_EN; dma2Stream1++; } } //#warning "Uncomment function for DCMI used" void DMA2_Stream0_IRQHandler(void) { /* Test on DMA Stream Transfer Complete interrupt */ if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0)) { /* Clear DMA Stream Transfer Complete interrupt pending bit */ DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0); dma2Stream0++; } } Принцип следующий: есть 2 буфера в RAM по 19200 32-х разрядных слов. Один канал DMA берет данные с камеры и кидает в активный буфер (по кольцу). Второй канал DMA из RAM перекидывает в SRAM(внешняя), т.к. для разрешения 640x480 необходимо 307200*2=614400 байт(формат YUV). Clock камеры 24Мгц Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Fataris 0 28 августа, 2015 Опубликовано 28 августа, 2015 · Жалоба Я мого видел примеров, но все они на SPL, а мне необходим HAL Я использую RGB565, 320 на 240 - этого вроде хватает Но буфер пустует, не пойму из-за чего Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
LightElf 0 4 сентября, 2015 Опубликовано 4 сентября, 2015 · Жалоба Я мого видел примеров, но все они на SPL, а мне необходим HAL Я использую RGB565, 320 на 240 - этого вроде хватает Но буфер пустует, не пойму из-за чего Данные с камеры идут (осциллографом)? Полярность HSYNC/VSYNC/PCLK правильно настроена? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Fataris 0 16 сентября, 2015 Опубликовано 16 сентября, 2015 · Жалоба Да, данные шли, камеры OV шлют данные сразу, как к ним подключается тактирование и даже можно различить образы среди помех (может кому полезно будет) Дело было в версии хала, не пользуйтесь халом от кокса, возможно, к прочтению этого сообшения кем-то эту проблему устронят, но лучше скачайте свежую версию с ST и проверьте свой код на ней Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться