Esempio n. 1
0
void write_flash_memory_block(unsigned char *src, uint32_t start_addr,unsigned short num_bytes)
{
    // 1. Write the 2 DMA descriptors to RAM
    write_xdata_memory_block(ADDR_DMA_DESC_0, dma_desc_0, 8);
    write_xdata_memory_block(ADDR_DMA_DESC_1, dma_desc_1, 8);

    // 2. Update LEN value in DUP's DMA descriptors
    unsigned char len[2] = {HIBYTE(num_bytes), LOBYTE(num_bytes)};
    write_xdata_memory_block((ADDR_DMA_DESC_0+4), len, 2);  // LEN, DBG => ram
    write_xdata_memory_block((ADDR_DMA_DESC_1+4), len, 2);  // LEN, ram => flash

    // 3. Set DMA controller pointer to the DMA descriptors
    write_xdata_memory(DUP_DMA0CFGH, HIBYTE(ADDR_DMA_DESC_0));
    write_xdata_memory(DUP_DMA0CFGL, LOBYTE(ADDR_DMA_DESC_0));
    write_xdata_memory(DUP_DMA1CFGH, HIBYTE(ADDR_DMA_DESC_1));
    write_xdata_memory(DUP_DMA1CFGL, LOBYTE(ADDR_DMA_DESC_1));

    // 4. Set Flash controller start address (wants 16MSb of 18 bit address)
    start_addr >>= 2;
	write_xdata_memory(DUP_FADDRH, HIBYTE( start_addr ));
    write_xdata_memory(DUP_FADDRL, LOBYTE( start_addr ));

    // 5. Arm DBG=>buffer DMA channel and start burst write
    write_xdata_memory(DUP_DMAARM, CH_DBG_TO_BUF0);
    burst_write_block(src, num_bytes);

    // 6. Start programming: buffer to flash
    write_xdata_memory(DUP_DMAARM, CH_BUF0_TO_FLASH);
    write_xdata_memory(DUP_FCTL, 0x06);

    // 7. Wait until flash controller is done
    while (read_xdata_memory(DUP_FCTL) & 0x80);
}
Esempio n. 2
0
//==============================================================================
uint16_t CC_UnitDriver::calc_block_crc()
{
    write_xdata_memory(reg_info_.rndl, 0xFF);
    write_xdata_memory(reg_info_.rndl, 0xFF);
    write_xdata_memory(reg_info_.dma_arm, 0x01);
    write_xdata_memory(reg_info_.dma_req, 0x01);

    while (!(read_xdata_memory(reg_info_.dma_irq) & 0x01));

    ByteVector xsfr;
    read_xdata_memory(reg_info_.rndl, 2, xsfr);
    return xsfr[0] | (xsfr[1] << 8);
}
Esempio n. 3
0
//==============================================================================
void CC_UnitDriver::write_flash_slow(const DataSectionStore &section_store)
{
	const size_t WRITE_BLOCK_SIZE = reg_info_.write_block_size;

	// Channel 0: Xdata buffer -> Flash controller
	uint8_t dma_desc[8] = {
		  HIBYTE(reg_info_.dma_data_offset),// src[15:8]
		  LOBYTE(reg_info_.dma_data_offset),// src[7:0]
		  HIBYTE(reg_info_.fwdata),    		// dest[15:8]
		  LOBYTE(reg_info_.fwdata),      	// dest[7:0]
		  HIBYTE(WRITE_BLOCK_SIZE),			// block size[15:8]
		  LOBYTE(WRITE_BLOCK_SIZE),			// block size[7:0]
		  18,								// trigger FLASH
		  0x42 								// increment source
	};

	// Load dma descriptors
	write_xdata_memory(reg_info_.dma0_cfg_offset, dma_desc, sizeof(dma_desc));

	// Set the pointer to the DMA descriptors
	write_xdata_memory(reg_info_.dma0_cfgl, LOBYTE(reg_info_.dma0_cfg_offset));
	write_xdata_memory(reg_info_.dma0_cfgh, HIBYTE(reg_info_.dma0_cfg_offset));

	size_t faddr = 0xFFFF;

	ByteVector data;
	section_store.create_image(0xFF, data);
	data.resize((section_store.upper_address() + (WRITE_BLOCK_SIZE - 1)) &
			~(WRITE_BLOCK_SIZE - 1), 0xFF);

	pw_.write_start(data.size());

	ByteVector empty_block;
	empty_block.resize(WRITE_BLOCK_SIZE, 0xFF);

	for (size_t i = 0; i < (data.size() / WRITE_BLOCK_SIZE); i++)
	{
		pw_.write_progress(WRITE_BLOCK_SIZE);

		size_t offset = WRITE_BLOCK_SIZE * i;
		if (!memcmp(&data[offset], &empty_block[0], WRITE_BLOCK_SIZE))
			continue;

		size_t new_faddr = WRITE_BLOCK_SIZE * i / reg_info_.flash_word_size;
		if (new_faddr != faddr)
		{
			faddr = WRITE_BLOCK_SIZE * i / reg_info_.flash_word_size;
			write_xdata_memory(reg_info_.faddrl, LOBYTE(faddr));
			write_xdata_memory(reg_info_.faddrh, HIBYTE(faddr));
			faddr += WRITE_BLOCK_SIZE / reg_info_.flash_word_size;
		}

		write_xdata_memory(reg_info_.dma_data_offset, &data[offset], WRITE_BLOCK_SIZE);

		write_xdata_memory(reg_info_.dma_arm, 0x01);
		write_xdata_memory(reg_info_.fctl, reg_info_.fctl_write);
		while ((read_xdata_memory(reg_info_.fctl) & 0x80));
	}
	pw_.write_finish();
}
Esempio n. 4
0
//==============================================================================
void CC_UnitDriver::flash_read(size_t offset, size_t size, ByteVector &flash_data)
{
    uint8_t flash_bank = 0xFF;

    while (size)
    {
        size_t bank_offset = offset % FLASH_BANK_SIZE;
        size_t count = std::min(size, (size_t)0x8000);
        uint8_t flash_bank_0 = offset / FLASH_BANK_SIZE;
        uint8_t flash_bank_1 = (offset + count) / FLASH_BANK_SIZE;

        if (flash_bank_0 != flash_bank_1)
            size_t count = ((offset + count) % FLASH_BANK_SIZE);

        if (flash_bank != flash_bank_0)
        {
            flash_bank = flash_bank_0;
            write_xdata_memory(reg_info_.fmap, flash_bank);
            bank_offset = offset % FLASH_BANK_SIZE;
        }

        flash_read_near(bank_offset + reg_info_.xbank_offset, count, flash_data);

        size -= count;
        offset += count;
    }
}
Esempio n. 5
0
//==============================================================================
bool CC_UnitDriver::erase_page(uint_t page_offset)
{
    page_offset /= reg_info_.flash_word_size;

    write_xdata_memory(reg_info_.faddrl, 0);
    write_xdata_memory(reg_info_.faddrh, HIBYTE(page_offset));

    // erase
    write_xdata_memory(reg_info_.fctl, FCTL_ERASE);

    // wait for write to finish
    uint8_t reg;
    while ((reg = read_xdata_memory(reg_info_.fctl)) & FCTL_BUSY);

    return !(reg & FCTL_ABORT);
}
Esempio n. 6
0
void read_flash_memory_block(unsigned char bank,unsigned short flash_addr,unsigned short num_bytes, unsigned char *values)
{
    unsigned char instr[3];
    unsigned short i;
    unsigned short xdata_addr = (0x8000 + flash_addr);

    // 1. Map flash memory bank to XDATA address 0x8000-0xFFFF
    write_xdata_memory(DUP_MEMCTR, bank);

    // 2. Move data pointer to XDATA address (MOV DPTR, xdata_addr)
    instr[0] = 0x90;
    instr[1] = HIBYTE(xdata_addr);
    instr[2] = LOBYTE(xdata_addr);
    HM10SendDebugCommand(instr, 3);

    for (i = 0; i < num_bytes; i++)
    {
	    // 3. Move value pointed to by DPTR to accumulator (MOVX A, @DPTR)
	    instr[0] = 0xE0;
	    values[i] = HM10SendDebugCommand(instr, 1);

	    // 4. Increment data pointer (INC DPTR)
	    instr[0] = 0xA3;
	    HM10SendDebugCommand(instr, 1);
    }
}
Esempio n. 7
0
//==============================================================================
bool CC_UnitDriver::flash_verify_by_crc(const DataSectionStore &section_store)
{
    // Channel 0: Flash mapped to Xdata -> CRC shift register
    uint8_t dma_desc[8] = {
        HIBYTE(reg_info_.xbank_offset),   // src[15:8]
        LOBYTE(reg_info_.xbank_offset),   // src[7:0]
        HIBYTE(reg_info_.rndh),    		// dest[15:8]
        LOBYTE(reg_info_.rndh),      		// dest[7:0]
        HIBYTE(reg_info_.verify_block_size),// block size[15:8]
        LOBYTE(reg_info_.verify_block_size),// block size[7:0]
        0x20,                     		// no trigger event, block mode
        0x42,                   			// increment source
    };

    write_xdata_memory(reg_info_.dma_arm, 0x00);

    // set the pointer to the DMA descriptors
    write_xdata_memory(reg_info_.dma0_cfgl, LOBYTE(reg_info_.dma0_cfg_offset));
    write_xdata_memory(reg_info_.dma0_cfgh, HIBYTE(reg_info_.dma0_cfg_offset));

    size_t flash_bank = 0xFF; // correct flash bank will be set later

    pw_.read_start(section_store.actual_size());

    foreach (const DataSection &section, section_store.sections())
    {
        size_t section_offset = section.address;
        size_t total_size = section.size();
        size_t bank_offset = section_offset % FLASH_BANK_SIZE;
        while (total_size)
        {
            size_t count = std::min(total_size, reg_info_.verify_block_size);
            size_t flash_bank_0 = section_offset / FLASH_BANK_SIZE;
            size_t flash_bank_1 = (section_offset + count) / FLASH_BANK_SIZE;

            if (flash_bank_0 != flash_bank_1)
                count = FLASH_BANK_SIZE - (section_offset % FLASH_BANK_SIZE);

            if (flash_bank != flash_bank_0)
            {
                flash_bank = flash_bank_0;
                if (reg_info_.memctr)
                    write_xdata_memory(reg_info_.memctr, flash_bank);
                bank_offset = section_offset % FLASH_BANK_SIZE;
            }

            dma_desc[0] = HIBYTE(bank_offset + reg_info_.xbank_offset);
            dma_desc[1] = LOBYTE(bank_offset + reg_info_.xbank_offset);
            dma_desc[4] = HIBYTE(count);
            dma_desc[5] = LOBYTE(count);
            write_xdata_memory(reg_info_.dma0_cfg_offset, dma_desc, sizeof(dma_desc));

            CrcCalculator crc_calc;
            crc_calc.process_bytes(&section.data[section.size() - total_size], count);
            if (calc_block_crc() != crc_calc.checksum())
                return false;

            total_size -= count;
            section_offset += count;
            bank_offset += count;

            pw_.read_progress(count);
        }
    }
    pw_.read_finish();
    return true;
}
Esempio n. 8
0
//==============================================================================
void CC_UnitDriver::write_xdata_memory(uint16_t address, const ByteVector &data)
{
    write_xdata_memory(address, &data[0], data.size());
}
Esempio n. 9
0
//==============================================================================
void CC_UnitDriver::write_xdata_memory(uint16_t address, uint8_t data)
{
    write_xdata_memory(address, &data, 1);
}