3 Replies Latest reply on Mar 4, 2020 11:51 AM by KyTr_1955226

    PSoC5LP I2C Bootloader: PSoC is stretching clock on "Write Flash" command?

    KyTr_1955226

      I'm running into a weird issue with using the PSoC5LP I2C Bootloader Interface.

       

      I am using a CY8C5467LTI-LP003.  Building my project in PSoC Creator Version 4.2.

       

      I am performing the bootload operation with a custom C# .NET application using bootl_utils.dll (built from the source from Creator 4.1 if I'm remembering right), that interfaces with the CY7C65211A (I2C Vendor Driver) via cyusbserial.dll.

       

      I should note that I have modified the bootloader utilities library that I'm using here, as I detailed here in this old thread where I was also having problems bootloading over I2C.

       

      I can see nothing wrong with the operation of the host, it looks to be sending the correct packets in the correct format, but the data coming back from the PSoC appears to be the issue.  Particularly with the response to the "Program Row" command.  See the logic capture below:

      ProgramRow.JPG

       

      Note the response from the PSoC5, it looks like it's stretching the clock for some reason when its address is called out after receiving the 0x39 (Program Row) command packet.  It actually looks like it forms a correct response, but the first byte of the packet is wrong (0xFF).  It's a little tough to see, but the bytes in the response on the stretched read are as follows:

      FF-01-00-00-00-FF-FF

       

      This is interesting, because judging from previous responses, the packet SHOULD be:

      01-00-00-00-FF-FF-17

       

      It looks like it's sending the correct number of bytes, and that it assembles the packet, but for some reason is sneaking an 0xFF into the first byte rather than the 0x01 Start of Packet byte, and pushing out the 0x17 End of Packet byte.  I image

       

      I am logging all I2C in and out in the log window of my bootloader application, here's the complete Command/Response history leading up to the failure:

       

      W: 01-38-00-00-C7-FF-17

      R: 01-00-08-00-69-30-10-2E-00-3C-01-01-E2-FE-17

      W: 01-33-01-00-00-CB-FF-17

      R: 01-05-00-00-FA-FF-17-FF-FF

      W: 01-32-01-00-00-CC-FF-17

      R: 01-00-04-00-15-00-FF-00-E7-FE-17

      W: 01-37-39-00-00-40-00-20-11-15-00-00-51-1E-00-00-51-1E-00-00-08-B5-00-F0-BD-FC-00-00-10-B5-05-4C-23-78-33-B9-04-4B-13-B1-04-48-AF-F3-00-80-01-23-23-70-10-BD-48-C1-FF-1F-00-00-00-00-88-74-F0-17

      R: 01-00-00-00-FF-FF-17

      W: 01-37-39-00-46-00-00-08-4B-10-B5-1B-B1-08-49-08-48-AF-F3-00-80-08-48-03-68-03-B9-10-BD-07-4B-00-2B-FB-D0-BD-E8-10-40-18-47-00-BF-00-00-00-00-4C-C1-FF-1F-88-46-00-00-C8-C0-FF-1F-00-00-64-ED-17

      R: 01-00-00-00-FF-FF-17

      W: 01-37-39-00-00-00-80-B5-9A-B0-62-B6-02-F0-AB-F9-02-F0-BF-F9-02-F0-F9-F8-02-F0-45-F9-02-21-00-20-01-F0-27-F9-00-F0-D9-FC-85-4C-00-F0-01-02-D3-B2-22-70-00-F0-1E-02-04-2A-0D-D0-02-D8-02-BA-E5-17

      R: 01-00-00-00-FF-FF-17

      W: 01-37-39-00-2A-05-D0-27-E0-08-2A-0E-D0-10-2A-13-D0-22-E0-00-22-62-70-FB-B1-7B-4A-13-E0-01-22-62-70-0B-B9-7A-4A-0E-E0-7A-4A-0C-E0-02-22-62-70-0B-B9-78-4A-07-E0-78-4A-05-E0-03-22-62-70-E6-EA-17

      R: 01-00-00-00-FF-FF-17

      W: 01-37-39-00-0B-B9-77-4A-00-E0-77-4A-13-78-03-F0-F1-03-43-F0-08-03-13-70-13-78-43-F0-01-03-13-70-01-45-00-40-01-4F-00-40-07-52-00-40-09-64-00-40-02-65-00-40-15-00-01-40-37-01-01-40-58-C7-F1-17

      R: 01-00-00-00-FF-FF-17

      W: 01-39-06-00-00-15-00-02-01-40-68-FF-17

      R: FF-01-00-00-00-FF-FF

      W: 01-3B-00-00-C4-FF-17

       

      It also looks like the response to the Get Application Status (0x33) command is a little funky, with 2 extra 0xFF bytes tacked on the end, but this doesn't seem to be causing any problem in the process.

       

      The problem appears to be on the PSoC side, but I was also able to successfully load using the Bootloader Host included with creator using the MiniProg3 as my USB-I2C bridge, so there's evidence pointing to both ends being the culprit?

       

      Might anyone have an idea as to what's going on? 

       

      Thanks in advance for any tips!

        • 1. Re: PSoC5LP I2C Bootloader: PSoC is stretching clock on "Write Flash" command?
          KyTr_1955226

          FWIW:
          Updating the bootloader utils to build from the source included in Creator 4.2 brings me back to the problem I had a year and a half ago, failing on Get Application Status (0x33):

           

          W: 01-38-00-00-C7-FF-17

          R: 01-00-08-00-69-30-10-2E-00-3C-01-01-E2-FE-17

          W: 01-33-01-00-00-CB-FF-17

          R: 01-05-00-00-FA-FF-17-FF-FF

          W: 01-3B-00-00-C4-FF-17

           

          Looks like the fix I made in the 4.1 bootloader utils needs to be re-applied to the 4.2 version:

          in cybtldr_api2.c:

          err = CyBtldr_ParseHeader(lineLen, line, &siliconId, &siliconRev, &chksumtype);
          
              if (CYRET_SUCCESS == err)
              {
                  CyBtldr_SetCheckSumType(chksumtype);
          
                  err = CyBtldr_StartBootloadOperation(comm, siliconId, siliconRev, &blVer, securityKey);
                  bootloaderEntered = 1;
          
                  appId -= 1; /* 1 and 2 are legal inputs to function. 0 and 1 are valid for bootloader component */
                  if (appId > 1)
                  {
                      appId = INVALID_APP;
                  }
          
                  if ((CYRET_SUCCESS == err) && (appId != INVALID_APP))
                  {
                      /* This will return error if bootloader is for single app */
                      err = CyBtldr_GetApplicationStatus(appId, &isValid, &isActive);
          
                      /* Active app can be verified, but not programmed or erased */
                      if (CYRET_SUCCESS == err && VERIFY != action && isActive)
                      {
                          /* This is multi app */
                          err = CYRET_ERR_ACTIVE;
                      }
                      else if (CYBTLDR_STAT_ERR_CMD == (err ^ (int)CYRET_ERR_BTLDR_MASK))    //Added These lines otherwise we fail on single app
                      {                                                                      //||
                          /* Single app - restore previous CYRET_SUCCESS */                  //||
                          err = CYRET_SUCCESS;                                               //||
                      }                                                                      //||
                  }
              }
          
          • 2. Re: PSoC5LP I2C Bootloader: PSoC is stretching clock on "Write Flash" command?
            KyTr_1955226

            Update:

             

            I tried programming via the Bootloader Host tool with the MiniProg3 as my USB-I2C bridge.  I saw some interesting things:

             

            1) The bootload process completes with no errors.

             

            2) The stretched clock still occurs, as does the leading 0xFF from the PSoC, but this does not seem to disrupt the process when using Bootloader Host:

            read.JPG

            This seems to be because:

            3) The EoP byte 0x17 DOES eventually show up, but not until a separate read about 2mS later:

            eop.JPG

             

            It looks like this clock stretching behavior occurs just as it's pictured above for each and every "Program Row" command, with the 0x17 EoP coming well after the rest of the packet:

            longcapture.JPG

             

            Is this expected?  And why can't the bootloader utils library cope with this on my end?

            • 3. Re: PSoC5LP I2C Bootloader: PSoC is stretching clock on "Write Flash" command?
              KyTr_1955226

              So I've been able to come up with a workaround for this that I don't love, but seems to work at least.

               

              My ReadData callback for the I2C Bootloader host looked like this:

              public unsafe int ReadData(IntPtr buffer, int size)
              {
                  string strdata;
                  int status = 0;
                  CY_RETURN_STATUS cy_stat;
                  byte[] data = new byte[MaxTransferSize];
              
                  fixed (byte* b = data)
                  {
                      cyReadDataBuffer.buffer = b;
                      cyReadDataBuffer.length = (uint)size;
                      cyI2CDataConfig.isNakBit = 1;
                      cyI2CDataConfig.isStopBit = 1;
              
                      fixed (CY_I2C_DATA_CONFIG* data_cfg = &cyI2CDataConfig)
                      {
                          fixed (CY_DATA_BUFFER* dta_buff = &cyReadDataBuffer)
                          {
                              cy_stat = CyI2cRead(cyDeviceHandle, data_cfg, dta_buff, 5000);
                          }
                      }
                  }
              
                  Marshal.Copy(data, 0, buffer, size);
              
                  /*Print our bytes to the text log*/
                  strdata = BitConverter.ToString(data).TrimEnd('-', '0');
                  WriteLog(Color.Blue, 0, "R: " + strdata + "\r\n");
              
                  if (cy_stat == CY_RETURN_STATUS.CY_SUCCESS)
                  {
                      status = ERR_SUCCESS;
                  }
                  else
                  {
                      status = ERR_READ;
                      CyI2cReset(cyDeviceHandle, 0);
                  }
              
                  return status;
              }
              

               

              What I set out to do was recreate what the official Bootloader Host was doing (or at least, looked like it was doing), as it seems to account for this 0xFF byte at the beginning of a transmission from the PSoC being loaded.  I can presumably do this by looking for the 0xFF in the first index of the read buffer, and adjusting behavior accordingly.  I replaced the Marshal.Copy() at line 24 with this:

               

              /*On Program Row commands, the PSoC will stretch the clock and insert a 0xFF in the first index before transmitting the 0x01 SoP byte*/
              /*This causes the bootloader to not read the 0x17 EoP byte at the end of the packet*/
              /*If we have 0xFF in the first index, we need to strip it out, then read an extra byte and place it at the end of the incoming data*/
              if (data[0] == 0xFF)
              {
                  Marshal.Copy(data, 1, buffer, size);
              
                  fixed (byte* b = data)
                  {
                      cyReadDataBuffer.buffer = b;
                      cyReadDataBuffer.length = (uint)1;
                      cyI2CDataConfig.isNakBit = 1;
                      cyI2CDataConfig.isStopBit = 1;
              
                      fixed (CY_I2C_DATA_CONFIG* data_cfg = &cyI2CDataConfig)
                      {
                          fixed (CY_DATA_BUFFER* dta_buff = &cyReadDataBuffer)
                          {
                              cy_stat = CyI2cRead(cyDeviceHandle, data_cfg, dta_buff, 5000);
                          }
                      }
                  }
              
                  Marshal.WriteByte(buffer, size-1, data[0]);
                  Marshal.Copy(buffer, data, 0, size);
              } 
              else
              {
                  Marshal.Copy(data, 0, buffer, size);
              }
              

               

              This does seem to work, but I don't feel super great about it (it feels like adjusting for something that shouldn't be happening in the first place).

               

              I'd feel much more comfortable if anyone could fill me in on why the PSoC behaves in this way and if compensating for it on the host is strictly necessary? Should I maybe be on the lookout for possibly more 0xFF bytes preceding the actual bootloader response packet?

               

              If anyone has any info on this they could share I'd love to hear it.  I almost feel like this should be documented somewhere...