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.

TMS320F28335: SCI to RS485 Transmission at 921k baud with Flash Pipelining Issue

Part Number: TMS320F28335
Other Parts Discussed in Thread: SYSBIOS

I have an RS-485 transceiver connected to the SCI-B TX/RX pins and configured at a baud rate of 921600.

The Sysclkout is configured at 60Mhz (20Mhz OSC, with PLLCR[DIV] = 6, PLLSTS[DIVSEL] = 2).

The LSPCLK is configured to 15Mhz (LOSPCP[LSPCLK] = 2, SYSCLK / 4).

Flash pipelining has been configured with the following function and is called before main. I also made sure that this runs from RAM.

void init_flash(void)
{
   EALLOW;
       
   //Enable Flash Pipeline mode to improve performance
   //of code executed from Flash.
   FlashRegs.FOPT.bit.ENPIPE = 1;

   //                CAUTION
   //Minimum waitstates required for the flash operating
   //at a given CPU rate must be characterized by TI.
   //Refer to the datasheet for the latest information.

   // 150 MHz uses 5 (+1) SYSCLK cycles, 100 uses 3 (+1) SYSCLK cycles
   // This means that we need 1 SYSCLK of wait state per 25MHz

   //Set the Paged Waitstate for the Flash
   FlashRegs.FBANKWAIT.bit.PAGEWAIT = 2;

   //Set the Random Waitstate for the Flash
   FlashRegs.FBANKWAIT.bit.RANDWAIT = 2;

   // 150 MHz uses 8 (+1) SYSCLK cycles, 100 uses 5 (+1) SYSCLK cycles
   // This means that we need 1 SYSCLK of wait state per 16.667MHz

   //Set the Waitstate for the OTP
   FlashRegs.FOTPWAIT.bit.OTPWAIT = 4;
   //                CAUTION
   //ONLY THE DEFAULT VALUE FOR THESE 2 REGISTERS SHOULD BE USED
   FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF;
   FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF;
       
   EDIS;

   //Force a pipeline flush to ensure that the write to
   //the last register configured occurs before returning.

   asm(" RPT #7 || NOP");
}

With flash pipelining enabled, I get gaps in traffic as shown in the oscilloscope picture below:

Both of these gaps appear to be around 60us/16.67Mhz in width and occur twice. The width measured with the scope cursors seem to rhyme with how the Sysclk is configured at a 60Mhz/16.67 rate, but I'm unsure as to how these could play into the flash-pipelining or if this is a red herring.

When the flash pipelining is disabled, I dont experience these gaps between bytes and the traffic is fine.

The buffer which holds each byte to be transmitted is allocated to an external RAM chip connected via the XINTF pins.

Any ideas as to how this flash pipelining could be causing this issue?

  • Further clarification: The target baudrate is 921600, but is really a 937500 since the SCI-B Baud registers care configured with a BRR value of 1.

  • Hi Jack,

    I've reached out to the flash experts on this, the period between 60us period is significantly longer than the idle period of 10 bits of idle-line multiprocessor mode in SCI, so this is something in the flash delaying transfers.

    My apologies for the delay.

    Regards,

    Vince

  • Hey Vince, 

    Thanks for responding back. Do you have any tips or advice for investigating how the flash delay transfers can be debugged for narrowing down which flash data could be causing this?

  • Hello Jack,

    Any ideas as to how this flash pipelining could be causing this issue?

    I'm not sure what your code looks like, but if you have loops or branches then this will cause the Flash pipeline to flush, which incurs extra cycles. This is likely what you are seeing, although I can't guarantee it.

    Is there a particular reason your code needs to run from Flash? Can you program it to Flash and then run it on RAM using memcpy?

    Best regards,

    Omer Amir

  • If the ISR code is already running from RAM, could branching or loops still cause flash pipeline to flush? I use the looping in the tx isr to keep the sci fifo full and have the TXFFIL sci register set so that the interrupt triggers whenever the fifo has a space for another byte.

    I made sure that the globals it uses are stored in external RAM. I initialize the HWI with 

    Hwi_create(...); in c-code prior.
    Would there be any benefit to moving the Hwi initialization to the app.cfg file? Also, if I use the arg parameter within the Hwi_Params, does that cause anything with flash memory with Sysbios? 
  • If the ISR code is already running from RAM, could branching or loops still cause flash pipeline to flush?

    This may happen with the CPU, I'm not sure. If the issue seems to be focused on executing program instructions from RAM, then I will forward this question to the appropriate expert.

    Would there be any benefit to moving the Hwi initialization to the app.cfg file? Also, if I use the arg parameter within the Hwi_Params, does that cause anything with flash memory with Sysbios? 

    This is more of a SYS BIOS question, but before I forward this to that expert do you mind telling me if any of your code is running from Flash, or is it all loaded to RAM at the beginning of your program and just kept in Flash for the sake of a POR?

  • Some of the code in the code base does run from flash, typically low priority code, but we have the HWI ISRs loaded into RAM at the beginning of the program, such as the SCI TX ISR. The appcode that ultimately starts a SCI port transmission runs from flash, but once the SCI transmission is requested, the sci driver sets the SCI TX ISR to handle the shifting from the FW buffers stored in external RAM to and from the SCI registers as they are sent and received.

  • You may need to verify that the during the entire duration of the transaction, the program is running from RAM. If at any point it jumps to executing/reading something from Flash then there may be delays if the SCI peripheral is for some reason waiting on code (but I believe the transfer should be independent of code execution).