/*
 * Initialize the SD RAM controller.
 */
void
sdram_init(void) {
	int i;
	uint32_t cr_tmp, tr_tmp; /* control, timing registers */

	/*
	* First all the GPIO pins that end up as SDRAM pins
	*/
	rcc_periph_clock_enable(RCC_GPIOB);
	rcc_periph_clock_enable(RCC_GPIOC);
	rcc_periph_clock_enable(RCC_GPIOD);
	rcc_periph_clock_enable(RCC_GPIOE);
	rcc_periph_clock_enable(RCC_GPIOF);
	rcc_periph_clock_enable(RCC_GPIOG);

	for (i = 0; i < 6; i++) {
		gpio_mode_setup(sdram_pins[i].gpio,
				GPIO_MODE_AF, GPIO_PUPD_NONE,
				sdram_pins[i].pins);
		gpio_set_output_options(sdram_pins[i].gpio, GPIO_OTYPE_PP,
					GPIO_OSPEED_50MHZ, sdram_pins[i].pins);
		gpio_set_af(sdram_pins[i].gpio, GPIO_AF12, sdram_pins[i].pins);
	}

	/* Enable the SDRAM Controller */
#if 1
	rcc_periph_clock_enable(RCC_FSMC);
#else
	rcc_peripheral_enable_clock(&RCC_AHB3ENR, RCC_AHB3ENR_FMCEN);
#endif

	/* Note the STM32F429-DISCO board has the ram attached to bank 2 */
	/* Timing parameters computed for a 168Mhz clock */
	/* These parameters are specific to the SDRAM chip on the board */

	cr_tmp  = FMC_SDCR_RPIPE_1CLK;
	cr_tmp |= FMC_SDCR_SDCLK_2HCLK;
	cr_tmp |= FMC_SDCR_CAS_3CYC;
	cr_tmp |= FMC_SDCR_NB4;
	cr_tmp |= FMC_SDCR_MWID_16b;
	cr_tmp |= FMC_SDCR_NR_12;
	cr_tmp |= FMC_SDCR_NC_8;

	/* We're programming BANK 2, but per the manual some of the parameters
	 * only work in CR1 and TR1 so we pull those off and put them in the
	 * right place.
	 */
	FMC_SDCR1 |= (cr_tmp & FMC_SDCR_DNC_MASK);
	FMC_SDCR2 = cr_tmp;

	tr_tmp = sdram_timing(&timing);
	FMC_SDTR1 |= (tr_tmp & FMC_SDTR_DNC_MASK);
	FMC_SDTR2 = tr_tmp;

	/* Now start up the Controller per the manual
	 *	- Clock config enable
	 *	- PALL state
	 *	- set auto refresh
	 *	- Load the Mode Register
	 */
	sdram_command(SDRAM_BANK2, SDRAM_CLK_CONF, 1, 0);
	milli_sleep(1); /* sleep at least 100uS */
	sdram_command(SDRAM_BANK2, SDRAM_PALL, 1, 0);
	sdram_command(SDRAM_BANK2, SDRAM_AUTO_REFRESH, 4, 0);
	tr_tmp = SDRAM_MODE_BURST_LENGTH_2				|
				SDRAM_MODE_BURST_TYPE_SEQUENTIAL	|
				SDRAM_MODE_CAS_LATENCY_3		|
				SDRAM_MODE_OPERATING_MODE_STANDARD	|
				SDRAM_MODE_WRITEBURST_MODE_SINGLE;
	sdram_command(SDRAM_BANK2, SDRAM_LOAD_MODE, 1, tr_tmp);

	/*
	 * set the refresh counter to insure we kick off an
	 * auto refresh often enough to prevent data loss.
	 */
	FMC_SDRTR = 683;
	/* and Poof! a 8 megabytes of ram shows up in the address space */
}
Ejemplo n.º 2
0
int Dfu::download(const QString &filename)
{
    int bytes_sent = 0;
    unsigned char *buf;
    struct dfu_status dst;
    int ret;
    int fsize;
    unsigned int bytes_left;
    int chunk_size;
    const char *exception = NULL;

    FILE *filep = fopen(filename.toUtf8(), "rb");
    if (filep == NULL)
        throw std::runtime_error("Cannot open file.");

    buf = (unsigned char *)malloc(m_transfer_size);
    fseek(filep, 0, SEEK_END);
    fsize = ftell(filep);
    rewind(filep);

    while (bytes_sent < fsize)
    {
        bytes_left = fsize - bytes_sent;
        if (bytes_left < m_transfer_size)
            chunk_size = bytes_left;
        else
            chunk_size = m_transfer_size;
        ret = fread(buf, 1, chunk_size, filep);
        if (ret < 0)
        {
            exception = "Error while reading file.";
            goto exit;
        }
        ret = dfu_download(m_dif.dev_handle, m_dif.interface, ret, ret ? buf : NULL);
        if (ret < 0)
        {
            exception = "Error while downloading DFU file.";
            goto exit;
        }
        bytes_sent += ret;

        do {
            ret = dfu_get_status(m_dif.dev_handle, m_dif.interface, &dst);
            if (ret < 0)
            {
                exception = "Error while getting status.";
                goto exit;
            }

            if (dst.bState == DFU_STATE_dfuDNLOAD_IDLE ||
                    dst.bState == DFU_STATE_dfuERROR)
                break;

            milli_sleep(dst.bwPollTimeout);

        } while (1);

        if (dst.bStatus != DFU_STATUS_OK)
        {
            exception = "Bad status during DFU download.";
            goto exit;
        }
    }

    /* send one zero sized download request to signalize end */
    ret = dfu_download(m_dif.dev_handle, m_dif.interface, 0, NULL);
    if (ret < 0)
    {
        exception = "Error while downloading DFU file.";
        goto exit;
    }

    /* Transition to MANIFEST_SYNC state */
    ret = dfu_get_status(m_dif.dev_handle, m_dif.interface, &dst);

exit:
    free(buf);
    fclose(filep);
    if (exception)
        throw std::runtime_error(exception);

    return bytes_sent;
}