Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 09:46 28 Apr 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : uM2(+): Arbitrary bit sequence generator

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8582
Posted: 11:37pm 20 Jun 2016
Copy link to clipboard 
Print this post

Prompted by a PM about the DMX protocol I've written a very simple CSUB that can generate any arbitrary sequence of bits.

Usage is simplicity itself:

Set up the pin as an output and set it to the required initial condition high or low
set up an array of bit lengths in micro-seconds expressed as floating point numbers
call the bitbanger CSUB

At the end of each bit duration the CSUB will invert the output so you need to specify both the on and off durations.

The CSUB takes care of things like CPU speed but of course the faster the CPU the more accurate the bit lengths

If an even number of bits is specified the output is left in the same state as it started. An odd number will result in it ending up inverted. In both cases the last duration specified does not result in a transition but must be included to terminate the CSUB

The picture is the result of the example code





Option explicit
option default NONE
setpin 19,DOUT
pin(19)=1
dim float lengths(9)=(1, 1.5, 0.5, 0.75, 1, 0.5, 1.5, 1, 0.5, 1) 'array of bit lengths in usec
pause 3000
bitbanger(19,10,lengths())
end

CSub bitbanger 'pin number, number of bits, floating point array of bit lengths in usec
00000000
27BDFFC0 AFBF003C AFBE0038 AFB70034 AFB60030 AFB5002C AFB30024 AFB20020
AFB1001C AFB00018 AFB40028 3C109D00 8E030000 00808821 8E020080 8C640000
00A09021 00002821 00C0B021 0040F809 8E140064 00409821 8E02009C 3C0449F4
0040F809 24842400 00402821 0280F809 02602021 0040B821 8E240000 8E020024
24050007 0040F809 241E0001 AFA20010 8E020028 0040F809 8E240000 8E520000
8E030040 005EF004 0060F809 00122080 AFA20014 12400013 0040A821 0000A021
00008821 3C139D00 0014A080 02D41821 8C640000 8E620058 8E70007C 0040F809
02E02821 26310001 0200F809 00402021 02B4A021 0232182B AE820000 1460FFF2
0220A021 8FA30014 3C040008 8C620000 2442FFFD AC620000 3C03BF88 AC641064
3C03BF88 00001021 AC601068 40824800 8FA50014 8FA30010 2652FFFF AC7E0000
8CA40000 00442021 40024800 0044182B 1460FFFD 00000000 1640FFF6 24A50004
8FBF003C 3C020008 3C03BF88 AC621064 3C03BF88 8FBE0038 8FB70034 8FB60030
8FB5002C 8FB40028 8FB30024 8FB20020 8FB1001C 8FB00018 AC621068 03E00008
27BD0040
End CSub


C source

void bitbanger(long long *mypin,long long *numpulses, float parray[]){
float ppusec=FDiv(IntToFloat(CurrentCpuSpeed),LoadFloat(0x49F42400));//number of clock ticks per microsecond
unsigned int volatile * invport=GetPortAddr(*mypin, LATINV);
int k,pin=1<<GetPinBit(*mypin);
register unsigned int index=0,next_clock,current_ticks = 0, j=*numpulses;
int *sarray=GetTempMemory(j * 4);
for(k=0;k<j;k++){
sarray[k]=FloatToInt(FMul(parray[k],ppusec));
}
sarray[0]=sarray[0]-3; //loop initialisation overhead
mT4IntEnable(0);
asm volatile("mtc0 %0, $9": "+r"(current_ticks)); //set the current number of ticks to 0
do {
*invport=pin;
next_clock=current_ticks+sarray[index++];
j--;
do {
asm volatile("mfc0 %0, $9" : "=r"(current_ticks));//get the time in ticks since zeroed
} while(current_ticks<next_clock);
} while(j);
mT4IntEnable(1); //re-enable the RTC
}


Edited by matherp 2016-06-22
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2289
Posted: 03:16am 21 Jun 2016
Copy link to clipboard 
Print this post

this looks like an extremely useful bit of code. i was wondering: how hard would it be to modify the function just a fraction, so that if the pin specified was already configured as a PWM output, then instead of inverting the pin at the completion of each 'step', instead the PWM was turned on/off?

this would allow an IR LED to be attached to the pin specified, in order to generate infrared remote control codes. the application i am thinking of is using a micromite to create a replacement for a heatpump remote control (with simplified operation compared to the original remote), though it could be generalized to any IR control application where you could uncover the timing.

cheers,
rob :-)
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8582
Posted: 03:31am 21 Jun 2016
Copy link to clipboard 
Print this post

  Quote  how hard would it be to modify the function just a fraction, so that if the pin specified was already configured as a PWM output, then instead of inverting the pin at the completion of each 'step', instead the PWM was turned on/off?


Easiest way of doing this is a simple discrete logic AND of a continuous PWM and the bit sequence



Edited by matherp 2016-06-22
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 8582
Posted: 01:50am 03 Mar 2017
Copy link to clipboard 
Print this post

As requested here is a version for the MZ.

There is one important difference. The durations are expressed as nano-seconds and must be passed as an integer array

Option explicit
option default NONE
const testpin=97
setpin testpin,DOUT
pin(testpin)=1
dim INTEGER lengths(9)=(1000, 1500, 500, 750, 1000, 500, 1500, 1000, 500, 1000) 'array of bit lengths in nsec
bitbangerMZ testpin,10,lengths()
end
CSub bitbangerMZ
00000000
27BDFFD0 AFBF002C AFB50028 AFB40024 AFB30020 AFB2001C AFB10018 AFB00014
00808021 00A0A821 00C08821 3C149D00 8E824024 8C840000 0040F809 24050007
00409021 8E824028 0040F809 8E040000 24130001 00539804 8EB00000 8E824040
0040F809 001020C0 12000021 00404821 00003021 00001821 3C0A9D00 000630C0
01262821 02263021 8CC40000 8CC80004 8D464090 80CB0057 24060408 11600003
00003821 24060333 00003821 01060018 70870000 00004012 00C40019 00003012
00003810 01073821 000724C0 00064342 01042025 ACA40000 00072343 ACA40004
24630001 0070202B 1480FFE4 00603021 8C440000 8C450004 2483FFFD 0064202B
24A5FFFF 00852021 AC430000 AC440004 41636000 000000C0 00001821 40834800
00403021 AE530000 8CC50000 00652821 2610FFFF 40034800 0065202B 1480FFFD
00000000 1600FFF7 24C60008 41636020 3C039D00 8C634044 0060F809 00402021
8FBF002C 8FB50028 8FB40024 8FB30020 8FB2001C 8FB10018 8FB00014 03E00008
27BD0030
End CSub
 
CaptainBoing

Guru

Joined: 07/09/2016
Location: United Kingdom
Posts: 1985
Posted: 02:32am 03 Mar 2017
Copy link to clipboard 
Print this post

... told you

Peter, I bet there was smoke coming off your keyboard
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024