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.

CC1312R: Bit bang multiple DIO as fast as possible

Part Number: CC1312R

Hi,

I have to bit bang 12 DIOs at high speed, uninterrupted, but also have to have radio capabilities.

Using an infinite loop and writing to GPIO addresses directly for setting and clearing (0x40022090 and 0x400220A0) yields somewhat decent results in terms of speed, but radio (TI 15.4) operations are needed, and these interruptions cause glitches in the IO, naturally.

I gave Sensor Controller Studio a try as a test to free the M4 core, but I could only get roughly 33 kHz for a simple toggle with:

    while(1) {
        scifSwTriggerExecutionCodeNbl(1 << SCIF_LED_BLINKER_TASK_ID);
    }

where the sensor studio execution code is simply:

gpioToggleOutput(AUXIO_O_LED_CTRL);

Is this all I can hope for from the sensor core?

Ideally, I could get GPIO at a few MHz one way or another and I would appreciate suggestions on the best way to proceed. 

Thanks in advance!

  • Hi mh,

    You can get much better performance out of the Sensor Controller (SC), your test case is toggling a pin by trying to execute the task code as fast as you can, this is not really how you are intended to use the SC (while you are free to do so if you want). This approach means you basically need to sync the M4 and SC at each toggle, what you really want to do is to write the SC program to run independently of the M4 (start once, run forever/until stopped). 

    For example, the sensor controller code could be something along the lines:

    while (state.ended == 0)
    {
       gpioToggle()
    }

    With your M4 application only starting the task ones. 

  • Hi M-W,  I tried the infinite loop in SC as you suggest, then used the following in CCS:

        // Initialize the SCIF driver
        scifInit(&scifDriverSetup);
    
        // Enable RTC ticks, with N Hz tick interval
        scifStartRtcTicksNow(0x0001000 / 1);
    
        scifStartTasksNbl(1 << SCIF_LED_BLINKER_TASK_ID);

    While I saw the toggle in SC, the above code doesn't seem to toggle the pin when run in CCS. That is also the reason I initially had the toggle in the main while loop in my initial post.

    Cn you provide some guidance? Just getting started on SC, it required a bit of getting used to.

  • ...following up. I see I shouldn't have used TIRTOS to sync the task (though I'd still like to understand why it fails to work, regardless of system tick settings!)

    I've now just done:

    scifSwTriggerExecutionCodeNbl(1 << SCIF_LED_BLINKER_TASK_ID);

    outside a loop and see the toggle. Sorry about that!

    Now, I am getting 1.2 MHz, not bad, and actually same as I saw in Sensor Studio. Any chance I can get this higher?

  • I think 1.2 MHz is in the ballpark of what to expect in this case (assuming 1.2 MHz includes a full period, 50% high and 50% low).

    If you create a simple loop as I suggested above, the loop would require ~10 cycles to run (1 instruction typically takes 2 cycles on the SC). This means that you should run the GPIO toggle part at a rate of 24 MHz / 10, or 2.4 Mhz. Assuming 2 toggles / period, that makes 1.2 Mhz. 

    Now what someone using the sensor controller can do is to write their own "routines" in assembly in order to do something in a more efficient way. This is however not trivial and can take some trial an error (but the help section contains the documentation needed).

    To get an idea of how this could be done, I recommend looking at the "proc_def" folder of Sensor Controller Studio. This contains all the API function such as GPIO toggle. If you open the ".prd" file for gpio_toggle, you should get an idea of how it works. You could compare what you see here to what is generated by SC. You do this by clicking the "Debug one task iteration" option in the Task Testing view. This brings up the full code and allows you to single step and also see what the assembly generated looks like.

  • Alright, thanks M-W. One final question, if I may. I don't readily see a way in the language reference to bit bang IOs from a buffer, or to toggle IOs simultaneously. Outside of assembly, is there a way to write to IO registers directly?

  • On the SC, the normal GPIO APIs are for a single IO only. You could however toggle/set a group of values if you implement your own routine for it. An easy start would be to make a copy of for example the GPIO toggle .prd file and inside it, change the "<proc_def name="gpioToggleOutput" version="1.0.0">" line to a new fitting name. This will result in you getting your own function into SC easily. You could then simply re-work the assembly part of this new .prd file to fit your needs.

    Note that you could really only access at most 8 IOs at a time. Section 19.4.2 in the Technical Reference Manual describes this in more detail. 

  • The Sensor Controller assembly? 

  • Sensor Controller itself, the assembly, yes. But I was expressing how the overall CC13x2/SimpleLink/TIRTOS ecosystem and the support offered here is pretty incredible! Big thanks!

  • Happy to hear it :) If there is anything else you have questions about, don't hesitate to open up a new forum post!