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'DIMBBang__D00=b'00000000'//The below takes 5 instructions, can it be made in less?BBang__D00.2=PortF.6LATC=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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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(?).
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I need to sample PORTF.6 and write its state to LATC.2, simultaneously keeping LATC.1 low and setting LATC.0 low.
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.
This may be faster
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'
The ASM clears the LATC.0 bit.
And, there is no concept in ASM of simultaneously. Use can use CLC - that could.
and, in the new simulator LATC.0 is cleared as expected.
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!
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.
This is faster.
Option volatile LATC.2
LATC.2 = PortF.6
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
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.
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.
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.
Last edit: Roger Jönsson 2026-03-21