Shop OBEX P1 Docs P2 Docs Learn Events
Download PropBasic Version 1.48 (Aug 9, 2018) Here... - Page 2 — Parallax Forums

Download PropBasic Version 1.48 (Aug 9, 2018) Here...

2»

Comments

  • Hi

    I'm using the rctime function to read a thermistor (in conjunction with a 0.1uf capacitor).
    It works great in cog mode but not in LMM mode.

    Dave
  • BeanBean Posts: 8,129
    Dave,
    I will look into it and let you know what I find.

    Bean
  • BeanBean Posts: 8,129
    Dave,
    Looking at the source code I don't see any issues.
    Can you post a a little of your code ? And maybe the section of .spin (pasm) code that it generates ?
    That would help a lot.

    Bean
  • Hi
    I expect its to do with the waitcnt . Maybe 80 clocks is not long enough for LMM to complete.
    Its seems to print gibberish ever 50 or so seconds (nowhere near exactly that) which is about how long it takes to count 2^32 at 80Mhz.
    'test of rctime on thermister 10k ohm at 25 degs c
    '220 ohm resisitor from pin 24 to thermister and 0.1 uF cap in parallel-other end to 0v
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    
    therm	PIN  24 low			
    
    
    pcrlf		SUB 0
    sertx		SUB 1
    print		SUB 1
    pstr		SUB 1
    
    strslt	hub string(20)
    
    temp	var	long
    stmp1	var	long
    stmp2	var	long
    
    
    
    ' ======================================================================
    ' this works- LMM doesn't (bet I've done something daft!!!!)
      PROGRAM Start  'LMM
     
    ' ======================================================================
    
    START:
    pause 5000
    pstr "starting"
    pcrlf
    
    do
    high therm
    pause 5
    rctime therm,1,temp 
    print temp
    pstr " "
    pause 1000
    loop
    end
    
    
    '========== SUBS ===========================
    sub pstr	'send serial string
    stmp1=__param1
    do
    	rdbyte stmp1,stmp2
    	if stmp2=0 then exit
    	sertx stmp2
    	inc stmp1
    loop
    endsub
    '----------------
    sub print
    	strslt=str __param1,8
    	pstr strslt
    endsub
    '------------------------
    
    sub sertx	'send serial byte
    	SEROUT 30,T9600,__param1
    endsub
    
    '---------------------------
    sub pcrlf
    	sertx 13
    	sertx 10
    endsub
    

    the relevant spin bits....
    cog version:-
    mov           __temp2,#5                   'pause 5
                      mov           __temp1,_1mSec              
                      add           __temp1,cnt                 
    __L0002                                                     
                      waitcnt       __temp1,_1mSec              
                      djnz          __temp2,#__L0002            
    
                      mov           __temp1,therm                'rctime therm,1,temp 
                      andn          dira,__temp1                
                      mov           temp,#0                     
                      mov           __temp2,cnt                 
                      adds          __temp2,#80                 
    __L0003                                                     
                      adds          temp,#1                     
                      waitcnt       __temp2,#80                 
                      and           __temp1,ina NR, WZ          
        IF_NZ         jmp           #__L0003                    
    
                      mov           __param1,temp                'print temp
                      call          #print                      
    

    This is LMM version:-
    mov           __temp2,#5                   'pause 5
                      mov           __temp1,_1mSec              
                      add           __temp1,cnt                 
    __L0002                                                     
                      waitcnt       __temp1,_1mSec              
                      djnz          __temp2,#_LMM_JUMP          
                      long          @@@__L0002                  
    
                      mov           __temp1,therm                'rctime therm,1,temp 
                      andn          dira,__temp1                
                      mov           temp,#0                     
                      mov           __temp2,cnt                 
                      adds          __temp2,#80                 
    __L0003                                                     
                      adds          temp,#1                     
                      waitcnt       __temp2,#80                 
                      and           __temp1,ina NR, WZ          
        IF_NZ         sub           __PC,#(($-__L0003)*4)+4     
    
                      mov           __param1,temp                'print temp
    

    Hope that helps

    Dave
  • BeanBean Posts: 8,129
    Dave,
    You are correct. 80 clocks is not quite enough time to get through the loop in LMM.
    I will have to change RCTIME to measure in 2uSec increments.
    As a workaround you could use in-line assembly.
    ASM
                      mov           __temp1,therm                'rctime therm,1,temp 
                      andn          dira,__temp1                
                      mov           temp,#0                     
                      mov           __temp2,cnt                 
                      adds          __temp2,#160                 
    __RCTIMEFIX                                                     
                      adds          temp,#1                     
                      waitcnt       __temp2,#160                 
                      and           __temp1,ina NR, WZ          
        IF_NZ         sub           __PC,#(($-__RCTIMEFIX)*4)+4     
    ENDASM
    

    If you try it, let me know if it works.
    Remember the value will be in 2uSec units instead of 1uSec units.

    Bean
  • Hi again

    Yes that works- BUT- got another

    it seems in LMM one byte strings are corrupt- I have an example
    DEVICE P8X32A, XTAL1, PLL16X
    FREQ 80_000_000
    
    
    strslt	hub string(20)
    
    stmp1	var	long
    stmp2	var	long
    
    
    pcrlf		SUB 0
    sertx		SUB 1
    print		SUB 1
    pstr		SUB 1
    
    
    ' ======================================================================
      PROGRAM Start  LMM
    ' ======================================================================
    
    START:
    
    pause 5000
    pstr "starting"
    pcrlf
    do
    	pcrlf
    	pstr "hello"
    	pstr " "
    	pstr "Dave"
    	pstr "a"
    	pstr "bb"
    	pause 1000
    loop
    end
    
    '========== SUBS ===========================
    
    sub pstr	'send serial string
    stmp1=__param1
    do
    	rdbyte stmp1,stmp2
    	if stmp2=0 then exit
    	'phex stmp2
    	sertx stmp2
    	inc stmp1
    loop
    endsub
    '----------------
    sub print
    	strslt=str __param1,8
    	pstr strslt
    endsub
    '------------------------
    
    sub sertx	'send serial byte
    	SEROUT 30,T9600,__param1
    endsub
    
    '---------------------------
    sub pcrlf
    	sertx 13
    	sertx 10
    endsub
    

    produces...
    starting
    
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    hello&L(Davebb
    

    as you can see the one byte string " " and "a" are problematic while the longer ones are fine.
    The " " string with one space in produces &L( and the "a" produces nothing at all!

    Thanks for looking into these querks- really appreciate all your hard work.

    Dave

  • BeanBean Posts: 8,129
    edited 2019-09-12 00:45
    In PropBasic a single character in quotes is a byte value.
    More than one character produces a pointer to the address of the string.
    If you want to pass a single character to a SUB that is expecting a string you can append \000.

    You would have to use:
    pstr " \000" for space or pstr "a\000" for "a".

    You might get away with testing the parameter to see if it is less than 128 because strings are stored at the end of the program (I think...) so as long as there is at least 128 bytes of code, it should work.
    sub pstr	'send serial string
      IF __param1 < 128 THEN
        SERTX __param1
      ELSE
        stmp1=__param1
        do
    	rdbyte stmp1,stmp2
    	if stmp2=0 then exit
    	'phex stmp2
    	sertx stmp2
    	inc stmp1
        loop
      ENDIF
    endsub
    


    Bean
  • tritoniumtritonium Posts: 539
    edited 2019-09-21 20:50
    Hi

    Thanks for explaining- I have another question regarding LMM
    While running in LMM mode how much of the cog is used to "run" the LMM code (which can, I assume use the whole of the hub- barring hub variables etc.) and how much is left for cog vars? I am writing some code that 'could' use a large number of instant access cog vars but 'could' instead use hub variables, but at the expense of 'looking' less obvious. If you say there is enough room for 150 cog vars left while running LMM that might do. Hope I explained that clearly!

    edit/
    Also, whereas I can access hub variables by using a name or index from a base variable- can this be done in the cog vars. If I define an array date_time(7) VAR LONG then each long can be indexed, but if I want to also directly acces via year, month, day, etc is there a way- I cant assign a name to each of the indexed vars.


    Dave
  • BeanBean Posts: 8,129
    The cog code to run LMM is pretty minimum. There should be plenty of room for 150 longs.
    I don't recommend using COG arrays, it requires self-modifying-code and uses precious code space (for non-LMM code).
    I never use cog arrays, so I'm not sure if this will work but you can try:

    name VAR LONG MyArray(2)

    to create an alias.

    Bean
  • Hi Bean

    Thanks- pretty much as I thought.
    Having lots of fun trying to convert some pbasic code to prop. Its all quite do-able but looks rather different. I know propbasic has some commands like rctime and PULSOUT, pause etc and others have made libraries and examples of alternatives to lookup, lookdown etc, to achieve the same ends- all is good.

    Dave
  • Hi again

    Is there a way to restart the basic program- resetting stack etc as in the 'RUN' command of old.
    Will entering 'goto start' achieve this?

    Dave
  • BeanBean Posts: 8,129
    Unless you are using LMM there is no stack.

    In LMM you should be able to reset the call stack by doing:
    asm
      MOV __STACKPTR,#__STACK
    endasm
    

    Bean
Sign In or Register to comment.