Anyone have examples of using the Prop Boe's ADC from PASM?
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.
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
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 1I 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
* 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.
{ ┌──────────────────────────────────────────────────────────┐ │ TSL1401-DB_driver.spin │ │(c) Copyright 2010 Philip C. Pilgrim (propeller@phipi.com)│ │ See end of file for terms of use. │ └──────────────────────────────────────────────────────────┘ This object provides a TSL1401-DB driver for the Propeller Backpack. Version History ─────────────── 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 '' ┌────────┬────────┬────────┬────────┐ '' │ MaxLoc │ MinLoc │ MaxPix │ MinPix │ , where '' └────────┴────────┴────────┴────────┘ '' '' 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 {{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ │is furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}David, do you have some C I2C routines or are they included in an example with Prop GCC?
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).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
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.
{ ┌──────────────────────────────────────────────────────────┐ │ TSL1401-DB_driver.spin │ │(c) Copyright 2010 Philip C. Pilgrim (propeller@phipi.com)│ │(c) Copyright 2012 John Abshier from OBEX Spin object │ │(c) Copyright 2012 Martin C Heermance │ │ See end of file for terms of use. │ └──────────────────────────────────────────────────────────┘ 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 ─────────────── 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 '' ┌────────┬────────┬────────┬────────┐ '' │ MaxLoc │ MinLoc │ MaxPix │ MinPix │ , where '' └────────┴────────┴────────┴────────┘ '' '' 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 {{ ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation │ │files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, │ │modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software│ │is furnished to do so, subject to the following conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.│ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE │ │WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR │ │COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │ │ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ }}My crazy idea is to use spin2cpp to port this code to GCC and then obtain a speed up that way.
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