Post Go back to editing

ADSP-SC835 bootloader

Thread Summary

The user is implementing a bootloader for the ADSP-SC835 to boot from SPI1 flash and support firmware updates with a double slot scheme. The primary ADSP-SC835 will boot itself and then boot the secondary ADSP-SC835 via LinkPort. The solution involves creating a custom bootloader on the primary SHARC-FX core and ensuring proper softSwitch configuration on the secondary ADSP-SC835 to successfully receive and boot the firmware through LinkPort.
AI Generated Content
Category: Hardware

Hello, we are working with the ADSP-SC835, and we need to implement a bootloader that allows booting the system from a flash memory connected to SPI1, and also performing firmware updates with a double slots scheme (allowing rollbacks).
The complete system is composed of 2 units of ADSP-SC835, so our plan is to implement the bootloader in the primary SoC which should load the firmware on itself, and then boot the secondary SoC probably through LinkPort interface.

For development purposes we are working in CCES 3.0.3 with 2 ADSP-SC835W-EV-SOM + 2 SOMCRR breakout board, and they are connected thorugh LinkPort interface.As the primary core is the SHARC-FX, we understand that Mcuboot is not a suitable option, and we were not able to find any "out of the box" solution in the examples nor in the documentation (HRM / datasheet). Is there any example code or implementation that you would recomend for doing this task?

In the meantime we are implementing our custom bootloader from scratch as a separate project in CCES, which runs on SHARC-FX core, and basically calls adi_rom_Boot() to boot an LDR flashed in a specific address of the SPI1 flash memory of the SOM, with a double slot scheme defined by ourselves. In case there is no out-of-the-box implementation, would you recomend following this path? or perhaps would it be better to implement Mcuboot in ARM core for example, and boot the system from there?

Any recomendation is welcome, thank you.

Parents
  • ADI North America will be on winter shutdown starting December 24, 2024; perhaps another community member can assist you until our return on January 2, 2025.
  • Hi,

    We understand that your system consists of two ADSP-SC835. The requirement is to boot the primary ADSP-SC835 using SPI master boot mode. Once the primary device has successfully booted, it is then required to boot the secondary ADSP-SC835 via link port(Slave boot). Please confirm whether our understanding is correct.

    If so, both approaches mentioned below are feasible.

    Approach 1:
    The primary ADSP-SC835 boots directly from SPI flash in master boot mode. After the primary device has initialized, you can include host code in the primary application to boot the secondary ADSP-SC835 via link port.

    Approach 2:
    You can flash the application which needs to boot the primary ADSP-SC835 in sector 0 of the SPI flash. In this primary application, the adi_rom_boot API can be used to load a second application(Host application) stored in a different flash sector. Once this second application is executed, it boots the secondary ADSP-SC835 via link port.

    You may consider using the SPI peripheral instead of link port to boot the secondary ADSP-SC835.

    We don't have host example available for ADSP-SC835. Please refer the attached link port host example and the SPI host example available in the below link. Please use these codes as a reference and modify as per ADSP-SC835.

    Link_Port_21569_Host.zip
    ADSP-21569 SPI Host example 

    You can also take an reference of below mentioned FAQ.
    ADSP-SC598 SPI Master SSL Booting 

    Regards,
    Nandini C

  • Hi  , about the question in the first paragraph, your understanding is correct.
    I'll review the examples and test the LinkPort implementation adapting it to ADSP-SC835.

    Thank you very much.

    Leopoldo

  • Hi  , I've followed your recomendations but unluckily I'm not able to boot the secondary ADSP-SC835 in LinkPort boot mode, perhaps I'm still missing some details. 

    The setup is the one described in the first message, simplified as follows for tests:
    - SoC 1: ADSP-SC835 SOM + SOMCRR running an application from CCES 3.0.3 debug sesion with ICE-1000
    - SoC 2: ADSP-SC835 SOM + SOMCRR booted with rotary switch on Boot Mode 4: LinkPort Host
    - SoC 1 LinkPort_1 (Tx) connected to SoC2 LinkPort_0 (Rx) with LinkPort compatible cable on SOMCRR connectors

    SoC 1 runs a very simple application:
    - initializes components, SPU, soft-switches and UART for logs
    - system.svc has CLK, ACK, and all 8 LinkPort_1 data signals enabled
    - disables SYS_FAULT to allow LinkPort_1 clock usage: *pREG_PADS0_PCFG0 |= BITM_PADS_PCFG0_FAULT_DIS
    - includes the LDR file that will run on SoC 2, which was created without init file, and with "include" format:
    unsigned char source0[] __attribute__ ( (section(".L1.data")) ) __attribute__ ((aligned(32))) = {#include "../LDR/loader.ldr"};
    - finally sends the firmware for SoC 2 through LinkPort in one of the following ways:

    or using the LinkPort API as follows:

    	uint32_t fwSize = sizeof(source0);
    	uint32_t source0Offset = 0;
    	ADI_LINKPORT_RESULT lpResult;
    	ADI_LINKPORT_HANDLE linkPortTxHandle = NULL;
    	uint8_t linkPortTxMemory[ADI_LP_MEMORY_SIZE];
    	
        lpResult = adi_linkport_Open(1, ADI_LINKPORT_DIR_TX, linkPortTxMemory, ADI_LP_MEMORY_SIZE, &linkPortTxHandle);
        if ( lpResult != ADI_LINKPORT_SUCCESS )
            return lpResult;
    
        lpResult = adi_linkport_ConfigClock( linkPortTxHandle, 15 );
        if ( lpResult != ADI_LINKPORT_SUCCESS )
    	   return lpResult;
    
        lpResult = adi_linkport_ConfigTransferMode(linkPortTxHandle, ADI_LINKPORT_SDR_8BIT_TRANSFER_MODE);
        if ( lpResult != ADI_LINKPORT_SUCCESS )
    	   return lpResult;
    
    	pr_debug("Sending LDR of total size: %i\n\r", fwSize);
    	for ( int index = 0; index < fwSize ; index += 4 )
    	{
    		lpResult = adi_linkport_CoreTransfer(linkPortTxHandle, (void*) &source0[index], 1, ADI_OSAL_TIMEOUT_FOREVER);
    		if ( lpResult != ADI_LINKPORT_SUCCESS )
    			pr_debug("adi_linkport_CoreTransfer: %i\n\r", (int) lpResult);
    	}
    	pr_debug("Finished sending data\n\r");


    or writing directly to the configuration registers as follows:

    	// Disable LP for handshake
    	*pREG_LP1_STAT=BITM_LP_STAT_LTRQ | BITM_LP_STAT_LRRQ;
    	*pREG_LP1_CTL = 0;
    
    	// Configure as Tx
    	*pREG_LP1_CTL |= (ENUM_LP_CTL_TX | ENUM_LP_CTL_TRQ_EN | ENUM_LP_CTL_8BIT_SDR);
    	*pREG_LP1_DIV = 15;
    
    	// Enable LP
    	*pREG_LP1_CTL |= ENUM_LP_CTL_EN;
    
    	int LDR_size = sizeof(source0);
    	int *pSource = (int*) &source0[0];
    
    	pr_debug("Operation start \n\r");
    	for ( int index = 0; index < fwSize/4; index++)
    	{
    		int iTemp= 1;
    		while ( iTemp )
    		{
    			iTemp = ((*pREG_LP1_STAT & BITM_LP_STAT_FFST)>>BITP_LP_STAT_FFST);
    		}
    
    		*pREG_LP1_TX= *pSource;
    		pSource++;
    	}
    	pr_debug("Operation Complete \n\r");

    The initial bytes of the LDR file that is being to SoC 2 are similar to the ones in your shared in the example, which suggest me that there is no error in the elfloader settings:

    0x01,
    0x50,
    0x84,
    0xAC,
    0xE8,
    0x00,
    0x80,
    0x2F,
    0x00,
    0x00,
    0x00,
    0x00,
    0x44,
    0x79,
    0x03,
    0x00,
    0x01,
    0x00,
    0x1F,
    0xAC,
    0x00,
    0x00,
    0x02,
    0x20,
    0x90,
    0x00,

    The commands in SoC 2 project settings for loader generation are:
    -proc ADSP-SC835 -si-revision 0.0 -blphost -fInclude -core1="${ProjDirPath}/../SOCB_Core1.dxe" -core2="${ProjDirPath}/../SOCB_Core2"

    With both alternatives, after booting SoC 2 in LinkPort boot mode, and running the debug session on SoC 1, I can verify that SoC 2 turns it's ACK link to high, and SoC 1 starts sending the expected data through LinkPort_1 (to SoC 2 LinkPort_0), but after some bytes SoC 2 switches the ACK line to low state, preventing SoC 1 to send more bytes:

    I have also tried a different approach, creating a small application for SoC 2 and flashing it to SPI1 flash memory, which initializes softSwitches and calls adi_rom_Boot() in LinkPort boot mode:
    adi_rom_Boot(0, 0, 0, 0, 0x00000014, 0);
    But the results are the same in all cases

    Is there any obvious reason that I am not seeing for SoC 2 stoping the reception of bytes through LinkPort? is there any other recomendation you could give for LinkPort boot mode on ADSP-SC835?

    Thank you very much,
    Leopoldo

  • Hi Leopoldo,

    We are checking on this and will get back to you as soon as possible.

    Regards,
    Nandini.C

  • Hi  , I was able to make it work using the last aproach mentioned in my comment.

    I created a bootloader for SoC 2 and flashed it to its SPI1 flash memory, which initializes softSwitches and calls adi_rom_Boot() in LinkPort boot mode adi_rom_Boot(0, 0, 0, 0, 0x00000014, 0);

    With the proper setting of the softSwitches in SoC2, it was now able to correctly receive all the data through LinkPort and boot, otherwise not. The disadvantage of this is the need to have a flash memory on SoC 2 just for a bootloader that does this job, but I guess that working with a hardware design without softSwitches should avoid this issue right?

    Thanks,
    Leopoldo

  • Hi,

    Glad to know that the issue is resolved and thanks for the update.

    Yes, your understanding is correct. This issue can be avoided with a hardware design that does not use soft switches. On the evaluation board, the softconfig switches need to be configured properly.

    Regards,
    Nandini C

Reply Children
No Data

Before You Switch


Switching languages will make ADI Explorer unavailable. Resume your session by switching back to English and reopening ADI Explorer.