Driver for TSL3301 line sensor (spin and asm)
Lawson
Posts: 870
Finally got around to objectifying this driver code for the Taos TSL3301 digital interface line sensor. All of this code is based off the "Using the TSL3301 with a Microcontroller.pdf" that can be found on Taos's product page for the TSL3301
"TSL3301_driver_spn_v1" is a spin driver that directly translates the pseudo code from the Taos .pdf.
"TSL3301_spn_demo" is a short spin program that will use the spin driver to capture line images from a TSL3301
"TSL3301_driver_v1" is a high speed assembly driver for the TSL3301. It can trigger off of an external pin and get the electronic shutter of the TSL3301 open in <500nS. (fully configurable) The minimum line integration time for the assembly code is ~2uS. (again configurable) Data readout from the chip takes ~172uS. The spin interface to assembly driver is different than to the spin driver. This driver is optimized to quickly grab individual lines. The maximum lines per second could be doubled (within limits) if the code was re-written to overlap data readout time and line optical integration time. I'd also say code optimizations should be able to get at least a 10% speed up in serial speed and response times. The assembly code could likely also be made much smaller.
I'd like comments and edits from the forum before I .zip all this up and submit it to the Object Exchange.
Lawson
"TSL3301_driver_spn_v1" is a spin driver that directly translates the pseudo code from the Taos .pdf.
"TSL3301_spn_demo" is a short spin program that will use the spin driver to capture line images from a TSL3301
"TSL3301_driver_v1" is a high speed assembly driver for the TSL3301. It can trigger off of an external pin and get the electronic shutter of the TSL3301 open in <500nS. (fully configurable) The minimum line integration time for the assembly code is ~2uS. (again configurable) Data readout from the chip takes ~172uS. The spin interface to assembly driver is different than to the spin driver. This driver is optimized to quickly grab individual lines. The maximum lines per second could be doubled (within limits) if the code was re-written to overlap data readout time and line optical integration time. I'd also say code optimizations should be able to get at least a 10% speed up in serial speed and response times. The assembly code could likely also be made much smaller.
I'd like comments and edits from the forum before I .zip all this up and submit it to the Object Exchange.
Lawson
Comments
Congrats! That's quite the tour de force! The TSL3301 is not an easy chip to drive and, frankly, I wasn't sure the Prop could do it as well as the SX. One thing that definitely helps is your clever use of phsa to generate the clock pulses.
Now that you've mastered it, what do you have planned for the TAOS sensor?
-Phil
Seems like it might be able to easily handle 3000 lines/sec which is what I'm chasing. I've ordered a 3301, will look at it in a week or so when it gets here.
keep up the great work!
tubular
What this TAOS sensor is doing is controlling a laser. The ability get a 2uS exposure ~500nS after a sync pulse is critical for this. Something the analog interface TAOS chips can't do.
Lawson
I think the limit is over 5000 lines/sec if you re-arrange the commands sent to the chip. (just shy of 6000 lines/sec would be reasonable if the read loop is accelerated to 10MHz) I.e. instead of starting an integration, waiting, ending the integration, and reading out data you would send the "READHoldNStart" macro command to end the integration, start data read out and start a new integration period. Or for a bit more elegance, you could re-write the code with a combo read/write function, and use the "READhold" command to start readout with the integration start command sent during the chip readout with a call to the read/write function. After that I wonder if the TSL3301 will overclock well if we run the Propeller on a 6.25MHz crystal?
Lawson
-Phil
My local rep appears to be located in the "Cayman Islands" - surely that can't be right?
-Phil
thanks
tubular
Lawson
Lawson
Thanks for your excellent work on the driver. Got it running in no time.
For the benefit of anyone else, here's how I broke out the (SMD) TSL3301 to a standard DIP8 socket, using fine 0.25mm wire on the back
Next step is to link it to the 160x120x64 greyscale driver
Is that 160x120x64 greyscale driver for VGA?
Lawson
Yes, the 64 grey is for VGA, using Kye's 160x120 driver (1 byte per pixel), with some different resistors. Details here
Had more play time with this and got the ASM version working nicely with Kye's 160x120x64 grey driver over the weekend. It was producing really nice images at 2500 lines/second (96MHz prop), and seemed to run at least to 4200 lines/second. These figures include copying the line scan across to the video buffer using spin to initiate CaptureFrame and GetFrameData(@videobufferoffset). So it could go even faster still.
I took some video, will post it when I get a moment.
I put a note in the obex because setting the external trigger pin > 31 doesn't do it (it still hangs on the WaitPEQ), but commenting it out frees things up.
Next is to integrate FSRW for dumping the video stream to uSD card. I figure it should be able to dump a good 60~110 minutes of video before hitting the 2GB fsrw limit.
cheers
tubular
The test subject is a music scale. Illumination is by 4 ultra bright white leds which are not very even (no diffuser).
I am moving the music past the sensor quickly and the music sheet is not necessarily flat so some parts of the image are out of focus some of the time, and in focus at other times.
Scan rate is something like 3000 lines/second
One advantage of the new compact TSL3301 in SMT form rather than DIP, is that it is much narrower, so I thought it may be worth trying 3 side by side under the same lens. With some red-green-blue filters on top colour may be possible. There may be some fade-out in the corners, we'll see.
Thanks for that note. I guess the "|<" operator only looks at the lower 5-bits of it's input. My intention was to set the "Q_sw_mask" variable to zero which should make the WAITPEQ effectively a NOP.
GetFrameData uses a BYTEMOVE, if you expand the destination buffer by 2 bytes and make sure it's long alligned a LONGMOVE might be slightly faster. The return value of CaptureFrame is the address of the line buffer.
If you upload a video to YouTube, etc. you should be able to insert a link into your post.
Nice scan of that sheet music! Hopefully you can fix the focus with a fixture to more accurately feed the sheets. Interesting idea with the parallel RGB array, love to see how that works out! Wonder how much of a speed hit reading from three chips in parallel will be?
Lawson
I think the only thing that would need to slow is the real time display - which is color limit anyway.
The alternative would be to rewrite the pasm to grab data from the sensors round robin, formatting it into color pixels as it goes (2x2x2 bits of color for each pixel). That would allow the display to keep up, since it would be a direct copy without translation, but not sure how much spare time there is in your pasm routines.
I think round robin readout per pixel would require independent clock lines due to how the chip works. Specifically, once the pixel readout is started, one clock gets you one bit of data or a stop/start bit. The chip allows pixel readout to be aborted early, but you loose the rest of the data.
Lawson
Thinking some more, this arrangement could work really well with a 18 bit RGB LCD for live display. P0/8/16 could be the inputs from the TSL3301s, and P2~7/10~15/18~23 could be set as outputs to drive the LCD. Once 24 bits of data has been shifted in, you just clock the LCD's DotClock to latch the data. Many LCDs can happily run at dotclocks in the low MHz.
Pins would run tight especially if SD card is also required, might be necessary to sacrifice some color depth.