Menu

Bit Banging. Is there any saving to be made in my code example?

2026-03-20
2026-03-21
  • Roger Jönsson

    Roger Jönsson - 2026-03-20

    I need to sample PORTF.6 and write its state to LATC.2, simultaneously keeping LATC.1 low and setting LATC.0 low.

    //LatC is b'00000001'
    DIM BBang__D00=b'00000000'
    //The below takes 5 instructions, can it be made in less?
    BBang__D00.2 = PortF.6
    LATC = BBang__D00 
    //If LATC.2=1 then I get LATC=b'00000100' etc = ok
    

    I have turned and squeezed and this is the most effective solution I could come up with. For my planned needs it is just about what I need, so really its fine. -Still I can't but wonder if there are a smarter, more time efficient way.

     
  • Anobium

    Anobium - 2026-03-20

    This may be faster

    #Option volatile LATC.2
    LATC.2 =  PortF.6
    
     
  • Roger Jönsson

    Roger Jönsson - 2026-03-20

    That does not change LATC.0 to zero?

    //I have
    LATC=b'00000001'
    //I need to do SIMULTANEOUSLY:
    LATC.2 = PortF.6
    LATC.0 =0

    //If LATC.2=1 then the result is: LATC=b'00000100'

     
    • Anobium

      Anobium - 2026-03-20

      The ASM clears the LATC.0 bit.

      And, there is no concept in ASM of simultaneously. Use can use CLC - that could.

       
      • Anobium

        Anobium - 2026-03-20

        and, in the new simulator LATC.0 is cleared as expected.

         
  • Roger Jönsson

    Roger Jönsson - 2026-03-20

    Maybe I simplified my example too far for it to be understandable....
    This is about a parallel to serial interface. So different data bits/pins are sequentially read, combined with 2 clockbits generated from a pattern.

    I choose from a sequential pattern, one of four variables containing clock states to output (two bits/pins = four combinations) and which datain pin to sample and insert into the variable.
    Then I send the variable (all three bits) to the PORT in one BANG!

    BBang__D00.2 = PortF.6
    LATC = BBang__D00 //=b'XXXXXDCC' 
    // D is the data inserted and CC is the output clock bits.
    

    This takes five instruction cycles. Pretty quick, fast enough and the real world output looks very nice, so I'm not complaining at all! What I wondered is if there was some magic trick maybe saving one instruction cycle, not having to read the databit into the variable before sending it all to the PORT/LATC. Some trick in the logic that I haven't been able to imagine.
    I have other ideas using timers doing roughly the same thing that would be more efficient, but I would see how far this track takes me.

     
  • Anobium

    Anobium - 2026-03-21

    This is faster.

    Option volatile LATC.2

    LATC.2 = PortF.6

     
  • Roger Jönsson

    Roger Jönsson - 2026-03-21

    It is actually one instrucktion cycle slower with #Option volatile LATC.2.
    If I turn it off 3 instructions, if I turn it on 4 instructions. Measuring at the outputs.
    Also I can not follow protocol, updating writing bitbanged clock cykles at the same time as the value from PortF.6
    So I guess my current code is pretty much optimal(?).

    //With: #Option volatile LATC.2:
    ;LATC.1 = PortF.6
    btfss PORTF,5,ACCESS
    bcf LATC,1,ACCESS
    btfsc PORTF,6,ACCESS
    bsf LATC,1,ACCESS

    // Without: #Option volatile LATC.2:
    ;LATC.1 = PortF.6
    bcf LATC,1,ACCESS
    btfsc PORTF,6,ACCESS
    bsf LATC,1,ACCESS

     
  • Anobium

    Anobium - 2026-03-21

    Without #option the output port WILLL always be set low priority to being set high. This will look like jitter on a scope. But, it may be ok/acceptable with your use case.

     
  • Roger Jönsson

    Roger Jönsson - 2026-03-21

    Just sending byte variables to the PORT looks jitter free on my 350MHz 1GSa/s oscilloscope. No glitches to be seen (18F57Q84), so I guess it the safest and fastest way for my project. I will see what happens when I hook it up to a DAC.

     
  • Roger Jönsson

    Roger Jönsson - 2026-03-21

    I hooked this Parallel to i2S converter up to DAC. A sine plays nicely, coming from another 16F57Q84 clocked by an external interrupt from the i2S converter (which is clock master).
    My Musicbox slave to external interrupt, chokes when more than 6 voices plays (it slacks a bit on load and then probably does not deliver data in time = horribly sounding bit errors), but it sounds fine with a limited number of voices. I will leave it at that. I have other ideas where to use an i2S DAC = HQ 16-bit audio.
    GC-basic delivered. Again!

    Correction: Ofcourse I couldn't stop poking. I was sending the Musicbox sample data to the ports at the wrong moment. After moving that instruction it now plays without problem.

     
    👍
    1

    Last edit: Roger Jönsson 2026-03-21

Log in to post a comment.

MongoDB Logo MongoDB