Shop OBEX P1 Docs P2 Docs Learn Events
"SUB or FUNCTION cannot be nested"...error message in Propbasic — Parallax Forums

"SUB or FUNCTION cannot be nested"...error message in Propbasic

Having a tough time figuring out what the above means. I have a GOSUB in a do/loop, but the respective SUB ROUTINE with the RETURN is outside the DO/LOOP. It is not "nested", as far as I can see...
DEVICE P8X32A, XTAL1, PLL8X
XIN 5_000_000
STACK 100
'========CONSTANTS============
baud2                  CON "T115200" 
HMC6352_READ           CON      $43
HMC6352_WRITE          CON      $42
GET_HEADING_command    CON      $41
'========PIN ASSIGNMENTS========
'Assignments of pin go in each COG that is using that pin..
HMC6352_data  PIN     1
HMC6352_clk   PIN     2
'============CODE===============
'================VARIABLES==================
I2C_DATA           VAR       LONG
I2C_LSB            VAR       LONG
rawHeading         VAR       LONG
  HMC6352 TASK   
PROGRAM Start  'this is running in COG 0
  Start:


 DO
   I2C_Start SUB
   I2C_Write SUB
   I2C_Stop  SUB
   I2C_ACK   SUB
   I2C_Read  SUB
   I2C_NACK  SUB
'''''''''''''''''''''''''''''''''''HMC6352:
''''''''''''''''''''''''''''''''''first read
  GOSUB I2C_Start                            ' Start communications on the I2C buss
  I2C_DATA = HMC6352_WRITE
  GOSUB I2C_Write                            ' Address the HMC6352 in write mode
  I2C_DATA = GET_HEADING_command
  GOSUB I2C_Write                            ' Send the get rawHeading command
  GOSUB I2C_Stop                             ' End communications on the I2C buss
  PAUSE 10
  GOSUB I2C_Start                            ' Start communications on the I2C buss
  I2C_DATA = HMC6352_READ
  GOSUB I2C_Write                            ' Address the HMC6352 in read mode
  PAUSE 10                                   ' Give the HMC6352 time to calculate the rawHeading
  GOSUB I2C_Read
  rawHeading = I2C_DATA                'HIGHBYTE Read in the high byte
  GOSUB I2C_ACK
  GOSUB I2C_Read
  rawHeading = I2C_DATA                 'LOWBYTE Read in the low byte
  GOSUB I2C_NACK
  GOSUB I2C_Stop                             ' End communications on the I2C buss
  rawHeading = rawHeading / 10               'whole degrees

LOOP
'=======================SUB ROUTINES========================
SUB I2C_Start
  HMC6352_data = 0                                   ' Pull HMC6352_data low
  HMC6352_clk  = 0                                  ' Pull HMC6352_clk low
RETURN
'
SUB I2C_Stop
  HMC6352_data = 0                                  ' Pull HMC6352_data low
  HMC6352_clk  = 1                                ' Let HMC6352_clk float high
  HMC6352_data = 1                                 ' Let HMC6352_data float high
RETURN
'
SUB I2C_ACK
  HMC6352_data = 0                                 ' Pull HMC6352_data low
  HMC6352_clk = 1                                  ' Let HMC6352_clk float high
  HMC6352_clk = 0                                 ' Pull HMC6352_clk low
  HMC6352_data = 1                                 ' Let HMC6352_data float high
RETURN
'
SUB I2C_NACK
  HMC6352_data = 1                                  ' Let HMC6352_data float high
  HMC6352_clk  = 1                                ' Let HMC6352_clk float high
  HMC6352_clk  = 0                                ' Pull HMC6352_clk low
RETURN
'
SUB I2C_Read
  SHIFTIN HMC6352_data, HMC6352_clk, MSBPRE, [I2C_DATA]       ' Read in 8 bits, MSB first
RETURN
'
SUB I2C_Write
  I2C_LSB = I2C_DATA.BIT0                    ' Store the status of the LSB
  I2C_DATA = I2C_DATA / 2
  SHIFTOUT HMC6352_data, HMC6352_clk, MSBFIRST, [I2C_DATA\7]  ' Write out the first 7 bits, MSB first
  IF I2C_LSB THEN INPUT HMC6352_data ELSE LOW HMC6352_data     ' Write the 8th bit
  INPUT HMC6352_clk                                  ' Using an open collector output
  LOW HMC6352_clk
  INPUT HMC6352_data                                  ' Leave HMC6352_data as an input
  INPUT HMC6352_clk                                  ' Ignore the ACK bit
  LOW HMC6352_clk
RETURN

ENDTASK HMC6352

Comments

  • BeanBean Posts: 8,129
    Just use the I2C commands built in to PropBasic...

    Bean
  • Thank you Bean, but I was wondering if you might have an example on how to get a heading out of the HMC6352 compass module using your I2C. The code example that I used, is what I use for the Basic stamp, and I know that works...and I was trying to model PROPBASIC code after that....but not getting anywhere.

    DenO
  • BeanBean Posts: 8,129
    Okay, but why are you making another TASK ?

    You do ENDTASK without even making a TASK ?

    You need to move the SUB defines before the PROGRAM line (before any code).

    You don't need GOSUB to call a SUB, just put the name.

    Why running at 40MHz instead of 80MHz ?

    You don't need STACK if not using LMM mode ?

    I have no idea if this will work, but something like this is formed right.

    P.S. You will probably need to put a delay every time you set a pin because the Propeller is too fast.
    DEVICE P8X32A, XTAL1, PLL8X
    XIN 5_000_000
    STACK 100
    '========CONSTANTS============
    baud2                  CON "T115200" 
    HMC6352_READ           CON      $43
    HMC6352_WRITE          CON      $42
    GET_HEADING_command    CON      $41
    '========PIN ASSIGNMENTS========
    'Assignments of pin go in each COG that is using that pin..
    HMC6352_data  PIN     1
    HMC6352_clk   PIN     2
    '============CODE===============
    '================VARIABLES==================
    I2C_DATA           VAR       LONG
    I2C_LSB            VAR       LONG
    rawHeading         VAR       LONG
    
    I2C_Start SUB
    I2C_Write SUB
    I2C_Stop  SUB
    I2C_ACK   SUB
    I2C_Read  SUB
    I2C_NACK  SUB
    
    
    PROGRAM Start  'this is running in COG 0
    
    Start:
    
    
     DO
    '''''''''''''''''''''''''''''''''''HMC6352:
    ''''''''''''''''''''''''''''''''''first read
      I2C_Start                            ' Start communications on the I2C buss
      I2C_DATA = HMC6352_WRITE
      I2C_Write                            ' Address the HMC6352 in write mode
      I2C_DATA = GET_HEADING_command
      I2C_Write                            ' Send the get rawHeading command
      I2C_Stop                             ' End communications on the I2C buss
      PAUSE 10
      I2C_Start                            ' Start communications on the I2C buss
      I2C_DATA = HMC6352_READ
      I2C_Write                            ' Address the HMC6352 in read mode
      PAUSE 10                                   ' Give the HMC6352 time to calculate the rawHeading
      I2C_Read
      rawHeading = I2C_DATA                'HIGHBYTE Read in the high byte
      I2C_ACK
      I2C_Read
      rawHeading = I2C_DATA                 'LOWBYTE Read in the low byte
      I2C_NACK
      I2C_Stop                             ' End communications on the I2C buss
      rawHeading = rawHeading / 10               'whole degrees
    
    LOOP
    '=======================SUB ROUTINES========================
    SUB I2C_Start
      HMC6352_data = 0                                   ' Pull HMC6352_data low
      HMC6352_clk  = 0                                  ' Pull HMC6352_clk low
    ENDSUB
    '
    SUB I2C_Stop
      HMC6352_data = 0                                  ' Pull HMC6352_data low
      HMC6352_clk  = 1                                ' Let HMC6352_clk float high
      HMC6352_data = 1                                 ' Let HMC6352_data float high
    ENDSUB
    '
    SUB I2C_ACK
      HMC6352_data = 0                                 ' Pull HMC6352_data low
      HMC6352_clk = 1                                  ' Let HMC6352_clk float high
      HMC6352_clk = 0                                 ' Pull HMC6352_clk low
      HMC6352_data = 1                                 ' Let HMC6352_data float high
    ENDSUB
    '
    SUB I2C_NACK
      HMC6352_data = 1                                  ' Let HMC6352_data float high
      HMC6352_clk  = 1                                ' Let HMC6352_clk float high
      HMC6352_clk  = 0                                ' Pull HMC6352_clk low
    ENDSUB
    '
    SUB I2C_Read
      SHIFTIN HMC6352_data, HMC6352_clk, MSBPRE, [I2C_DATA]       ' Read in 8 bits, MSB first
    ENDSUB
    '
    SUB I2C_Write
      I2C_LSB = I2C_DATA.BIT0                    ' Store the status of the LSB
      I2C_DATA = I2C_DATA / 2
      SHIFTOUT HMC6352_data, HMC6352_clk, MSBFIRST, [I2C_DATA\7]  ' Write out the first 7 bits, MSB first
      IF I2C_LSB THEN INPUT HMC6352_data ELSE LOW HMC6352_data     ' Write the 8th bit
      INPUT HMC6352_clk                                  ' Using an open collector output
      LOW HMC6352_clk
      INPUT HMC6352_data                                  ' Leave HMC6352_data as an input
      INPUT HMC6352_clk                                  ' Ignore the ACK bit
      LOW HMC6352_clk
    ENDSUB
    
    

    Bean
  • I am trying to work out I2C comm's using PROPBASIC, and the HMC6352 compass. I'm not getting very far, even with Bean's help in the 1.48 "rules of the propBasic".

    Has anyone written any code for the above, that they would like to share with a "newbee", for my learning experience.?

    I appreciate your time...and I have been using the FLIP, with other programs in PropBasic, and what a great "all in one processor". Hope it will become as popular at the Basic Stamp...was.

    DennO

Sign In or Register to comment.