PDA

View Full Version : TipsNTricks: Why JMP JMP JMP makes sense



MagIO2
03-21-2009, 05:17 AM
Hi all!
Maybe you already recognized that I'm a new member of this forum and new to the Propeller programming. Today I want to share a finding I made in PASM programming to other newbies. I made this finding when programming a driver for a IR receiver. Of course I found the IR module on the ObEx and tried it out and it worked. But when you are new in something you need to have goals. So I made reprogramming an IR driver my first goal. (In the end it should read and transmit any kind of IR codes from IR remote controls).
The driver can permanently stay in a COG and reads a buffer for commands.
First part of my driver has to detect the lenght of pulses and pauses, which is needed to find out which coding is used for a IR remote control. As the driver should not be blocking, it only waits a limited time for this measurement.
Soon I discovered that the loop for measuring the 1s and the one for measuring the 0s looked mostly identical. So I did the following to put these two parts together:

ir_trim_startииииииииии movииииииииииии ir_time, cntииииииииии' initialize the wait
иииииииииииииииииииииии addииииииииииии ir_time, ir_dt
иииииииииииииииииииииии movииииииииииии ir_trim_jump, ir_trim_jump1иии' initialize the jump commands to the initial code-flow
иииииииииииииииииииииии movииииииииииии ir_trim_cjmp, ir_trim_cjmp1
иииииииииииииииииииииии movииииииииииии ir_trim_out, ir_trim_out1
ir_trim_lp1ииииииииииии movииииииииииии ir_count, ir_zeroииииииииииииии ' start measurement of a 0 or a 1
ir_trim_lp2ииииииииииии waitcntииииииии ir_time, ir_dtиииииииииииииииии ' no need to count faster for low frequency IR signal
иииииииииииииииииииииии addииииииииииии ir_count, #1ииииииииииииииииии
иииииииииииииииииииииии cmpииииииииииии ir_maxwait, ir_count WCииииииии ' if the maxwait has been reached
ir_trim_outии if_cиииии jmpииииииииииии #ir_loop_retиииииииииииииииииии ' we go back to ... well, that depends
иииииииииииииииииииииии testиииииииииии ir_mask, ina WZииииииииииииииии ' now let's see if the IR-Pin has changed
ir_trim_cjmpи if_zиииии jmpииииииииииии #ir_trim_lp2иииииииииииииииииии ' flag depends on current loop-status
ir_trim_jumpиииииииииии jmpииииииииииии #ir_set_1ииииииииииииииииииииии ' find max and min of 1s or 0s
ir_trim_jump1ииииииииии jmpииииииииииии #ir_set_1ииииииииииииииииииииии ' here we have a list of jump commands. One set for reading 1s
ir_trim_jump2ииииииииии jmpииииииииииии #ir_set_0ииииииииииииииииииииии ' and one set for reading 0s
ir_trim_cjmp1 if_zиииии jmpииииииииииии #ir_trim_lp2
ir_trim_cjmp2 if_nzииии jmpииииииииииии #ir_trim_lp2
ir_trim_out1и if_cиииии jmpииииииииииии #ir_loop_ret
ir_trim_out2и if_cиииии jmpииииииииииии #ir_trim_done
ir_set_1иииииииииииииии cmpииииииииииии ir_1_max, ir_count WCииииииииии ' find out the min and max duration
иииииииииииии if_cиииии movииииииииииии ir_1_max, ir_count
иииииииииииииииииииииии cmpииииииииииии ir_count, ir_1_min WC
иииииииииииии if_cиииии movииииииииииии ir_1_min, ir_count
иииииииииииииииииииииии movииииииииииии ir_trim_jump, ir_trim_jump2ииии ' and now switch to reading 1s
иииииииииииииииииииииии movииииииииииии ir_trim_cjmp, ir_trim_cjmp2
иииииииииииииииииииииии movииииииииииии ir_trim_out, ir_trim_out2
иииииииииииииииииииииии jmpииииииииииии #ir_trim_lp1
ir_set_0иииииииииииииии cmpииииииииииии ir_count, ir_0_max WCииииииииии ' and now switch to reading 0s
иииииииииииии if_ncииии movииииииииииии ir_0_max, ir_count
иииииииииииииииииииииии cmpииииииииииии ir_0_min, ir_count WC
иииииииииииии if_ncииии movииииииииииии ir_0_min, ir_count
иииииииииииииииииииииии movииииииииииии ir_trim_jump, ir_trim_jump1
иииииииииииииииииииииии movииииииииииии ir_trim_cjmp, ir_trim_cjmp1
иииииииииииииииииииииии movииииииииииии ir_trim_out, ir_trim_out1
иииииииииииииииииииииии jmpииииииииииии #ir_trim_lp1
ir_timeииииии longиииии 0
ir_dtииииииии longиииии 800
ir_maxwaitиии longиииии 200
ir_1_maxиииии longиииии 0
ir_1_minиииии longиииии 0
ir_0_maxиииии longиииии 0
ir_0_minиииии longиииии 0
ir_countиииии longиииии 0
ir_maskииииии longиииии %00000000_00000000_00000100_00000000

I know, there is still room for improvements - or better to say, I figured it out while writing this. Morphing code with the movs, movd and movi can be more effective (in terms of needed RAM), if only one part of the command needs to be changed - which is the case in my loop. But if you have to change condition flags AND the adress moving pre-compiled code is more effective.
Why do I write a thread for that? Today I was thinking about this while waiting for the train and I wondered why I did not do that before with other Controllers/CPUs. I programmed a lot of different processors in Assembly (6501, 68k, 80486, 8051, PIC, AVR, R8C). And the answer is:
1. Sometimes the code is in Flash and it is simply impossible
2. Harvard Architecture does not allow to change code
3. CPU's load code to different places, so the jumps are usually relative
By the way, this technique is also nice when reading commands from HUB, like a lot of drivers do it. Instead of MOVS and NOP (for pipeline delay) one can jump into a jump-table, which needs one command less. Of course there are other ways which use less RAM. Sounds like the YIN and YANG of programming ;o)
I'm very curious on what to find next.

Post Edited (MagIO2) : 3/20/2009 9:22:42 PM GMT