Shop OBEX P1 Docs P2 Docs Learn Events
Anyone have examples of using the Prop Boe's ADC from PASM? — Parallax Forums

Anyone have examples of using the Prop Boe's ADC from PASM?

Martin_HMartin_H Posts: 4,051
edited 2013-07-08 00:29 in Propeller 1
I have a sensor that has an analog output and some Propeller code that uses sigma delta analog conversion to interface with it. I want to port the code to the Prop Boe and use its on-board ADC instead. If this was Spin code I could do it pretty easily, but the original code is in PASM, which I've been avoiding for a while now. I used to program in assembler back in the 80's, so I bit the bullet and read through the code. I found it relatively straight forward with a few bits I was clueless on.

I think if I had a PASM example showing how to use the Prop Boe's ADC, I could cut out the sigma delta section and replace it with the ADC example tweaked for this application. I imagine debugging PASM is a whole lot harder than debugging Spin as you don't have access to the serial terminal. But I'm willing to give this a shot since I think it will be easier than re-writing the whole thing in Spin.

Comments

  • David BetzDavid Betz Posts: 14,516
    edited 2012-10-01 12:37
    I don't have PASM code to do it but I do have PropGCC COG C code. That is, C code compiled to run directly in the COG not using LMM.
  • Martin_HMartin_H Posts: 4,051
    edited 2012-10-01 12:45
    Hmm, interesting idea. I haven't climbed the PropGCC learning curve, does the compiler produce human readable assembler output? If so could you cut and paste it here?
  • David BetzDavid Betz Posts: 14,516
    edited 2012-10-01 12:54
    Martin_H wrote: »
    Hmm, interesting idea. I haven't climbed the PropGCC learning curve, does the compiler produce human readable assembler output? If so could you cut and paste it here?
    I think GCC produces decent assembly output but it will be GAS syntax not PASM I think. I'll try to post it late tonight. Unfortunately, I'm busy this afternoon and early evening.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-10-01 13:32
    Martin,

    Here's some working code I've excerpted from a program I'm working on. It reads two inputs. Perhaps you can modify it for your own needs.
    PUB start
    
    CON
    
      SCL           = 28
      SDA           = 29
      WR_DATA       = 0
      RD_DATA       = 1
      ADC_RESULT    = %0011_0000
    
    DAT
    
                  mov       dira,debug_mask         'Add debug pins (I2C echo) to outputs.
    
                  '...
    
                  mov       acc,#WR_DATA            'Begin sample ADC from two pins.
                  call      #i2c_begin              '
                  mov       acc,#ADC_RESULT         '
                  call      #i2c_wr                 '
    
                  mov       acc,#RD_DATA            'Send read command.
                  call      #i2c_begin              '
    
                  call      #get_adc_ack            'Get first result.
    
                  '...
    
                  call      #get_adc_nak            'Get second result.
                  call      #i2c_stop
    
                  '...
    
    get_adc_ack   test      $,#1 wz                 'Set NZ for ACK after second byte.
                  jmp       #get_adc
    
    get_adc_nak   test      $,#0 wz                 'Set Z for NAK after second byte.
    
    get_adc       call      #i2c_rd_ack             'Read high byte with ACK.
                  mov       adc_data,acc            'Save result in adc_data,
                  shl       adc_data,#8             '  and shift it left.
            if_nz call      #i2c_rd_ack             'Read low byte with ACK or NAK
            if_z  call      #i2c_rd_nak             '
                  or        adc_data,acc            'OR into result.
                  shr       adc_data,#2             'Shift right by unused bits.
                  and       adc_data,ten_bits       'AND with $3ff.
    get_adc_ack_ret                                 'Return
    get_adc_nak_ret                                 '
                  ret                               '
    
    '-----------[ i2c routines ]--------------------------------------------------
    
    'i2c_waddr: Begin an ADC transaction. On call, acc is 0 for write, 1 for read.
    
    i2c_begin     call      #i2c_start              'Do start condition.
                  or        acc,#%010_0001_0        'Get write address command in acc.
                  call      #i2c_wr                 'Send it.
            if_c  jmp       #i2c_begin              'Restart if not acknowledged (may be busy writing a page).
    
    i2c_begin_ret ret
    
    'i2c_rd_nak: Read a byte from ADC and send NAK.
    
    i2c_rd_nak    test      $,#1 wc                 'Set carry flag (odd parity) for NAK.
                  jmp       #i2c_rd
    
    'i2c_rd_ack: Read a byte from ADC and send ACK.
    
    i2c_rd_ack    test      $,#0 wc                 'Clear carry flag (even parity) for ACK.
    
    'i2c_rd: Read a byte from ADC and send ACK/NAK based on carry.
    
    i2c_rd        mov       acc,#$ff                'Make sure no zeroes get written.
                  jmp       #i2c_rd_wr
    
    'i2c_wr: Write a byte to ADC, returning ACK in carry.
    
    i2c_wr        test      $,#1 wc                 'Set carry flag (odd parity) to read ACK.
    
    'i2c_byte: Combo read and write byte routine.
    
    i2c_rd_wr     mov       count,#9                'Nine bits, including ACK.
                  rcl       acc,#24                 'Get byte into 8 MSBs, and ACK/NAK into next bit.
    
    :wrlp         rcl       acc,#1 wc               'Rotate carry into acc and next write bit out.
                  muxnc     dira,sda_pin            'Pull sda low iff carry is clear.
                  call      #i2c_pace               'Wait.
                  andn      dira,scl_pin            'Set SCL high.
                  call      #i2c_pace               'Wait.
                  test      sda_pin,ina wc          'Get SDA pin state into carry (parity). (Last time is ACK/NAK.)
                  or        dira,scl_pin            'Drive SCL low.
                  call      #i2c_pace               'Wait.
                  djnz      count,#:wrlp            'Back for next bit.
    
                  and       acc,#$ff                'Acc has data read from i2c; carry has ACK/NAK.
    i2c_rd_ack_ret
    i2c_rd_nak_ret
    i2c_rd_ret
    i2c_wr_ret    ret
    
    'i2c_start: Set a start condition.
                
    i2c_start     andn      dira,sda_pin            'Set SDA high.
                  call      #i2c_pace               'Wait.
                  andn      dira,scl_pin            'Set SCL high.
                  call      #i2c_pace               'Wait.
                  or        dira,sda_pin            'Pull sda low.
                  call      #i2c_pace               'Wait.
                  or        dira,scl_pin            'Drive SCL low.
                  call      #i2c_pace               'Wait.
    i2c_start_ret ret
    
    'i2c_stop: Set a stop condition.
    
    i2c_stop      or        dira,scl_pin            'Pull SCL low.
                  call      #i2c_pace               'Wait.
                  or        dira,sda_pin            'Pull sda low.
                  call      #i2c_pace               'Wait.
                  andn      dira,scl_pin            'Set SCL high.
                  call      #i2c_pace               'Wait.
                  andn      dira,sda_pin            'Set SDA high.
                  call      #i2c_pace               'Wait.
    i2c_stop_ret  ret
    
    '-------[ Delay routine. ]------------------------------------------------------
    
    'i2c_pace: Keep speed within specs and echo pin states to P12 & 13 for scope monitoring.
    
    i2c_pace      nop
                  nop
                  nop
                  nop
    
                  mov       debug,ina               'Echo pins 28 & 29 to 12 & 13              
                  shr       debug,#16               '
                  xor       debug,outa              '
                  and       debug,debug_mask        '
                  xor       outa,debug              '
                  
    i2c_pace_ret  ret
    
    '-------[ Constants and variables. ]-------------------------------------------
    
    debug_mask    long      3 << 12
    sda_pin       long      1 << SDA
    scl_pin       long      1 << SCL
    ten_bits      long      $03ff
    
    acc           res       1
    adc_data      res       1
    count         res       1
    debug         res       1              
    

    I should add that, although the datasheet is complete and accurate, it's terse to a fault. It took me quite awhile to figure out how to read the results. Also, I discovered that the PropBOE has nowhere handy to probe the SCL and SDA pins, so I added an echo function to P12 & P13, so I could see what was going on with my scope. If you don't use this facility, just replace the echo lines with nops or some other equivalent delay.

    BTW, the amount of delay seems large for the ADC chip's stated specs, but I suspect it's because the PropBOE uses 10K pull-ups. They should be 3.3K or less for reasonable clock speeds at 3.3V.

    -Phil
  • Martin_HMartin_H Posts: 4,051
    edited 2012-10-01 13:50
    Phil, thanks! I'll see if I can get this working tonight.
  • David BetzDavid Betz Posts: 14,516
    edited 2012-10-01 15:30
    Okay, I guess you don't really need the output from compiling my COG C code. I'm sure Phil's code is far easier to read! :-)
  • Martin_HMartin_H Posts: 4,051
    edited 2012-10-01 19:46
    The good news:

    * I can read the ADC using the Simple ADC test and I know it is working because I changed the voltage into the ADC and saw it reflected in the output.

    * I removed all the sigma delta stuff from the TSL1401 driver and the adc code did nothing. But I could attach the TSL1401_monitor_simple.exe and produce a flat line. So the bones of the program is working.

    The bad news:

    * I added in the I2C ADC code and it terminates execution and it's clear I'm in over my head as I don't really understand it well enough to know if it looks right or wrong.
    {
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                  TSL1401-DB_driver.spin                  &#9474;
    &#9474;(c) Copyright 2010 Philip C. Pilgrim (propeller@phipi.com)&#9474;
    &#9474;            See end of file for terms of use.             &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    
    This object provides a TSL1401-DB driver for the Propeller Backpack.
    
    Version History
    &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;
    2010.03.01: Initial release
    
    }
    
    CON
    
      AOpin         = 0
      SIpin         = 1
      CLKpin        = 2
      SCL           = 28
      SDA           = 29
      WR_DATA       = 0
      RD_DATA       = 1
      ADC_RESULT    = %0011_0000
    
      MAXARGS       = 7
    
      #1, cmdSNAP, cmdGETPIX, cmdGETSTATS, cmdSETEXP
    
    VAR
    
      byte cog
      long command[MAXARGS+1], clk_mult  
    
    PUB start
    
    '' Start the driver.
    
      stop
      exp_time := clkfreq / 120
      clk_mult := clkfreq * 10 / 2441
      command~~
      if (result := (cog := cognew(@tsl1401, @command) + 1))
        repeat while command
    
    PUB stop
    
    '' Stop the driver.
    
      if cog
        cogstop(cog - 1)
        cog~
    
    PUB snap
    
    '' Snap a picture.
    
      _command(cmdSNAP)
    
    PUB getpix(addr)
    
    '' Transfer the pixels to a long-aligned 128-byte array at addr.
    
      command[1] := addr
      _command(cmdGETPIX)
    
    PUB getstats
    
    '' Return stats from the last snap, packed in a single long as:
    ''
    ''  31    24 23    16 15     8 7      0
    '' &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    '' &#9474; MaxLoc &#9474; MinLoc &#9474; MaxPix &#9474; MinPix &#9474; , where
    '' &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    ''
    '' MinPix is the value (1 - 255) of the darkest pixel,
    '' MaxPix is the value (1 - 255) of the brightest pixel,
    '' MinLoc is the index (0 - 127) of the darkest pixel, and
    '' MaxLoc is the index (0 - 127) of the brightest pixel.
    
      _command(cmdGETSTATS)
      return command[1]
    
    PUB setexp_us(exptime_us)
    
    '' Set the exposure time to exptime_us microseconds (20 us min for 80 MHz clock).
    
      setexp((exptime_us * clk_mult) >> 12)
    
    PUB setexp(exptime)
    
    '' Set the exposure time to exptime system clock ticks (from 1600 to ?).
    
      command[1] := exptime #> 1600
      _command(cmdSETEXP)
    
    PRI _command(cmd)
    
      command := cmd
      repeat while command
    
    DAT
                  org       0
    tsl1401       mov       dira,dira0              'Set the pins that are outputs.
                  call      #flush                  'Clear the TSL1401, to make sure AO is tristated.
    
    :got_it       andn      dira,AOmask             'Done calibrating. Make AO pin an input.
                  sub       clk_period,intvl        'Adjust clk_period. Remainder is "soak time".
    
    get_cmd       wrlong    zero,par                'Zero the command, so caller knows we're ready.
    
    wait_cmd      rdlong    acc,par wz              'Get the next command.
            if_z  jmp       #wait_cmd               'Keep checking if zero.
    
                  cmp       acc,#cmdSNAP wz         'Jump table for commands.
            if_z  jmp       #do_snap
    
                  cmp       acc,#cmdGETPIX wz
            if_z  jmp       #do_getpix
    
                  cmp       acc,#cmdGETSTATS wz
            if_z  jmp       #do_getstats
    
                  cmp       acc,#cmdSETEXP wz
            if_z  jmp       #do_setexp
    
                  jmp       #get_cmd                'Command didn't match anything, so try again.
    
    'Expose and capture a scan.
    
    do_snap       call      #flush                  'Flush the pixels, and begin a new exposure.
                  add       exp_start,exp_time      'Add the exposure time to the start time.
                  waitcnt   exp_start,#0            'Wait for exposure to complete.
                  or        outa,SImask             'Start clocking out pixels.
                  or        outa,CLKmask
                  andn      outa,SImask
                  andn      outa,CLKmask
                  mov       time,cnt                'Set up timer for pixel rate.
                  add       time,clk_period
                  mov       pixno,#0                'Initialize the pixel index.
                  mov       longcnt,#32             'Initialize the longs count.
                  movd      :putpix,#cogpixels      'Point to the beginning of the cog pixel array.
                  mov       maxpix,#0               'Initialize brightest and darkest pixels.
                  mov       minpix,#255
    
    :lp0          mov       pixcnt,#4               'Outer loop: Initialize pixel count.
    
    :lp1          call      #adc                    'Inner loop: Sample four pixels and pack in long. Get pix value.
                  or        outa,CLKmask            'Clock to next pixel.
                  andn      outa,CLKmask
                  sub       acc,loresult            'Subtract the zero reference.            
                  mins      acc,#1                  'Make sure result is between 1 (yes 1, not 0)
                  maxs      acc,#255                '  and 255.
                  min       maxpix,acc wc           'Is this the biggest pixel so far?
            if_c  mov       maxloc,pixno            '  Yes: Mark the location.
                  max       minpix,acc wc           'Is this the smallest pixel so far?
            if_nc mov       minloc,pixno            '  Yes: Mark the location.
                  add       pixno,#1                'Increment the pixel index.
                  shr       pix_long,#8             'Shift the long value right by a byte.
                  shl       acc,#24                 'Shift teh pixel value left by three bytes.
                  or        pix_long,acc            'Squish 'em together.
                  djnz      pixcnt,#:lp1            'Back for another pixel.
    
    :putpix       mov       0-0,pix_long            'Four bytes are packed. Save the long.
                  add       :putpix,inc_dest        'Increment the destination address.
                  djnz      longcnt,#:lp0           'Back for another four pixels.
    
                  jmp       #get_cmd                'Done: tell the caller.
    
    'Transfer the cog pixel array to the hub.
    
    do_getpix     mov       acc,#1                  'Get the hub destination address.
                  call      #get_parms
                  movd      :getpix,#cogpixels      'Point to the cog pixel array.
                  mov       pixcnt,#32              'Transferring 32 longs.
    
    :getpix       wrlong    0-0,params              'Transfer a long (four pixels).
                  add       params,#4               'Index the hub address.
                  add       :getpix,inc_dest        'Index the cog address.
                  djnz      pixcnt,#:getpix         'Back for another.
    
                  jmp       #get_cmd                'Done.
    
    'Return the stats to the hub via the first param.
    
    do_getstats   mov       acc,maxloc              'Pack four byte-size stats into a long.
                  shl       acc,#8
                  or        acc,minloc
                  shl       acc,#8
                  or        acc,maxpix
                  shl       acc,#8
                  or        acc,minpix
                  mov       ptr,par
                  add       ptr,#4
                  wrlong    acc,ptr                 'Write it to the parameter array.
                  jmp       #get_cmd                'Done.
    
    'Set the exposure time.
    
    do_setexp     mov       acc,#1                  'Get the exposure time parameter.
                  call      #get_parms              
                  mov       exp_time,params         'Save it to the exp_time variable.
                  jmp       #get_cmd                'Done.
    
    'Do a quick flush of the TSL1401 to clear the pixels and start a new exposure.
    
    flush         andn      outa,CLKmask            'Make sure the clock is low to start.
                  
                  or        outa,SImask             'Start the transfer.
                  or        outa,CLKmask
                  andn      outa,SImask
                  andn      outa,CLKmask
                  mov       acc,#17
                  
    :lp0          or        outa,CLKmask            'Clock out 17 pixels.
                  andn      outa,CLKmask
                  djnz      acc,#:lp0
                  
                  mov       exp_start,cnt           'New exposure start now.
                  mov       acc,#112
                  
    :lp1          or        outa,CLKmask            'Clock out 112 more pixels.
                  andn      outa,CLKmask
                  djnz      acc,#:lp1
                                
    flush_ret     ret                               'Done.
    
    'Get the analog value on pin AO.
    
    adc           mov       acc,#WR_DATA            'Begin sample ADC from two pins.
                  call      #i2c_begin              '
                  mov       acc,#ADC_RESULT         '
                  call      #i2c_wr                 '
    
                  mov       acc,#RD_DATA            'Send read command.
                  call      #i2c_begin              '
    
                  call      #get_adc_ack            'Get first result.
                  call      #get_adc_nak            'Get second result.
                  call      #i2c_stop
    adc_ret       ret                               'Done.
    
    'Get parameter(s) for current operation.
    
    get_parms     movd      :get_par,#params        'Point to cog parameter array.
                  mov       ptr,par                 'Point to command in hub.
    
    :lp           add       ptr,#4                  'Increment to point to next parameter.
    :get_par      rdlong    0-0,ptr                 'Get it.
                  add       :get_par,inc_dest       'Point to next cog location.
                  djnz      acc,#:lp                'Get only as many as requested.
    
    get_parms_ret ret                               'Done.
    
    '-----------[ adc routines ]--------------------------------------------------
    
    get_adc_ack   test      $,#1 wz                 'Set NZ for ACK after second byte.
                  jmp       #get_adc
    
    get_adc_nak   test      $,#0 wz                 'Set Z for NAK after second byte.
    
    get_adc       call      #i2c_rd_ack             'Read high byte with ACK.
                  mov       adc_data,acc            'Save result in adc_data,
                  shl       adc_data,#8             '  and shift it left.
            if_nz call      #i2c_rd_ack             'Read low byte with ACK or NAK
            if_z  call      #i2c_rd_nak             '
                  or        adc_data,acc            'OR into result.
                  shr       adc_data,#2             'Shift right by unused bits.
                  and       adc_data,ten_bits       'AND with $3ff.
    get_adc_ack_ret                                 'Return
    get_adc_nak_ret                                 '
                  ret 
    
    '-----------[ i2c routines ]--------------------------------------------------
    
    'i2c_waddr: Begin an ADC transaction. On call, acc is 0 for write, 1 for read.
    
    i2c_begin     call      #i2c_start              'Do start condition.
                  or        acc,#%010_0001_0        'Get write address command in acc.
                  call      #i2c_wr                 'Send it.
            if_c  jmp       #i2c_begin              'Restart if not acknowledged (may be busy writing a page).
    
    i2c_begin_ret ret
    
    'i2c_rd_nak: Read a byte from ADC and send NAK.
    
    i2c_rd_nak    test      $,#1 wc                 'Set carry flag (odd parity) for NAK.
                  jmp       #i2c_rd
    
    'i2c_rd_ack: Read a byte from ADC and send ACK.
    
    i2c_rd_ack    test      $,#0 wc                 'Clear carry flag (even parity) for ACK.
    
    'i2c_rd: Read a byte from ADC and send ACK/NAK based on carry.
    
    i2c_rd        mov       acc,#$ff                'Make sure no zeroes get written.
                  jmp       #i2c_rd_wr
    
    'i2c_wr: Write a byte to ADC, returning ACK in carry.
    
    i2c_wr        test      $,#1 wc                 'Set carry flag (odd parity) to read ACK.
    
    'i2c_byte: Combo read and write byte routine.
    
    i2c_rd_wr     mov       count,#9                'Nine bits, including ACK.
                  rcl       acc,#24                 'Get byte into 8 MSBs, and ACK/NAK into next bit.
    
    :wrlp         rcl       acc,#1 wc               'Rotate carry into acc and next write bit out.
                  muxnc     dira,sda_pin            'Pull sda low iff carry is clear.
                  call      #i2c_pace               'Wait.
                  andn      dira,scl_pin            'Set SCL high.
                  call      #i2c_pace               'Wait.
                  test      sda_pin,ina wc          'Get SDA pin state into carry (parity). (Last time is ACK/NAK.)
                  or        dira,scl_pin            'Drive SCL low.
                  call      #i2c_pace               'Wait.
                  djnz      count,#:wrlp            'Back for next bit.
    
                  and       acc,#$ff                'Acc has data read from i2c; carry has ACK/NAK.
    i2c_rd_ack_ret
    i2c_rd_nak_ret
    i2c_rd_ret
    i2c_wr_ret    ret
    
    'i2c_start: Set a start condition.
                
    i2c_start     andn      dira,sda_pin            'Set SDA high.
                  call      #i2c_pace               'Wait.
                  andn      dira,scl_pin            'Set SCL high.
                  call      #i2c_pace               'Wait.
                  or        dira,sda_pin            'Pull sda low.
                  call      #i2c_pace               'Wait.
                  or        dira,scl_pin            'Drive SCL low.
                  call      #i2c_pace               'Wait.
    i2c_start_ret ret
    
    'i2c_stop: Set a stop condition.
    
    i2c_stop      or        dira,scl_pin            'Pull SCL low.
                  call      #i2c_pace               'Wait.
                  or        dira,sda_pin            'Pull sda low.
                  call      #i2c_pace               'Wait.
                  andn      dira,scl_pin            'Set SCL high.
                  call      #i2c_pace               'Wait.
                  andn      dira,sda_pin            'Set SDA high.
                  call      #i2c_pace               'Wait.
    i2c_stop_ret  ret
    
    '-------[ Delay routine. ]------------------------------------------------------
    
    'i2c_pace: Keep speed within specs and echo pin states to P12 & 13 for scope monitoring.
    
    i2c_pace      nop
                  nop
                  nop
                  nop
    
                  mov       debug,ina               'Echo pins 28 & 29 to 12 & 13              
                  shr       debug,#16               '
                  xor       debug,outa              '
                  and       debug,debug_mask        '
                  xor       outa,debug              '
                  
    i2c_pace_ret  ret
    
    'Constants and pre-initialized variables.
    debug_mask    long      3 << 12
    sda_pin       long      1 << SDA
    scl_pin       long      1 << SCL
    ten_bits      long      $03ff
    
    exp_time      long      0-0
    'ctra0         long      %01001 << 26 | AOfb << 9 | AOadc
    dira0         long      1 << SIpin | 1 << CLKpin  | debug_mask
    AOmask        long      1 << AOpin
    SImask        long      1 << SIpin
    CLKmask       long      1 << CLKpin
    intvl0        long      1024
    inc_dest      long      512
    clk_period    long      2000
    zero          long      0
    
    'Variables.
    
    intvl         res       1
    dintvl        res       1
    loresult      res       1
    acc           res       1
    pixcnt        res       1
    longcnt       res       1
    pixno         res       1
    ptr           res       1
    time          res       1
    exp_start     res       1
    cogpixels     res       32
    minpix        res       1
    maxpix        res       1
    minloc        res       1
    maxloc        res       1
    params        res       8
    pix_long      res       0
    
    adc_data      res       1
    count         res       1
    debug         res       1
    
    {{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                                                   TERMS OF USE: MIT License                                                  &#9474;                                                            
    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
    &#9474;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    &#9474; 
    &#9474;files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    &#9474;
    &#9474;modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software&#9474;
    &#9474;is furnished to do so, subject to the following conditions:                                                                   &#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          &#9474;
    &#9474;WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         &#9474;
    &#9474;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   &#9474;
    &#9474;ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    }} 
    
  • Martin_HMartin_H Posts: 4,051
    edited 2012-10-02 06:11
    After fiddling around with Prop GCC and looking at some of the examples I think I'm going to try a port of the Spin and PASM to C. I think I have a better chance working in a language I know (C) than I language I only get the gist of PASM.

    David, do you have some C I2C routines or are they included in an example with Prop GCC?
  • David BetzDavid Betz Posts: 14,516
    edited 2012-10-02 06:15
    Martin_H wrote: »
    After fiddling around with Prop GCC and looking at some of the examples I think I'm going to try a port of the Spin and PASM to C. I think I have a better chance working in a language I know (C) than I language I only get the gist of PASM.

    David, do you have some C I2C routines or are they included in an example with Prop GCC?
    Here is the source to the ADC code I've been working on. I'm trying to make a library so most of the interesting code is in either the libsrc directory or the drivers directory. The main directory only contains a test program and the Makefile. Let me know if you have any questions.
    adc.zip 18.9K
  • Martin_HMartin_H Posts: 4,051
    edited 2012-10-02 06:23
    Thanks a bunch David. I'll try it tonight.
  • Martin_HMartin_H Posts: 4,051
    edited 2012-10-02 18:43
    As an aside I figured out where the PASM I2C was getting stuck. In function i2c_begin after the return from i2c_wr, it loops back to i2c_begin if the carry bit is set. The write command never sets the carry bit, so it loops forever.
    i2c_begin     call      #i2c_start              'Do start condition.
                  or        acc,#%010_0001_0        'Get write address command in acc.
                  call      #i2c_wr                 'Send it.
            if_c  jmp       #i2c_begin              'Restart if not acknowledged (may be busy writing a page).
    
    
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2012-10-02 19:09
    Martin,

    It's up to the slave device to pull SDA low, signalling an ACK condition after a write, which causes C to be cleared in i2c_rd_wr (called by i2c_wr). If it does not, it's up to the master to keep trying.The code I posted works. If it gets stuck in this loop, it means that something else has gone wrong.

    -Phil
  • Martin_HMartin_H Posts: 4,051
    edited 2012-10-03 03:28
    Phil, I am just pleased I was able to debug PASM enough to figure out where it was getting stuck.

    I used the Prop BOE Spin object with the ADC and it does work, but apparently not with this code. The OBEX has a pure Spin TSL1401 object which I tried and it works, but it uses pin thresholding for binary output. I could interface it with the Prop BOE ADC Spin code, but I'm thinking that the results will perform poorly as all that Spin code starts to add up.

    What I will probably do tonight is go back to the Propeller Backpack and have the Prop BOE consume its output like I was doing with the BS2. I thought it would be neat to use the Prop BOE's built in facilities, but I know the Prop backpack will do the trick.

    Propgcc has promise too, but there's a learning curve there which is more of a long term strategy than short term.
  • Martin_HMartin_H Posts: 4,051
    edited 2012-10-03 18:03
    For the heck of it I did a pure Spin port of Phil's TSL1401 driver program using John Absheir's OBEX camera code, and the Prop BOE ADC object example. As expected it is slow and does about 3 frames per second. However, it does work and provides analog output which is compatible with Phil's TSL1401_monitor_simple.exe. The dynamic range isn't quite as good as the Prop backpack which could be how I'm calculating exposure time, or reducing a 10 bit ADC value into a byte.
    {
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                  TSL1401-DB_driver.spin                  &#9474;
    &#9474;(c) Copyright 2010 Philip C. Pilgrim (propeller@phipi.com)&#9474;
    &#9474;(c) Copyright 2012 John Abshier from OBEX Spin object     &#9474; 
    &#9474;(c) Copyright 2012 Martin C Heermance                     &#9474;
    &#9474;            See end of file for terms of use.             &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    
    This object provides a TSL1401-DB driver for the Propeller BOE which
    is interface compatible with Phil Pi's binary driver. It uses some
    Spin code from John Absheir to clock in the pixels with my own code
    to call the Prop BOE's ADC.
    
    Version History
    &#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;
    2010.03.01: Initial release
    2012.10.03: Ported to a pure Spin version to allow calling Prop BOE's ADC.
    }
    
    CON
    
    OBJ
    
      adc    : "PropBOE ADC"                               ' A/D Converter on PropBOE
    
    VAR
    
      long clk_mult
      long exp_time
      byte cogpixels[128]           ' buffer for image.
      long adcPin                   ' camera analog output, si, clock and LED control pins
      long siPin
      long clkPin
      long ledPin
      long ms                       ' clock cycles for 1 ms
      long expTimeCorr              ' expTime correction for Spin timing overhead
      byte minpix
      byte maxpix
      byte minloc
      byte maxloc
    
    PUB start (ao, si, clk, led)
    
    '' Start the driver.
      adcPin := ao
      siPin := si
      clkPin := clk
      ledPin := led
    
      dira[siPin]~~
      dira[clkPin]~~
      dira[ledPin]~~
      outa[siPin]~
      outa[clkPin]~
      outa[ledPin]~~
      
      clk_mult := clkfreq * 10 / 2441
      setexp_us(100000)                         ' default to a 1/10 sec exposure
      expTimeCorr := 240_000_000 / clkfreq      ' adjust expTimeCorr for different clock frequencies
    
    PUB stop
    
    
    PUB snap | i, pixel
    
    '' Snap a picture.
      longfill(@cogpixels,0,32)                 ' zero image array
    
      outa[siPin]~~                             ' start exposure interval
      outa[clkPin]~~
      outa[siPin]~
      outa[clkPin]~
      repeat 256                                ' clock out pixels for one shot
        !outa[clkPin]
      outa[clkPin]~
    
      waitcnt(exp_time + cnt)                   ' wait exposure time
      outa[siPin]~~                             ' end exposure
      outa[clkPin]~~
      outa[siPin]~
      outa[clkPin]~
      pixel := adc.In(adcPin) >> 2              ' 10 bits returned, but we only want 8
      cogpixels[0] := pixel
    
        ' Initialize the statistics
      minpix := pixel
      maxpix := pixel
      minloc := 0
      maxloc := 0
    
      repeat i from 1 to 127
        outa[clkPin]~~                          ' high
        pixel := adc.In(adcPin) >> 2            ' 10 bits returned, but we only want 8
        cogpixels[i] := pixel
        outa[clkPin]~
    
        if pixel > maxpix
          maxloc := i
          maxpix := pixel
    
        if pixel < minpix
          minloc := i
          minpix := pixel
    
    PUB getpix(addr)
    
    '' Transfer the pixels to a long-aligned 128-byte array at addr.
      bytemove(addr, @cogpixels, 128)
    
    PUB getstats
    
    '' Return stats from the last snap, packed in a single long as:
    ''
    ''  31    24 23    16 15     8 7      0
    '' &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9516;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    '' &#9474; MaxLoc &#9474; MinLoc &#9474; MaxPix &#9474; MinPix &#9474; , where
    '' &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9524;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    ''
    '' MinPix is the value (1 - 255) of the darkest pixel,
    '' MaxPix is the value (1 - 255) of the brightest pixel,
    '' MinLoc is the index (0 - 127) of the darkest pixel, and
    '' MaxLoc is the index (0 - 127) of the brightest pixel.
      return   (maxloc << 24) | (minloc << 16) | (maxpix << 8) | minpix
    
    Pub ledOn
    {{ Turns LED connected to mezzanine connector on.  As you look at the camera use the bottom center and
       right sockets }} 
      outa[ledPin]~
    
    Pub ledOff
    {{ Turns LED connected to mezzanine connector off }} 
      outa[ledPin]~~
    
    PUB setexp_us(exptime_us)
    
    '' Set the exposure time to exptime_us microseconds (20 us min for 80 MHz clock).
    
      setexp((exptime_us * clk_mult) >> 12)
    
    PUB setexp(exptime)
    
    '' Set the exposure time to exptime system clock ticks (from 1600 to ?).
      exp_time := exptime  - expTimeCorr      ' Reduce for program overhead
    
    {{
    &#9484;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9488;
    &#9474;                                                   TERMS OF USE: MIT License                                                  &#9474;
    &#9500;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9508;
    &#9474;Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    &#9474;
    &#9474;files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    &#9474;
    &#9474;modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software&#9474;
    &#9474;is furnished to do so, subject to the following conditions:                                                                   &#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.&#9474;
    &#9474;                                                                                                                              &#9474;
    &#9474;THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          &#9474;
    &#9474;WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         &#9474;
    &#9474;COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   &#9474;
    &#9474;ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         &#9474;
    &#9492;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9472;&#9496;
    }}
    

    My crazy idea is to use spin2cpp to port this code to GCC and then obtain a speed up that way.
  • borisgborisg Posts: 39
    edited 2013-07-08 00:29
    Hi Phil.
    I seem to be one of the lucky people who has a BOE where the adc I2C address is %010_0001 instead of the expected %010_0011. Fortunately I found someone else who had the same problem on the forums and I've got the Spin version of the A/D code working but I can't figure out where I'd make changes in your Pasm code. I've entered the code and your debugging lines show what looks to be normal I2C clock and data on my Propscope except that there's no output returned by the program. Presumably your code was written under the assumption that the I2C address of the A/D was %010_0011.

    I'm sure if I spent a few hours slogging through your code I'd be able to figure this out, but after losing 3 days on what was supposed to be a really easy part of my current project I just can't afford to.

    Thanks,
    Boris
Sign In or Register to comment.