Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
11 years ago

Configuring Cyclone IV E over serial interface problem

Hello,

I have a setup in which an MCU is hooked to a Cyclone IV E with two options for configuration. The first option uses a compressed .rbf file saved in the MCU's flash memory and feeds it to the fpga through the Active Serial connection (AS). This works fine. However, the second option goes like this PC -> TCP -> MCU -> AS -> FPGA. I receive packets over TCP with 256 byte long chunks of a decropressed rbf from a PC application. All packets are correctly received by the MCU and retransmitted over the AS to the FPGA. Sadly, this isn't working. The CONF_DONE signal doesn't go high.

Here is the code for the first option (just for comparison)

void fpgaConfig(void){
    int i;
    int length;
    uint16_t temp;
    spiDAT1_t dataConfig;
    uint32 PC0Backup;
    gioSetBit(spiPORT1, SPI_PIN_SOMI, 0);    // nConfig low
    delay(0xffff);    // wait
    gioSetBit(spiPORT1, SPI_PIN_SOMI, 1);    // nConfig high
    while(gioGetBit(spiPORT1, SPI_PIN_ENA) == 0);    // wait until nStatus is high
    PC0Backup = spiREG1->PC0;
    spiSetFunctional(spiREG1, PC0Backup | (1U << SPI_PIN_SOMI));    // set nCONFIG as SPI pin
    dataConfig.CSNR = 0;
    dataConfig.CS_HOLD = 0;
    dataConfig.DFSEL = SPI_FMT_0;
    dataConfig.WDEL = 0;
    length = sizeof(designData);
    for(i = 0; i < length; i++)
    {
        temp = designData;
        spiTransmitData(spiREG1, &dataConfig, 1, &temp);
    }
    delay(0xfffff);    // wait
    while(gioGetBit(spiPORT2, SPI_PIN_CLK) == 0);    // wait until CONF_DONE is high
    while(gioGetBit(gioPORTB, 7) == 0);    // wait until INIT_DONE is high
    spiSetFunctional(spiREG1, PC0Backup);    // put back the original value. This is important to make reconfiguration possible
}

And here are the important parts of the second way:


case SEND_FPGA_DESIGN_START:            {
                if (state == PAIRED)
                {
                    receivingFpgaDesign = 1;
                    totalDesignSize = *((uint32 *)(&cmd.data));
                    packetsRemaining = *((uint16 *)(&cmd.data));
                    xSemaphoreTake(tcpSendProtection, portMAX_DELAY);//The mutex is freed in the server_sent callback
                    txBuffer = (uint8)FPGA_DESIGN_CONFIRMATION;
                    tcp_write(cmd.pcb, txBuffer, MINIMUM_PAYLOAD_LENGTH, 0);
                    tcp_output(cmd.pcb);
                }
                else
                {
                    state_machine_error();
                }
                break;
            }
            case SEND_FPGA_DESIGN_DATA:
            {
                if (state == PAIRED && receivingFpgaDesign)
                {
                    uint16 currentOrdinal = *((uint16 *)(&cmd.data));
                    if (currentOrdinal == 1) //This could also be in the previous CASE 
                    {
                        gioSetBit(spiPORT1, SPI_PIN_SOMI, 0);    // nConfig low
                        delay(0xffff);    // wait
                        gioSetBit(spiPORT1, SPI_PIN_SOMI, 1);    // nConfig high
                        while(gioGetBit(spiPORT1, SPI_PIN_ENA) == 0);    // wait until nStatus is high
                        PC0BackupValue = spiREG1->PC0;
                        spiSetFunctional(spiREG1, PC0BackupValue | (1U << SPI_PIN_SOMI));    // set nCONFIG as SPI pin
                        dataConfig.CSNR = 0;
                        dataConfig.CS_HOLD = 0;
                        dataConfig.DFSEL = SPI_FMT_0;
                        dataConfig.WDEL = 0;
                    }
                    if (currentOrdinal == lastOrdinal + 1)
                    {
                        lastOrdinal++;
                        if (packetsRemaining > 1)
                        {
                            int i;
                            uint16 temp;
                            for(i = 0; i < 256; i++)
                            {
                                temp = cmd.data;
                                spiTransmitData(spiREG1, &dataConfig, 1, &temp);
                            }
                            packetsRemaining--;
                        }
                        else //this was the last one
                        {
                            int i;
                            uint16 temp;
                            int upperBound = (totalDesignSize % 256) == 0 ? 256 : totalDesignSize % 256;
                            for(i = 0; i < upperBound; i++)
                            {
                                temp = cmd.data;
                                spiTransmitData(spiREG1, &dataConfig, 1, &temp);
                            }
                            delay(0xfffff);    // wait
                            while(gioGetBit(spiPORT2, SPI_PIN_CLK) == 0);    // HERE IT GETS STUCK
                            while(gioGetBit(gioPORTB, 7) == 0);    // wait until INIT_DONE is high
                            spiSetFunctional(spiREG1, PC0BackupValue);    // put back the original value. This is important to make reconfiguration possible
                        }

As you can see the second option is just like the first one only the data arrives in chunks.

Any ideas what the problem with the second one might be? I'm really at a loss now. I'd appreciate any help.

2 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Try reading back the portion of flash used for FPGA configuration in the working setup. Compare this to the data file you are sending using the MCU. There might be additional headers, byte swapping, checksums, etc that change the data as it is being programmed in flash.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Thank you,

    you were right. The data isn't the same. Now I must figure out how it got corrupted.

    Thanks again!