Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 22 of 22

Thread: FlexIO "Extra" clock cycle on 8080 parallel setup

  1. #1
    Senior Member
    Join Date
    Oct 2019
    Posts
    239

    FlexIO "Extra" clock cycle on 8080 parallel setup

    So the title may not fully reflect the content of this post, but I tried to keep it short

    So I'm in the process of building out an 8 bit parallel display driver for the Teensy Micromod using FlexIO2. Data is transmitted on FlexIO2 pins 4:11 and the WR on pin 0.
    I almost have a proof of concept working, but for some reason I am getting an empty pulse on the WR pin just before it shifts out the data from Shifter0

    The configuration for the shifter and timer has been taken from a few NXP demo code files that have implemented the same protocol to drive a display - one for the imxrt1050 and another for the KL28. The FlexIO peripheral works the same across these series from what I read.

    Below is an example sketch of the FlexIO2 setup, the shifter config, the timer config and a function to transmit the data 1 byte at a time.

    Code:
    #include <Arduino.h>
    #include "FlexIO_t4.h"
    //#include "DMAChannel.h"
     
    FlexIOHandler *pFlex;
    IMXRT_FLEXIO_t *p;
    const FlexIOHandler::FLEXIO_Hardware_t *hw;
    //DMAChannel myDMA;
    //volatile uint32_t DMAMEM dataBuffer[2] __attribute__((aligned(32)));
    uint8_t bufferData[4] = {0x17, 0x07, 0x19, 0x90};
     
    void FlexIO_Init(){
        /* Get a FlexIO channel */
        pFlex = FlexIOHandler::flexIOHandler_list[1]; // use FlexIO2
     
        /* Pointer to the port structure in the FlexIO channel */
        p = &pFlex->port();
        
        /* Pointer to the hardware structure in the FlexIO channel */
        hw = &pFlex->hardware();
     
        /* Basic pin setup */
        pinMode(10, OUTPUT); // FlexIO2:0
        pinMode(40, OUTPUT); // FlexIO2:4
        pinMode(41, OUTPUT); // FlexIO2:5
        pinMode(42, OUTPUT); // FlexIO2:6
        pinMode(43, OUTPUT); // FlexIO2:7
        pinMode(44, OUTPUT); // FlexIO2:8
        pinMode(45, OUTPUT); // FlexIO2:9
        pinMode(6, OUTPUT); // FlexIO2:10
        pinMode(9, OUTPUT); // FlexIO2:11
        
        /* High speed and drive strength configuration */
        *(portControlRegister(10)) = 0xFF; 
        *(portControlRegister(40)) = 0xFF;
        *(portControlRegister(41)) = 0xFF;
        *(portControlRegister(42)) = 0xFF;
        *(portControlRegister(43)) = 0xFF;
        *(portControlRegister(44)) = 0xFF;
        *(portControlRegister(45)) = 0xFF;
        *(portControlRegister(6)) = 0xFF;
        *(portControlRegister(9)) = 0xFF;
     
        /* Set clock */
        pFlex->setClockSettings(3, 0, 0); // 480 MHz
     
        /* Set up pin mux */
        pFlex->setIOPinToFlexMode(10);
        pFlex->setIOPinToFlexMode(40);
        pFlex->setIOPinToFlexMode(41);
        pFlex->setIOPinToFlexMode(42);
        pFlex->setIOPinToFlexMode(43);
        pFlex->setIOPinToFlexMode(44);
        pFlex->setIOPinToFlexMode(45);
        pFlex->setIOPinToFlexMode(6);
        pFlex->setIOPinToFlexMode(9);
     
        /* claim Shifter 0 */
        pFlex->claimShifter(0);
     
        /* claim Timer 0 */
        pFlex->claimTimer(0);
     
        /* Enable the clock */
        hw->clock_gate_register |= hw->clock_gate_mask;
     
        /* Enable the FlexIO with fast access */
        p->CTRL = FLEXIO_CTRL_FLEXEN | FLEXIO_CTRL_FASTACC;
    }
     
    void singleBeatWrite(uint8_t const * buffer, uint32_t const length){
        p->CTRL &= ~FLEXIO_CTRL_FLEXEN;
        //p->CTRL |= FLEXIO_CTRL_SWRST; //Software reset FlexIO registers enable
        //p->CTRL &= ~FLEXIO_CTRL_SWRST; //Software reset FlexIO registers disable
        /* Configure the shifters */
        p->SHIFTCFG[0] = 
            FLEXIO_SHIFTCFG_INSRC                                                   /* Shifter input */
          | FLEXIO_SHIFTCFG_SSTOP(0U)                                               /* Shifter stop bit disabled */
          | FLEXIO_SHIFTCFG_SSTART(0U)                                              /* Shifter start bit disabled and loading data on enabled */
          | FLEXIO_SHIFTCFG_PWIDTH(8U-1U);                                          /* Bus width */
          
        p->SHIFTCTL[0] = 
            FLEXIO_SHIFTCTL_TIMSEL(0U)                                              /* Shifter's assigned timer index */
          | (0<<23) //FLEXIO_SHIFTCTL_TIMPOL(0U)                        /* Shift on posedge of shift clock */
          | FLEXIO_SHIFTCTL_PINCFG(3U)                                              /* Shifter's pin configured as output */
          | FLEXIO_SHIFTCTL_PINSEL(4U)                                              /* Shifter's pin start index */
          | (0<<7) //((uint32_t)(1<<7))                                 /* Shifter's pin active high */
          | FLEXIO_SHIFTCTL_SMOD(2U);                                               /* Shifter mode as transmit */
     
        /* Configure the timer for shift clock */
        p->TIMCMP[0] = 
            ((1U * 2U - 1) << 8)                                                    /* TIMCMP[15:8] = number of beats x 2  1 */
          | (40U/2U - 1U); //(4U/2U - 1U)                                            /* TIMCMP[7:0] = baud rate divider / 2  1 */
        
        p->TIMCFG[0] = 
            FLEXIO_TIMCFG_TIMOUT(0U)                                                /* Timer output logic one when enabled and not affected by reset */
          | FLEXIO_TIMCFG_TIMDEC(0U)                                                /* Timer decrement on FlexIO clock, shift clock equals timer output */
          | FLEXIO_TIMCFG_TIMRST(0U)                                                /* Timer never reset */
          | FLEXIO_TIMCFG_TIMDIS(2U)                                                /* Timer disabled on timer compare */
          | FLEXIO_TIMCFG_TIMENA(2U)                                                /* Timer enabled on trigger high */
          | FLEXIO_TIMCFG_TSTOP(0U)                                                 /* Timer stop bit disabled */
          | (0<<1); //((uint32_t)(0<<1)) //FLEXIO_TIMCFG_TSTART(0U);    /* Timer start bit disabled */
        
        
        p->TIMCTL[0] = 
            FLEXIO_TIMCTL_TRGSEL((((0U) << 2) | 1U))                                /* Timer trigger selected as shifter's status flag */
          | (1<<23) //FLEXIO_TIMCTL_TRGPOL(1U)                          /* Timer trigger polarity as active low */
          | (1<<22)//FLEXIO_TIMCTL_TRGSRC(1U)                           /* Timer trigger source as internal */
          | FLEXIO_TIMCTL_PINCFG(3U)                                                /* Timer' pin configured as output */
          | FLEXIO_TIMCTL_PINSEL(0)                                                /* Timer' pin index: WR pin */
          | (1<<7) //FLEXIO_TIMCTL_PINPOL(1U)                           /* Timer' pin active low */
          | FLEXIO_TIMCTL_TIMOD(1U);                                                /* Timer mode as dual 8-bit counters baud/bit */
     
        /* Enable FlexIO */
        p->CTRL |= FLEXIO_CTRL_FLEXEN;
       
        if(length)
        {
            /* Use polling method for data transfer */
            for(uint32_t i=0; i<length-1U; i++)
            {     
                while(0 == (p->SHIFTSTAT & (1U << 0U)))
                {
                }
                p->SHIFTBUF[0U] = *buffer++;
            }
     
            /* Write the last byte */
            while(0 == (p->SHIFTSTAT & (1U << 0U)))
            {
            }
            p->TIMSTAT |= (1U << 0U);
            p->SHIFTBUF[0U] = *buffer++;
     
            /*Wait for transfer to be completed */
            while(0 == (p->TIMSTAT & (1U << 0U)));
            {
            }
        }
    } 
     
    void setup() {
      Serial.begin(115200);
      delay(1000);
      Serial.print(CrashReport);
      Serial.println("Start setup");
      delay(1000);
      FlexIO_Init();
      delay(10);
    }
     
    void loop() {
      singleBeatWrite(bufferData,4);
      Serial.println("sent data");
      delay(500);
    }
    Click image for larger version. 

Name:	download (2).jpg 
Views:	55 
Size:	81.4 KB 
ID:	25378

    As can be seen in the image above, the WR pin is sending out one pulse as soon as the shifter buffer is loaded, which it shouldn't. It should only send a pulse when the data moves from the shifter buffer to the shifter.

    Looking for suggestions on how to correct this issue - any input is appriciated!

    David

  2. #2
    If I'm understanding correctly, you should be getting 4 clock pulses but it looks like you are getting 6 instead? Is there an extra pulse at the end as well as the beginning?

    I wonder if this is because you are only shifting 8 bits out of the 32-bit wide shifter before reloading instead of shifting all 32 bits. Maybe FlexIO thinks the shifter is still partly full of data from the last time?
    Last edited by easone; 07-27-2021 at 10:16 PM.

  3. #3
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Posts
    823
    This is the relevant part from the datasheet that I believe is causing the first pulse:
    Code:
    50.5.1.6 Shifter Status (SHIFTSTAT)
    Shifter Status Flag
    For SMOD=Transmit, the status flag is set when SHIFTBUF data has been transferred to the Shifter (SHIFTBUF is empty) or when initially configured for SMOD=Transmit, and the status flag is cleared when the SHIFTBUF register is written.
    Your timer is being set to use that as it's trigger, so it then does what you would expect when you enable FlexIO with p->CTRL |= FLEXIO_CTRL_FLEXEN and it triggers a transmit because as far as it's concerned it believes it's right. Solution? Either don't set the FlexIO registers every time you setup a write sequence(by only setting it once in your FlexIO_Init() function) or clearing the Shifter Status Flag before enabling FlexIO.

  4. #4
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    Quote Originally Posted by easone View Post
    If I'm understanding correctly, you should be getting 4 clock pulses but it looks like you are getting 6 instead? Is there an extra pulse at the end as well as the beginning?

    I wonder if this is because you are only shifting 8 bits out of the 32-bit wide shifter before reloading instead of shifting all 32 bits. Maybe FlexIO thinks the shifter is still partly full of data from the last time?
    It looks like 6, but it is actually 5 pulses, the 1st one being the one I don't need.
    Per the data sheet, FLEXIO_SHIFTCFG_PWIDTH(n) will detemine how many bits are being pushed/read at a time, and TIMCMP[0][0:7] is how many beats it will pulse.
    So if I was to load 32 bits of data into the shifter, and set the number of beats to 4, it would push out 8 at a time until the buffer is empty, then it sets the flag and resets.

    Quote Originally Posted by vjmuzik View Post
    This is the relevant part from the datasheet that I believe is causing the first pulse:
    Code:
    50.5.1.6 Shifter Status (SHIFTSTAT)
    Shifter Status Flag
    For SMOD=Transmit, the status flag is set when SHIFTBUF data has been transferred to the Shifter (SHIFTBUF is empty) or when initially configured for SMOD=Transmit, and the status flag is cleared when the SHIFTBUF register is written.
    Your timer is being set to use that as it's trigger, so it then does what you would expect when you enable FlexIO with p->CTRL |= FLEXIO_CTRL_FLEXEN and it triggers a transmit because as far as it's concerned it believes it's right. Solution? Either don't set the FlexIO registers every time you setup a write sequence(by only setting it once in your FlexIO_Init() function) or clearing the Shifter Status Flag before enabling FlexIO.
    I will need to reconfigure the registers in runtime as the code will be alternating between single-beat blocking transmits, multi-beat blocking transmits, and multi-beat non blocking transmits (dma)
    So per your suggestion, I should clear the shifter status flag before enabling FlexIO & starting the transmit?
    Code:
     /* Clear the shifter status flag */
    p->SHIFTSTAT |= 0;
    
    /* Enable FlexIO */
    p->CTRL |= FLEXIO_CTRL_FLEXEN;

  5. #5
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Posts
    823
    The register is specified as write 1 to clear so it should be like this:
    Code:
     /* Clear the shifter status flag */
    p->SHIFTSTAT |= 1;
    If I’m understanding correctly then that should be do it.

  6. #6
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    Quote Originally Posted by vjmuzik View Post
    The register is specified as write 1 to clear so it should be like this:
    Code:
     /* Clear the shifter status flag */
    p->SHIFTSTAT |= 1;
    If I’m understanding correctly then that should be do it.
    You are correct, my transmit function will go into a while loop when SHIFTSTAT == 0 as it wait's for the transmit to complete. So setting it to 1 would clear it.
    Will give it a try later on today and report back

  7. #7
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    Tested it out - still no luck.

    I even moved the entire register config into the setup loop and it does the same thing.

    I have copied the exact configuration for the shifter and timer from the NXP example code - perhaps there is something faulty with my config as some of the defines they use are different than the ones in imxrt.h?
    For example, their config, and my interpretation based on imxrt.h:
    Code:
    FLEXIO_TIMCFG_TSTART(0U) -> (0<<1);
    FLEXIO_TIMCTL_PINPOL(1U) -> (1<<7)
    FLEXIO_TIMCTL_TRGSRC(1U) -> (1<<22)

  8. #8
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    @PaulStoffregen @KurtE have either of you seen this behavior with the FlexIO timers/timer's assigned output pin?
    I've been mucking around with this setup for a week now - getting nowhere with fixing this issue

    Seems to be experienced by users on the NXP community, but the NXP staff just dismiss them each time and refer them to application notes/demo code.

  9. #9
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Posts
    823
    I just now decided to test this for myself and curiously enough I'm not experiencing this with the code from post 1, at least not on the Teensy 4.0 that I have on hand. The only thing I changed was the pin numbers to match the different Teensy and the baud rate since my logic analyzer wasn't fast enough for the original(it's just a basic model).

  10. #10
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    Interesting!
    I’ll test it on my T4 & T4.1

    Do you mind sharing the code you used?

  11. #11
    Senior Member vjmuzik's Avatar
    Join Date
    Apr 2017
    Posts
    823
    I'll share it, though it is mostly the same.
    Code:
    #include <Arduino.h>
    #include "FlexIO_t4.h"
    //#include "DMAChannel.h"
     
    FlexIOHandler *pFlex;
    IMXRT_FLEXIO_t *p;
    const FlexIOHandler::FLEXIO_Hardware_t *hw;
    //DMAChannel myDMA;
    //volatile uint32_t DMAMEM dataBuffer[2] __attribute__((aligned(32)));
    uint8_t bufferData[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
     
    void FlexIO_Init(){
        /* Get a FlexIO channel */
        pFlex = FlexIOHandler::flexIOHandler_list[1]; // use FlexIO2
     
        /* Pointer to the port structure in the FlexIO channel */
        p = &pFlex->port();
        
        /* Pointer to the hardware structure in the FlexIO channel */
        hw = &pFlex->hardware();
     
        /* Basic pin setup */
        pinMode(10, OUTPUT); // FlexIO2:0
        pinMode(12, OUTPUT); // FlexIO2:1
        pinMode(11, OUTPUT); // FlexIO2:2
        pinMode(13, OUTPUT); // FlexIO2:3
    //    pinMode(43, OUTPUT); // FlexIO2:7
    //    pinMode(44, OUTPUT); // FlexIO2:8
    //    pinMode(45, OUTPUT); // FlexIO2:9
    //    pinMode(6, OUTPUT); // FlexIO2:10
    //    pinMode(9, OUTPUT); // FlexIO2:11
        
        /* High speed and drive strength configuration */
        *(portControlRegister(10)) = 0xFF; 
        *(portControlRegister(12)) = 0xFF;
        *(portControlRegister(11)) = 0xFF;
        *(portControlRegister(13)) = 0xFF;
    //    *(portControlRegister(43)) = 0xFF;
    //    *(portControlRegister(44)) = 0xFF;
    //    *(portControlRegister(45)) = 0xFF;
    //    *(portControlRegister(6)) = 0xFF;
    //    *(portControlRegister(9)) = 0xFF;
     
        /* Set clock */
        pFlex->setClockSettings(3, 0, 0); // 480 MHz
     
        /* Set up pin mux */
        pFlex->setIOPinToFlexMode(10);
        pFlex->setIOPinToFlexMode(12);
        pFlex->setIOPinToFlexMode(11);
        pFlex->setIOPinToFlexMode(13);
    //    pFlex->setIOPinToFlexMode(43);
    //    pFlex->setIOPinToFlexMode(44);
    //    pFlex->setIOPinToFlexMode(45);
    //    pFlex->setIOPinToFlexMode(6);
    //    pFlex->setIOPinToFlexMode(9);
     
        /* claim Shifter 0 */
        pFlex->claimShifter(0);
     
        /* claim Timer 0 */
        pFlex->claimTimer(0);
     
        /* Enable the clock */
        hw->clock_gate_register |= hw->clock_gate_mask;
     
        /* Enable the FlexIO with fast access */
        p->CTRL = FLEXIO_CTRL_FLEXEN | FLEXIO_CTRL_FASTACC;
    }
     
    void singleBeatWrite(uint8_t const * buffer, uint32_t const length){
        p->CTRL &= ~FLEXIO_CTRL_FLEXEN;
        //p->CTRL |= FLEXIO_CTRL_SWRST; //Software reset FlexIO registers enable
        //p->CTRL &= ~FLEXIO_CTRL_SWRST; //Software reset FlexIO registers disable
        /* Configure the shifters */
        p->SHIFTCFG[0] = 
            FLEXIO_SHIFTCFG_INSRC                                                   /* Shifter input */
          | FLEXIO_SHIFTCFG_SSTOP(0U)                                               /* Shifter stop bit disabled */
          | FLEXIO_SHIFTCFG_SSTART(0U)                                              /* Shifter start bit disabled and loading data on enabled */
          | FLEXIO_SHIFTCFG_PWIDTH(8U-1U);                                          /* Bus width */
          
        p->SHIFTCTL[0] = 
            FLEXIO_SHIFTCTL_TIMSEL(0U)                                              /* Shifter's assigned timer index */
          | (0<<23) //FLEXIO_SHIFTCTL_TIMPOL(0U)                        /* Shift on posedge of shift clock */
          | FLEXIO_SHIFTCTL_PINCFG(3U)                                              /* Shifter's pin configured as output */
          | FLEXIO_SHIFTCTL_PINSEL(1)                                              /* Shifter's pin start index */
          | (0<<7) //((uint32_t)(1<<7))                                 /* Shifter's pin active high */
          | FLEXIO_SHIFTCTL_SMOD(2U);                                               /* Shifter mode as transmit */
     
        /* Configure the timer for shift clock */
        p->TIMCMP[0] = 
            ((1U * 2U - 1) << 8)                                                    /* TIMCMP[15:8] = number of beats x 2  1 */
          | (119); //(4U/2U - 1U)                                            /* TIMCMP[7:0] = baud rate divider / 2  1 */
        
        p->TIMCFG[0] = 
            FLEXIO_TIMCFG_TIMOUT(0U)                                                /* Timer output logic one when enabled and not affected by reset */
          | FLEXIO_TIMCFG_TIMDEC(0U)                                                /* Timer decrement on FlexIO clock, shift clock equals timer output */
          | FLEXIO_TIMCFG_TIMRST(0U)                                                /* Timer never reset */
          | FLEXIO_TIMCFG_TIMDIS(2U)                                                /* Timer disabled on timer compare */
          | FLEXIO_TIMCFG_TIMENA(2U)                                                /* Timer enabled on trigger high */
          | FLEXIO_TIMCFG_TSTOP(0U)                                                 /* Timer stop bit disabled */
          | (0<<1); //((uint32_t)(0<<1)) //FLEXIO_TIMCFG_TSTART(0U);    /* Timer start bit disabled */
        
        
        p->TIMCTL[0] = 
            FLEXIO_TIMCTL_TRGSEL((((0U) << 2) | 1U))                                /* Timer trigger selected as shifter's status flag */
          | (1<<23) //FLEXIO_TIMCTL_TRGPOL(1U)                          /* Timer trigger polarity as active low */
          | (1<<22)//FLEXIO_TIMCTL_TRGSRC(1U)                           /* Timer trigger source as internal */
          | FLEXIO_TIMCTL_PINCFG(3U)                                                /* Timer' pin configured as output */
          | FLEXIO_TIMCTL_PINSEL(0)                                                /* Timer' pin index: WR pin */
          | (1<<7) //FLEXIO_TIMCTL_PINPOL(1U)                           /* Timer' pin active low */
          | FLEXIO_TIMCTL_TIMOD(1U);                                                /* Timer mode as dual 8-bit counters baud/bit */
     
        /* Enable FlexIO */
        p->CTRL |= FLEXIO_CTRL_FLEXEN;
       
        if(length)
        {
            /* Use polling method for data transfer */
            for(uint32_t i=0; i<length-1U; i++)
            {     
                while(0 == (p->SHIFTSTAT & (1U << 0U)))
                {
                }
                p->SHIFTBUF[0U] = *buffer++;
            }
     
            /* Write the last byte */
            while(0 == (p->SHIFTSTAT & (1U << 0U)))
            {
            }
            p->TIMSTAT |= (1U << 0U);
            p->SHIFTBUF[0U] = *buffer++;
     
            /*Wait for transfer to be completed */
            while(0 == (p->TIMSTAT & (1U << 0U)));
            {
            }
        }
    } 
     
    void setup() {
      Serial.begin(115200);
      delay(1000);
      Serial.print(CrashReport);
      Serial.println("Start setup");
      delay(1000);
      FlexIO_Init();
      delay(10);
    }
     
    void loop() {
      singleBeatWrite(bufferData,4);
      Serial.println("sent data");
      delay(500);
    }
    Of note, I didn't define the full 8 bit pin width for the Teensy 4.0 since my logic analyzer only has 4 pins, but it is running as if was.

  12. #12
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    @vjmuzik

    Thanks for your code example.

    I tested it on the Teensy 4.1, and I saw the same behavior as the Teensy MicroMod - An empty pulse when SHIFTBUF is loaded
    Click image for larger version. 

Name:	Screen Shot 2021-08-06 at 11.09.48.png 
Views:	19 
Size:	123.6 KB 
ID:	25512

    I then uploaded the exact same code to a Teensy 4.0, and you were right, it does not happen!
    Click image for larger version. 

Name:	Screen Shot 2021-08-06 at 11.14.00.png 
Views:	20 
Size:	159.3 KB 
ID:	25513

    Being that the Teensy 4.0 and the Teensy MicroMod use the same chip, whereas the Teensy 4.1 uses a physically larger chip, I can ONLY assume the issue lies within TeensyDuino core libraries or FlexIO_t4
    @PaulStoffregen @KurtE FYI

  13. #13
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    A quick update for anyone that might come across similar behavior with this:

    I don't know what the root cause was for this issue, but what fixed it was to compile for T4.0 first, then for the Teensy MM.
    Since installing TD1.54, I had never compiled any sketches for a T4, so something must had been "off". Very odd behavior, but unable to replicate it again.
    Click image for larger version. 

Name:	Screen Shot 2021-08-16 at 11.11.22.jpg 
Views:	17 
Size:	65.5 KB 
ID:	25576

    Now I need to try fix the pulsing length of the CS & D/C lines - these are standard digital pins using digitalWrite to set them HIGH/LOW.

  14. #14
    Any solution to this issue yet? I face the same issue.

  15. #15
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    So after some testing I have concluded that the root cause of the issue is compiling the sketch for any CPU clock speed below the default 600mhz.

    Not sure if this is by design or a bug, but doesn’t seem to interest anyone else here. So I’ll let it be as finding a solution is beyond my amateur coding capabilities

  16. #16
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,580
    Sorry I am not sure, but my guesses, would include:
    You are configuring the FlexIO to have a clock speed of 480mhz.

    Now when you are running at some different Speed maybe the clocks are into CPU clock timings and some rounding of clocks into the CPU clock timings...

  17. #17
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    I tried to play with other clock sources, such as PLL5 and PLL3 PFD2 using dividers of 2&3 - and what do you know, it worked.
    So back to PLL 3, this time with dividers as well - and it works!

    So the issue is as follows:
    As we know, FlexIO can run at a max speed of 240Mhz. But that is not true if CPU speed >=600Mhz (I tired 720 as well).

    So this is a combination of unexpected behavior, and my fault for overlooking the dividers
    Code:
    pFlex->setClockSettings(3, 0, 0); // 480 MHz
    I have it set as follows to get a clock speed of 240Mhz
    Code:
    pFlex->setClockSettings(3, 1, 0); // 240 MHz
    And it runs well below 600Mhz CPU speed.

  18. #18
    Quote Originally Posted by Rezo View Post
    I tried to play with other clock sources, such as PLL5 and PLL3 PFD2 using dividers of 2&3 - and what do you know, it worked.
    So back to PLL 3, this time with dividers as well - and it works!

    So the issue is as follows:
    As we know, FlexIO can run at a max speed of 240Mhz. But that is not true if CPU speed >=600Mhz (I tired 720 as well).

    So this is a combination of unexpected behavior, and my fault for overlooking the dividers
    Code:
    pFlex->setClockSettings(3, 0, 0); // 480 MHz
    I have it set as follows to get a clock speed of 240Mhz
    Code:
    pFlex->setClockSettings(3, 1, 0); // 240 MHz
    And it runs well below 600Mhz CPU speed.
    Wow a solution, I'm gonna try this!

    EDIT: It works!! You're a genius Rezo. And here I thought that KurtE was gonna be the one solving it :P
    Last edited by Dogbone06; 08-25-2021 at 11:49 AM.

  19. #19
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    9,580
    Glad you got it working!

  20. #20
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    Quote Originally Posted by KurtE View Post
    Glad you got it working!
    Thanks! Sometimes we overlook the small stuff.
    I closed the GitHub issue with a short explanation

  21. #21
    Thanks for the update! This also helps explain something I had noticed which is that the SmartMatrix driver (which uses FlexIO at 480 MHz) doesn't work properly with the CPU clock below 600 MHz.

    Is FlexIO only specified to run at 240, so anything above that is undocumented?

  22. #22
    Senior Member
    Join Date
    Oct 2019
    Posts
    239
    Quote Originally Posted by easone View Post
    Thanks for the update! This also helps explain something I had noticed which is that the SmartMatrix driver (which uses FlexIO at 480 MHz) doesn't work properly with the CPU clock below 600 MHz.

    Is FlexIO only specified to run at 240, so anything above that is undocumented?
    Hey Eric,
    So the documentation didn't state anything specific about max clock speed, as you can run FlexIO on other clock sources that run at a higher speed.
    But as the default clock source (or maybe call is suggested source) is PLL3, and the next highest frequency you can go to after 480Mhz is 240Mhz, I can only assume that that is the highest stable number it can run at.

    Also, I don't see any point in running the peripheral at such a high clock speed when the bus speed is 20-40 times lower, I'd just lower the clock speed and use a smaller divider on the TIMCMP register - but that's applicable to my usecase.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •