예제 #1
0
파일: sensor.c 프로젝트: dhylands/openmv
int sensor_reset()
{
    /* Reset the sesnor state */
    sensor.pixformat=0xFF;
    sensor.framesize=0xFF;
    sensor.framerate=0xFF;
    sensor.gainceiling=0xFF;

    mutex_lock(&fb->lock);
    fb->ready=0;
    mutex_unlock(&fb->lock);

    /* Hard reset the sensor */
    switch (sensor.reset_pol) {
        case ACTIVE_HIGH:
            DCMI_RESET_HIGH();
            systick_sleep(10);

            DCMI_RESET_LOW();
            systick_sleep(10);
           break;
       case ACTIVE_LOW:
            DCMI_RESET_LOW();
            systick_sleep(10);

            DCMI_RESET_HIGH();
            systick_sleep(10);
            break;
    }

    /* Call sensor-specific reset function */
    sensor.reset();
    return 0;
}
예제 #2
0
파일: main.c 프로젝트: godda/openmv
void __fatal_error(const char *msg) {
    printf("%s\n", msg);
    while (1) {
        led_state(LED_RED, 1);
        systick_sleep(250);
        led_state(LED_RED, 0);
        systick_sleep(250);
    }
}
예제 #3
0
static int set_pixformat(sensor_t *sensor, pixformat_t pixformat)
{
    int ret=0;
    // Read register COM7
    uint8_t reg = SCCB_Read(sensor->slv_addr, COM7);

    switch (pixformat) {
        case PIXFORMAT_RGB565:
            reg =  COM7_SET_FMT(reg, COM7_FMT_RGB);
            break;
        case PIXFORMAT_YUV422:
        case PIXFORMAT_GRAYSCALE:
            reg =  COM7_SET_FMT(reg, COM7_FMT_YUV);
            break;
        default:
            return -1;
    }

    // Write back register COM7
    ret = SCCB_Write(sensor->slv_addr, COM7, reg);

    // Delay
    systick_sleep(30);

    return ret;
}
예제 #4
0
void sdcard_init(void)
{
    volatile int retry=10;
    HAL_SD_CardInfoTypedef cardinfo;

    // SDIO configuration
    SDHandle.Instance                 = SDIO;
    SDHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
    SDHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
    SDHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
    SDHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
    SDHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
    SDHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV; //INIT_CLK_DIV will be used first

    // Deinit SD
    HAL_SD_DeInit(&SDHandle);
    // Init SD interface
    while(HAL_SD_Init(&SDHandle, &cardinfo) != SD_OK && retry--) {
        if (retry == 0) {
            __fatal_error("Failed to init sdcard: init timeout");
        }
        systick_sleep(100);
    }

    /* Configure the SD Card in wide bus mode. */
    if (HAL_SD_WideBusOperation_Config(&SDHandle, SDIO_BUS_WIDE_4B) != SD_OK) {
        __fatal_error("Failed to init sensor, sdcard: config wide bus");
    }

    // Configure and enable DMA IRQ Channel
    // SDIO IRQ should have a higher priority than DMA IRQ because it needs to
    // preempt the DMA irq handler to set a flag indicating the end of transfer.
    HAL_NVIC_SetPriority(SDIO_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
    HAL_NVIC_EnableIRQ(SDIO_IRQn);
}
예제 #5
0
int main(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;

    /* Enable GPIOG clock */
    LED_RCC_CLKCMD(LED_RCC_PERIPH, ENABLE);

    /* Configure LED pin in output mode */
    GPIO_InitStructure.GPIO_Pin   = LED_GPIO_PIN;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;

    GPIO_Init(LED_GPIO_PORT, &GPIO_InitStructure);
    GPIO_SetBits(LED_GPIO_PORT, LED_GPIO_PIN);

    /* configure systick to interrupt every 1ms */
    if (SysTick_Config(SystemCoreClock / 1000)) {
        while(1);
    }

    /* Do nothing */
    while (1) {
        /* wait 500ms */
        systick_sleep(500);

        /* Toggle LED */
        GPIO_ToggleBits(LED_GPIO_PORT, LED_GPIO_PIN);
    }
}
예제 #6
0
void sdcard_init(void)
{
    volatile int retry=10;

    /* SDIO initial configuration */
    SDHandle.Instance                 = SDIO;
    SDHandle.Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
    SDHandle.Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
    SDHandle.Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE; //TODO
    SDHandle.Init.BusWide             = SDIO_BUS_WIDE_1B;
    SDHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
    SDHandle.Init.ClockDiv            = SDIO_TRANSFER_CLK_DIV; //INIT_CLK_DIV will be used first

    /* DeInit in case of reboot */
    HAL_SD_DeInit(&SDHandle);

    /* Init the SD interface */
    HAL_SD_CardInfoTypedef cardinfo;
    while(HAL_SD_Init(&SDHandle, &cardinfo) != SD_OK && --retry) {
        systick_sleep(100);
    }

    if (retry == 0) {
        BREAK();
    }

    /* Configure the SD Card in wide bus mode. */
    if (HAL_SD_WideBusOperation_Config(&SDHandle, SDIO_BUS_WIDE_4B) != SD_OK) {
        BREAK();
    }
}
예제 #7
0
int sensor_snapshot(struct image *image)
{
    volatile uint32_t addr;
    volatile uint16_t length;

    addr = (uint32_t) fb->pixels;

    if (sensor.pixformat==PIXFORMAT_JPEG) {
        length = MAX_XFER_SIZE;
    } else {
        length =(fb->w * fb->h * 2)/4;
    }

    /* Lock framebuffer mutex */
    mutex_lock(&fb->lock);

    /* Start the DCMI */
    HAL_DCMI_Start_DMA(&DCMIHandle,
            DCMI_MODE_SNAPSHOT, addr, length);

    /* Wait for frame */
    while ((DCMI->CR & DCMI_CR_CAPTURE) != 0) {

    }

    if (sensor.pixformat == PIXFORMAT_GRAYSCALE) {
        /* If GRAYSCALE extract Y channel from YUYV */
        for (int i=0; i<(fb->w * fb->h); i++) {
            fb->pixels[i] = fb->pixels[i*2];
        }
    } else if (sensor.pixformat == PIXFORMAT_JPEG) {
        /* The frame is finished, but DMA still waiting
           for data because we set max frame size
           so we need to abort the DMA transfer here */
        HAL_DMA_Abort(&DMAHandle);

        /* Read the number of data items transferred */
        fb->bpp = (MAX_XFER_SIZE - DMAHandle.Instance->NDTR)*4;
    }

    if (image != NULL) {
        image->w = fb->w;
        image->h = fb->h;
        image->bpp = fb->bpp;
        image->pixels = fb->pixels;
    }

    fb->ready = 1;

    /* unlock framebuffer mutex */
    mutex_unlock(&fb->lock);

    while (fb->lock_tried) {
        systick_sleep(2);
    }
    return 0;
}
예제 #8
0
static int reset(sensor_t *sensor)
{
    int i=0;
    const uint8_t (*regs)[2];

    // Reset all registers
    SCCB_Write(sensor->slv_addr, COM7, COM7_RESET);

    // Delay 10 ms
    systick_sleep(10);

    // Write default regsiters
    for (i=0, regs = default_regs; regs[i][0]; i++) {
        SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
    }

    // Delay
    systick_sleep(30);

    return 0;
}
예제 #9
0
파일: usart.c 프로젝트: CNCBASHER/openmv
void usart_init(int baudrate)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	/* enable peripheral clock for USART3 */
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);

	/* GPIOD clock enable */
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

	/* GPIOA Configuration:  USART3 TX on PD8/9 */
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
	GPIO_Init(GPIOD, &GPIO_InitStructure);

	/* Connect USART3 pins to AF2 */
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource8, GPIO_AF_USART3);
	GPIO_PinAFConfig(GPIOD, GPIO_PinSource9, GPIO_AF_USART3);

    /* Disable USART */
	USART_Cmd(USART3, DISABLE);
    systick_sleep(10);
    USART_DeInit(USART3);
    systick_sleep(10);

	USART_InitStructure.USART_BaudRate = baudrate;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;

	USART_Init(USART3, &USART_InitStructure);
	USART_Cmd(USART3, ENABLE); // enable USART3
}
예제 #10
0
파일: sccb.c 프로젝트: 12019/openmv
uint8_t SCCB_Probe()
{
    uint8_t reg = 0x00;
    uint8_t slv_addr = 0x00;

    for (int i=0; i<127; i++) {
        if (HAL_I2C_Master_Transmit(&I2CHandle, i, &reg, 1, TIMEOUT) == HAL_OK) {
            slv_addr = i;
            break;
        }
        if (i!=126) {
            systick_sleep(1); // Necessary for OV7725 camera (not for OV2640).
        }
    }
    return slv_addr;
}
예제 #11
0
static int set_framesize(sensor_t *sensor, framesize_t framesize)
{
    int ret=0;
    uint16_t w = resolution[framesize][0];
    uint16_t h = resolution[framesize][1];

    // Write MSBs
    ret |= SCCB_Write(sensor->slv_addr, HOUTSIZE, w>>2);
    ret |= SCCB_Write(sensor->slv_addr, VOUTSIZE, h>>1);

    // Write LSBs
    ret |= SCCB_Write(sensor->slv_addr, EXHCH, ((w&0x3) | ((h&0x1) << 2)));

    // Delay
    systick_sleep(30);

    return ret;
}
예제 #12
0
파일: ov9650.c 프로젝트: mfauziz/openmv
static int reset(sensor_t *sensor)
{
    int i=0;
    const uint8_t (*regs)[2]=default_regs;

    /* Reset all registers */
    SCCB_Write(sensor->slv_addr, REG_COM7, 0x80);

    /* delay n ms */
    systick_sleep(10);

    /* Write initial regsiters */
    while (regs[i][0]) {
        SCCB_Write(sensor->slv_addr, regs[i][0], regs[i][1]);
        i++;
    }

    return 0;
}
예제 #13
0
//*****************************************************************************
//
//! initDriver
//!
//!  \param[in] cRequestPatch 0 to load with EEPROM patches 
//!             and 1 to load with no patches
//!
//!  \return none
//!
//!  \brief  The function initializes a CC3000 device 
//!          and triggers it to start operation
//
//*****************************************************************************
static int initDriver(unsigned short cRequestPatch)
{
    // WLAN On API Implementation
    wlan_init(CC3000_UsynchCallback, sendWLFWPatch, sendDriverPatch, sendBootLoaderPatch,
              ReadWlanInterruptPin, SpiResumeSpi, SpiPauseSpi, WriteWlanPin);

    // Trigger a WLAN device
    wlan_start(cRequestPatch);
    wlan_smart_config_set_prefix((char*)aucCC3000_prefix);
    wlan_ioctl_set_connection_policy(0, 0, 0);
    wlan_ioctl_del_profile(255);

    // Mask out all non-required events from CC3000
    wlan_set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|
                        HCI_EVNT_WLAN_UNSOL_INIT|
                        HCI_EVNT_WLAN_ASYNC_PING_REPORT);

    //unsolicicted_events_timer_init();
    systick_sleep(100);
    return(0);
}
예제 #14
0
파일: main.c 프로젝트: turmary/am18x-lib
int main(int argc, char* argv[]) {
	const char* title = "\nam18x library for ecap!\n";
	int i;

	arm_intr_enable();
	systick_start();

	printk(title);
	printk("tary, compiled date : %s %s\n", __DATE__, __TIME__);

	psc_state_transition(PSC_GPIO, PSC_STATE_ENABLE);
	psc_state_transition(PSC_ECAP, PSC_STATE_ENABLE);

	gpio_set_mux(LCDC_BL_PWR, GPIO_DIR_OUTPUT);
	gpio_set_output1(LCDC_BL_PWR, GPIO_HIGH);

	#if 0
	gpio_set_mux(LCDC_BL_PWM, GPIO_DIR_OUTPUT);
	gpio_set_output1(LCDC_BL_PWM, GPIO_HIGH);
	#else
	syscfg_pinmux(LCDC_BL_PWM_PINMUX);
	#endif

	ecap_init(ECAP_HW);

	for (i = 0;; i += 5) {
		if (i > 100) {
			i = 0;
		}
		ecap_conf->duty = i;
		ecap_set_conf(ECAP_HW, ecap_conf);

		systick_sleep(1000);
	}

	return 0;
}
예제 #15
0
파일: main.c 프로젝트: godda/openmv
int main(void)
{
    rcc_ctrl_set_frequency(SYSCLK_168_MHZ);

    /* Init SysTick timer */
    systick_init();

    /* Init MicroPython */
    libmp_init();

    /* init USB debug */
    usbdbg_init();

    /* init rng */
    rng_init();

    /* Add functions to the global python namespace */
    mp_store_global(qstr_from_str("help"), mp_make_function_n(0, py_help));
    mp_store_global(qstr_from_str("open"), mp_make_function_n(2, py_file_open));
    mp_store_global(qstr_from_str("vcp_connected"), mp_make_function_n(0, py_vcp_connected));
    mp_store_global(qstr_from_str("info"), mp_make_function_n(0, py_info));
    mp_store_global(qstr_from_str("gc_collect"), mp_make_function_n(0, py_gc_collect));
    mp_store_global(qstr_from_str("Image"), mp_make_function_n(1, py_image_load_image));
    mp_store_global(qstr_from_str("HaarCascade"), mp_make_function_n(1, py_image_load_cascade));

    /* Export Python modules to the global python namespace */
    for (const module_t *p = exported_modules; p->name != NULL; p++) {
        const mp_obj_module_t *module = p->init();
        if (module == NULL) {
            __fatal_error("failed to init module");
        } else {
            mp_module_register(p->name, (mp_obj_t)module);
        }
    }

    /* prepare workarea for sdcard fs */
    f_mount(&fatfs1, "1:", 0);

    /* Try to mount the flash fs */
    bool reset_filesystem = false;
    FRESULT res = f_mount(&fatfs0, "0:", 1);
    if (!reset_filesystem && res == FR_OK) {
        /* Mount sucessful */
    } else if (reset_filesystem || res == FR_NO_FILESYSTEM) {
        /* No filesystem, so create a fresh one */
        res = f_mkfs("0:", 0, 0);
        if (res != FR_OK) {
            __fatal_error("could not create LFS");
        }

        /* Create main.py */
        FIL fp;
        f_open(&fp, "0:/main.py", FA_WRITE | FA_CREATE_ALWAYS);
        UINT n;
        f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
        // TODO check we could write n bytes
        f_close(&fp);
    } else {
        __fatal_error("could not access LFS");
    }

    pyb_usb_dev_init(PYB_USB_DEV_VCP_MSC);

#if 1
    /* run main script */
    if (!libmp_do_file("0:/main.py")) {
        printf("failed to run main script\n");
    }

    libmp_do_repl();
#else
//  led_init(LED_BLUE);

    systick_sleep(100);
    wlan_test();
#endif
    while(1);
}
예제 #16
0
static mp_obj_t py_lcd_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args)
{
    py_lcd_deinit();
    switch (py_helper_keyword_int(n_args, args, 0, kw_args, MP_OBJ_NEW_QSTR(MP_QSTR_type), LCD_SHIELD)) {
        case LCD_NONE:
            return mp_const_none;
        case LCD_SHIELD:
        {
            GPIO_InitTypeDef GPIO_InitStructure;
            GPIO_InitStructure.Pull  = GPIO_NOPULL;
            GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
            GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_OD;

            GPIO_InitStructure.Pin = CS_PIN;
            CS_PIN_WRITE(true); // Set first to prevent glitches.
            HAL_GPIO_Init(CS_PORT, &GPIO_InitStructure);

            GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;

            GPIO_InitStructure.Pin = RST_PIN;
            RST_PIN_WRITE(true); // Set first to prevent glitches.
            HAL_GPIO_Init(RST_PORT, &GPIO_InitStructure);

            GPIO_InitStructure.Pin = RS_PIN;
            RS_PIN_WRITE(true); // Set first to prevent glitches.
            HAL_GPIO_Init(RS_PORT, &GPIO_InitStructure);

            spi_port = pyb_spi_make_new(NULL,
                2, // n_args
                3, // n_kw
                (mp_obj_t []) {
                    MP_OBJ_NEW_SMALL_INT(2), // SPI Port
                    MP_OBJ_NEW_SMALL_INT(SPI_MODE_MASTER),
                    MP_OBJ_NEW_QSTR(MP_QSTR_baudrate),
                    MP_OBJ_NEW_SMALL_INT(1000000000/66), // 66 ns clk period
                    MP_OBJ_NEW_QSTR(MP_QSTR_polarity),
                    MP_OBJ_NEW_SMALL_INT(0),
                    MP_OBJ_NEW_QSTR(MP_QSTR_phase),
                    MP_OBJ_NEW_SMALL_INT(0)
                }
            );
            width = 128;
            height = 160;
            type = LCD_SHIELD;
            backlight_init = false;

            RST_PIN_WRITE(false);
            systick_sleep(100);
            RST_PIN_WRITE(true);
            systick_sleep(100);
            lcd_write_command_byte(0x11); // Sleep Exit
            systick_sleep(120);

            // Memory Data Access Control
            lcd_write_command(0x36, 1, (uint8_t []) {0xC0});

            // Interface Pixel Format
            lcd_write_command(0x3A, 1, (uint8_t []) {0x05});

            // Display on
            lcd_write_command_byte(0x29);

            return mp_const_none;
        }
    }
    return mp_const_none;
}
예제 #17
0
void patch_prog_start()
{
    unsigned short  index;
    unsigned char   *pRMParams;

    printf("Initializing module...\n");

    // Init module and request to load with no patches.
    // This is in order to overwrite restrictions to
    // write to specific places in EEPROM.
    initDriver(1);

    // Read MAC address.
    mac_status = nvmem_get_mac_address(cMacFromEeprom);

    return_status = 1;

    printf("Reading RM parameters...\n");
    while ((return_status) && (counter < 3)) {
        // Read RM parameters.
        // Read in 16 parts to work with tiny driver.
        return_status = 0;
        pRMParams = cRMParamsFromEeprom;
        for (index = 0; index < 16; index++) {
            return_status |= nvmem_read(NVMEM_RM_FILEID, 8, 8*index, pRMParams);
            pRMParams += 8;
        }
        counter++;
    }

    // If RM file is not valid, load the default one.
    if (counter == 3) {
        printf("RM is not valid, loading default one...\n");
        pRMParams = (unsigned char *)cRMdefaultParams;
    } else {
        printf("RM is valid.\n");
        pRMParams = cRMParamsFromEeprom;
    }

    return_status = 1;

    printf("Writing new FAT\n");
    while (return_status) {
        // Write new FAT.
        return_status = fat_write_content(aFATEntries[0], aFATEntries[1]);
    }

    return_status = 1;

    printf("Writing RM parameters...\n");
    while (return_status) {
        // Write RM parameters.
        // Write in 4 parts to work with tiny driver.
        return_status = 0;

        for (index = 0; index < 4; index++) {
            return_status |= nvmem_write(NVMEM_RM_FILEID,
                                         32,
                                         32*index,
                                         (pRMParams + 32*index)); 
        }
    }

    return_status = 1;

    // Write back the MAC address, only if exists.
    if (mac_status == 0) {
        // Zero out MCAST bit if set.
        cMacFromEeprom[0] &= 0xfe;
        printf("Writing back MAC address..\n");
        while (return_status) {
            return_status = nvmem_set_mac_address(cMacFromEeprom);
        }
    }

    // Update driver
    ucStatus_Dr = 1;
    printf("Updating driver patch...\n");
    while (ucStatus_Dr) {
        // Writing driver patch to EEPRROM - PROTABLE CODE
        // Note that the array itself is changing between the
        // different Service Packs.
        ucStatus_Dr = nvmem_write_patch(NVMEM_WLAN_DRIVER_SP_FILEID,
                                        drv_length,
                                        wlan_drv_patch);
    }

    // Update firmware
    ucStatus_FW = 1;
    printf("Updating firmware patch...\n");
    while (ucStatus_FW) {
        // Writing FW patch to EEPRROM - PROTABLE CODE
        // Note that the array itself is changing between the
        // different Service Packs.
        ucStatus_FW = nvmem_write_patch(NVMEM_WLAN_FW_SP_FILEID,
                                        fw_length,
                                        fw_patch);
    }

    printf("Update complete, resetting module\n"\
           "If this doesn't work, reset manually...\n");

    wlan_stop();
    systick_sleep(500);

    // Re-Init module and request to load with patches.
    initDriver(0);

    // If MAC does not exist, it is recommended
    // that the user will write a valid mac address.
    if (mac_status != 0) {
        printf("MAC address is not valid, please write a new one\n");
    }

    // Patch update done
    printf("All done, call wlan.patch_version()\n");
}
예제 #18
0
파일: sensor.c 프로젝트: dhylands/openmv
int sensor_init()
{
    /* Do a power cycle */
    DCMI_PWDN_HIGH();
    systick_sleep(10);

    DCMI_PWDN_LOW();
    systick_sleep(100);

    /* Initialize the SCCB interface */
    SCCB_Init();
    systick_sleep(10);

    /* Configure the external clock (XCLK) */
    extclk_config(XCLK_FREQ);
    systick_sleep(10);

    /* Reset the sesnor state */
    memset(&sensor, 0, sizeof(struct sensor_dev));

    /* Some sensors have different reset polarities, and we can't know which sensor
       is connected before initializing SCCB and reading the PID register, which in
       turn requires pulling the sensor out of the reset state. So we try to read a
       register with both polarities to determine line state. */
    sensor.reset_pol = ACTIVE_HIGH;

    DCMI_RESET_HIGH();
    systick_sleep(10);

    DCMI_RESET_LOW();
    systick_sleep(10);

    /* Check if we can read PID */
    if (SCCB_Read(REG_PID) == 255) {
        /* Sensor is held in reset, so reset is active high */
        sensor.reset_pol = ACTIVE_LOW;

        DCMI_RESET_LOW();
        systick_sleep(10);

        DCMI_RESET_HIGH();
        systick_sleep(10);
    }

    /* Read the sensor information */
    sensor.id.MIDH = SCCB_Read(REG_MIDH);
    sensor.id.MIDL = SCCB_Read(REG_MIDL);
    sensor.id.PID  = SCCB_Read(REG_PID);
    sensor.id.VER  = SCCB_Read(REG_VER);

    /* Call the sensor-specific init function */
    switch (sensor.id.PID) {
        case OV9650_PID:
            ov9650_init(&sensor);
            break;
        case OV2640_PID:
            ov2640_init(&sensor);
            break;
        default:
            /* sensor not supported */
            return -1;
    }

    /* Configure the DCMI DMA Stream */
    if (dma_config() != 0) {
        return -1;
    }

    /* Configure the DCMI interface. This should be called
       after ovxxx_init to set VSYNC/HSYNC/PCLK polarities */
    if (dcmi_config() != 0){
        return -1;
    }

    /* init/re-init mutex */
    mutex_init(&fb->lock);
    return 0;
}
예제 #19
0
int sensor_init()
{
    /* Do a power cycle */
    DCMI_PWDN_HIGH();
    systick_sleep(10);

    DCMI_PWDN_LOW();
    systick_sleep(100);

    /* Initialize the SCCB interface */
    SCCB_Init();
    systick_sleep(10);

    /* Configure the sensor external clock (XCLK) to XCLK_FREQ (13MHz).
       Note: The sensor's internal PLL (when CLKRC=0x80) doubles the XCLK_FREQ
             (XCLK=XCLK_FREQ*2), and the unscaled PIXCLK output is XCLK_FREQ*4 */
    extclk_config(XCLK_FREQ);

    /* Uncomment this to pass through the MCO1 clock (HSI=16MHz) this results in a
       64MHz PIXCLK output from the sensor.
       Note: The maximum pixel clock input on the STM32F4xx is 54MHz,
             the STM32F7 can probably handle higher input pixel clock.
       */
    //(void) extclk_config;
    //HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1);

    /* Reset the sesnor state */
    memset(&sensor, 0, sizeof(struct sensor_dev));

    /* Some sensors have different reset polarities, and we can't know which sensor
       is connected before initializing SCCB and reading the PID register, which in
       turn requires pulling the sensor out of the reset state. So we try to read a
       register with both polarities to determine line state. */
    sensor.reset_pol = ACTIVE_HIGH;

    DCMI_RESET_HIGH();
    systick_sleep(10);

    DCMI_RESET_LOW();
    systick_sleep(10);

    /* Check if we can read PID */
    if (SCCB_Read(REG_PID) == 255) {
        /* Sensor is held in reset, so reset is active high */
        sensor.reset_pol = ACTIVE_LOW;

        DCMI_RESET_LOW();
        systick_sleep(10);

        DCMI_RESET_HIGH();
        systick_sleep(10);
    }

    /* Read the sensor information */
    sensor.id.MIDH = SCCB_Read(REG_MIDH);
    sensor.id.MIDL = SCCB_Read(REG_MIDL);
    sensor.id.PID  = SCCB_Read(REG_PID);
    sensor.id.VER  = SCCB_Read(REG_VER);

    /* Call the sensor-specific init function */
    switch (sensor.id.PID) {
        case OV9650_PID:
            ov9650_init(&sensor);
            break;
        case OV2640_PID:
            ov2640_init(&sensor);
            break;
        default:
            /* sensor not supported */
            return -1;
    }

    /* Configure the DCMI DMA Stream */
    if (dma_config() != 0) {
        return -2;
    }

    /* Configure the DCMI interface. This should be called
       after ovxxx_init to set VSYNC/HSYNC/PCLK polarities */
    if (dcmi_config(DCMI_JPEG_DISABLE) != 0){
        return -3;
    }

    /* init/re-init mutex */
    mutex_init(&fb->lock);

    // blocks usbdbg until the sensor is configured
    fb->ready=0;
    return 0;
}