This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC3200: OTA with DropBox has suddenly stopped working

Part Number: CC3200

Hi,

I had OTA for CC3200 devices working using DropBox api without any mayor issues. Today, when I tried to update a device, the process failed with error code -7 (RUN_STAT_ERROR_DOWNLOAD_SAVE).

Does anyone know if any changes were made to the DropBox api that would generate this error? Below this text are the definitions that the code developed using the CC3200 OTA documentation uses.

#define OTA_SERVER_NAME "api.dropbox.com"

#define OTA_SERVER_IP_ADDRESS 0x00000000

#define OTA_SERVER_SECURED 1

#define OTA_SERVER_REST_UPDATE_CHK "/1/metadata/auto/" // returns files/folder list

#define OTA_SERVER_REST_RSRC_METADATA "/1/media/auto" // returns A url that serves the media directly

#define OTA_SERVER_REST_HDR "Authorization: Bearer "

#define OTA_SERVER_REST_HDR_VAL XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

#define LOG_SERVER_NAME "api-content.dropbox.com"

#define OTA_SERVER_REST_FILES_PUT "/1/files_put/auto/"

#define OTA_VENDOR_STRING "Vid01_Pid32_Ver30"

Regards,

Marco.

  • Hi Marco,

    There was an update to the dropbox API that made it use much longer URIs than before, which the ota library is not designed to handle.
    Please take a look at Kobi's post here for the fixes you need:
    e2e.ti.com/.../2778411
    Then, rebuild the ota library and ensure that in your linker you point to the newly-rebuilt library.

    Let me know if that doesn't fix your issue or if you have further questions.

    Regards,
    Michael
  • Hi,

    The files were modified but the issue is still there. On the ota_api.h file, the line at 85 was actually at 92 but I think it's irrelevant. Do I need to update the Dropbox token, perhaps? Or download a fresh version of the 1.3.0 SDK and apply the changes to it?

    A previous patch was applied some time ago, perhaps there are some conflicts with the new one. https://e2e.ti.com/support/wireless-connectivity/wifi/f/968/t/580349

    Regards,

    Marco.

  • Hi Marco,

    I would try applying the fixes mentioned by Kobi in the thread I linked onto a fresh SDK first and seeing if that fixes things.

    Regards,
    Michael
  • Hi Michael,

    I have followed the steps on a fresh SDK and instead of throwing an error, the OTA process gets stuck at this loop. 

    	while (RUN_STAT_CONTINUE == lRetVal)    {
    		lRetVal = sl_extLib_OtaRun(pvOtaApp);
    	}

    When debugging, the function

    sl_extLib_OtaRun

    Returns 0 about 4 times and then the program is unable to reach the next line.

    Regards, 

    Marco.

  • Hi Marco,

    What is the state of pOtaApp when you reach this loop? Is there anything printed out on the UART terminal? The OTA library should use Report() to print out some useful debug info that could help isolate the issue.

    Regards,
    Michael
  • Hi Michael,

    The pOtaApp state is OTA_STATE_DOWNLOADING:

            case OTA_STATE_DOWNLOADING:
                /*Report("sl_extLib_OtaRun: call CDN to continue download the file %s\n", pOtaApp->pResourceMetadata->p_file_name); */
    
                /* set mcu number and reset flag (even in error) */
                if (pOtaApp->pResourceMetadata->flags & METADATA_FLAGS_RESET_NWP)
                {
                    pOtaApp->resetNwp = 1;
                }
                /* set reset flag if one of the files is with the reset flag */
                if (pOtaApp->pResourceMetadata->flags & METADATA_FLAGS_RESET_MCU)
                {
                    pOtaApp->resetMcu = 1;
                }
    
                status = CdnClient_Run(pOtaApp->pvCdnClient);
                if( status < 0)
                {
                    pOtaApp->state = OTA_STATE_RESOURCE_LIST;
    
                    if (status == CDN_STATUS_ERROR_SAVE_CHUNK)
                        pStatistics->download_error_save_chunk++;
                    else if (status == CDN_STATUS_ERROR_MAX_EAGAIN)
                        pStatistics->download_error_max_eagain++;
                    else if (status == CDN_STATUS_ERROR_CONNECT_CDN)
                        pStatistics->download_error_connect_cdn++;
                    else if (status == CDN_STATUS_ERROR_READ_HDRS)
                        pStatistics->download_error_read_hdrs++;
                    else
                        pStatistics->download_error++;
    
                    Report("sl_extLib_OtaRun ERROR: Failed on CdnClient_Run\r\n");
                    return RUN_STAT_ERROR_DOWNLOAD_SAVE;
                }
                else if (status == CDN_STATUS_DOWNLOAD_DONE)
                {
                    pStatistics->download_done++;
                    Report("sl_extLib_OtaRun: ---- Download file completed %s\r\n", pOtaApp->pResourceMetadata->p_file_name);
                    if(NULL != strstr((const char *)pOtaApp->file_path,"mcuimgA.bin"))
                    {
                      pOtaApp->isMCUAppUpdate = 1;
                    }
                    pOtaApp->state = OTA_STATE_RESOURCE_LIST; /* handle next resource */
                }
    
                /* continue with same state */
                break;

    The function sl_extLib_OtaRun reaches the OTA_STATE_DOWNLOADING case but it can not continue after this statement

    status = CdnClient_Run(pOtaApp->pvCdnClient);


    Within this function, the pCdnClient->state is CDN_STATE_FILE_DOWNLOAD_AND_SAVE, but after stepping into the switch, the debugger starts acting strange, as if I had order it to run.


    If I pause the execution, the program seems to be in a SPIDataGet() function. The source file can't be found, but the Disassembly window shows this:



    If I "assembly step", the program stays in an endless loop in the four green statements after $C$L39

    This is how far I could get while debugging. May the problem be solved if I change from dropbox to another hosting platform?

    Regards,
    Marco.

  • I have also tried to curl, and it works without issues:

    curl -X POST api.dropboxapi.com/.../list_folder     --header "Authorization: Bearer mytoken"     --header "Content-Type: application/json"     --data "{\"path\": \"\",\"recursive\": false,\"include_media_info\": false,\"include_deleted\": false,\"include_has_explicit_shared_members\": false,\"include_mounted_folders\": true}"
    {"entries": 
    ...
    "has_more": false}

  • Update.

    While debugging, I can get to the function _SlDrvMemZero at driver.c. If I step over sl_Memset(Addr, 0, size); the program enters the loop I mentioned before.

    void _SlDrvMemZero(void* Addr, _u16 size)
    {
        sl_Memset(Addr, 0, size);
    }

    The call stack is:
    _SlDrvResetCmdExt at driver.c
    sl_Recv at socket.c
    sl_Recv_eagain at OtaHttp.c
    _RecvFileChunk
    CdnClient_Run

    Should I post the parameters that each of these functions receive?

  • Update. This is the code of the loop where the function gets stuck

    //*****************************************************************************
    //
    //! Waits for the word to be received on the specified port.
    //!
    //! \param ulBase is the base address of the SPI module.
    //! \param pulData is pointer to receive data variable.
    //!
    //! This function gets a SPI word from the receive FIFO for the specified
    //! port.  If there is no word available, this function waits until a
    //! word is received before returning.
    //!
    //! \return Returns the word read from the specified port, cast as an
    //! \e unsigned long.
    //
    //*****************************************************************************
    void
    SPIDataGet(unsigned long ulBase, unsigned long *pulData)
    {
      //
      // Wait for Rx data
      //
      while(!(HWREG(ulBase + MCSPI_O_CH0STAT) & MCSPI_CH0STAT_RXS))
      {
      }
    
      //
      // Read the value
      //
      *pulData = HWREG(ulBase + MCSPI_O_RX0);
    }

  • I don't know where the issue comes from, but it worked after a work around posted in a different question.

    "Changing the minDmaTransferSize from 100 to something so high that the driver should never use DMA (4096 bytes)."

    uint32_t spiCC3200DMAscratchBuf[CC3200_LAUNCHXL_SPICOUNT];
    
    const SPICC3200DMA_HWAttrs spiCC3200DMAHWAttrs[CC3200_LAUNCHXL_SPICOUNT] = {
        {
            .baseAddr = GSPI_BASE,
            .intNum = INT_GSPI,
            .intPriority = (~0),
            .spiPRCM = PRCM_GSPI,
            .csControl = SPI_HW_CTRL_CS,
            .csPolarity = SPI_CS_ACTIVELOW,
            .pinMode = SPI_4PIN_MODE,
            .turboMode = SPI_TURBO_OFF,
            .scratchBufPtr = &spiCC3200DMAscratchBuf[0],
            .defaultTxBufValue = 0,
            .rxChannelIndex = UDMA_CH6_GSPI_RX,
            .txChannelIndex = UDMA_CH7_GSPI_TX,
            .minDmaTransferSize = 100
        },
        {
            .baseAddr = LSPI_BASE,
            .intNum = INT_LSPI,
            .intPriority = (~0),
            .spiPRCM = PRCM_LSPI,
            .csControl = SPI_SW_CTRL_CS,
            .csPolarity = SPI_CS_ACTIVEHIGH,
            .pinMode = SPI_4PIN_MODE,
            .turboMode = SPI_TURBO_OFF,
            .scratchBufPtr = &spiCC3200DMAscratchBuf[1],
            .defaultTxBufValue = 0,
            .rxChannelIndex = UDMA_CH12_LSPI_RX,
            .txChannelIndex = UDMA_CH13_LSPI_TX,
            .minDmaTransferSize = 4096
        }
    };