Friday, February 17, 2012

arrayForth notes #6 - Improved PCF2123 SPI Code

There were a lot of errors in the note #4 listing. I made the post mainly because I was excited to see commands fly between the PCF2123 and GA144 as viewed by a logic analyzer (even though spir8 didn't really work correctly). So, here is where I clean up the code, refactor it a bit and offer something a little more functional. I could go on for pages the rationale I had behind why this code lives in Node 7 and 8 and how I hooked up the chip. But, that is for another time. I hate having broken code posted to my blog, so this post is mainly a means to offer something that works. BTW, this runs on the eval board target chip. It still has some inefficiencies (compared to the GreenArray supplied SPI code), but by doing this myself (essentially a "clean room" implementation), I got to learn a lot more about how to code the GA144.

this is a brutally simple interface for a spi
cr
pin 1 - chip select cr
pin 3 - clock cr
pin 5 - mosi cr
pin 17 - miso cr
cr
/spi call first. main loop .
ckwait
pauses for an effective rate of 2mhz cr
-ckwait asserts the clock line low for 2mhz cr
cs asserts the chip select line high cr
-cs asserts the chip select line low cr
                                              

   850 list
todd's simple spi code cr
8 node 0 org cr
/spi @ push ex . /spi ;
ckwait
02 4A for unext ; approx. 2mhz cr
-ckwait 05 2B !b ckwait ;
cs
07 io b! -ckwait ;
-cs
0A 29 !b ;
spiw1
0C if drop 10 then 2F or !b ckwait -ckwa
it ;

spiw8
13 b- 80 7 for over over and spiw1 2/ ne
xt drop drop ;

spir1
1A -b @b . -if drop - 2* - ; then drop 2
* ;

spir8
1E -b 0 7 for 0 spiw1 spir1 next 2/ ; cr
26                                            


nxp pcf2123 calendar clock module.
/pcf2123
initializes the pcf2123 clock cr
rdt reads date and time
sdt
sets data and time port the cr
                                              

   852 list
7 node 0 org cr
/cs 00 left a! @p .. cs ! ;
cs/
04 @p .. -cs ! ;
put
07 d- @p .. @p .. ! ! ;
get
0A -d @p .. !p .. ! @ ;
spiw
0D put @p .. spiw8 ! ;
spir
11 @p .. spir8 ! get ;
/pcf2123
14 @p .. /spi ! /cs 10 spiw 58 spiw c
s/ ;

rdt
1C -smhwdmy /cs 92 spiw spir spir spir spi
r spir spir spir cs/ ;

sdt
27 ymdwhms- /cs 12 spiw spiw spiw spiw spi
w spiw spiw spiw cs/ ;

testdate
32 12 11 10 9 8 7 6 sdt ; cr
3C                                            

Wednesday, February 15, 2012

arrayForth notes #5 - Observations and hints

I've since improved the code in the previous entry. I've slimmed it down to 59 words (out of a max of 64). I am not sure I can get it small enough to include the wiring, but I'll look further at exemplar SPI code in the baseline for some more slimming tricks. One thing I am noticing is that literals (numbers) are very expensive. Each literal takes a whole word (18 bit cell) of RAM. This is the reason for such non-intuitive tricks as "dup or" instead of coding the literal "0". "Dup or" doesn't take up a whole RAM cell, so it can be packed with other instructions. Calls take up quite a bit of space too. If your word is shorter than a single 18 bit cell, you will do better just coding it inline rather than do a word call. Programming the GA144 in arrayForth means that you must become an expert in how words are compiled. You can escape this by using polyForth or eForth, but you lose the benefit of understanding how the GA144 actually works. I am still trying to get my arms around wiring, but I remain convinced that the true strength of the GA144 is basically as an FPGA killer for simple concurrent processes. Whereas the strength of a Silabs 8051 or ARM Cortex M is in the richness of peripherals, the GA144 doesn't benefit much from peripherals. It is an FPGA level Erlang. And, like Erlang, it has specific strengths. It's biggest strength is power efficient massive concurrency. I would like to see more I/O, but that only lulls me into the traditional concurrency perspective. I need to stop thinking about having dozens of sensors outputs tied to dozens of GA144 inputs. This isn't a strength. Most assuredly , it is my ability to model dozens of sensors concurrently without dealing with interrupts or global state machines -- that is it's biggest strength.

Tuesday, February 14, 2012

arrayForth notes #4 - PCF2123 SPI Code

This is brutally tight code. It is not the most efficient code, but it does fit in 1 node (unfortunately, there is no room for "plumbing" -- so it will most likely need to be refactored into 2 nodes).

The code can be exercised (by the IDE), by using "call" to invoke /pcf2123 for initialization, sdt to set the date and rdt to read the date.  Values for "sdt" can be pushed onto the node's stack by using "lit".  I used a logic analyzer to look at the results.

There was a lot of setup to get this going, and I am not going to cover that right now.

I need to get the plumbing (wiring) right. Getting 1 node to talk to another is not as intuitive as I hoped. I also fear that the IDE gets critically in the way (hook et al can wipe out your node's RAM when creating paths).  This will mean that the IDE will be less useful for stuff that is very node position dependent (i.e. GPIO nodes).

I don't fully grok the inter-node comms yet. In particular, I am not sure how to "push" numbers from one node to another.  The IDE does this fine with "lit", but if my node isn't wired by the IDE all I have is "warm/await".  The apparent exemplar for passing values between nodes is to explicitly have the target node "fetch" values from the port. Unfortunately, as you can see from the code below, I am out of room (0x40 max words per node and I am at 0x3d).  I could shrink the code a bit more, but...

this is a brutally simple interface for the cr
nxp pcf2123 calendar clock module. cr
pin 1 - chip select cr
pin 3 - clock cr
pin 5 - mosi cr
pin 17 - miso cr
cr
ckwait pauses for an effective rate of 2mhz cr
-ckwait asserts the clock line low for 2mhz cr
cs asserts the chip select line high cr
-cs asserts the chip select line low cr
/pcf2123 initializes the pcf2123 clock cr
rdt reads date and time
sdt
sets data and time                        

   850 list
todd's simple pcf2123 clock code cr
8 node 0 org cr
ckwait 00 4A for unext ; approx. 2mhz cr
-ckwait 03 2B !b ckwait ;
cs
05 io b! -ckwait ;
-cs
07 29 !b ;
spiw1
09 if drop 10 then 2F . + !b ckwait -ckw
ait ;

spiw8
10 b- 80 7 for over over and spiw1 2/ ne
xt drop drop ;

spir8
17 -b 0 7 for 2* dup or spiw1 @b . -if d
rop
1 or dup then drop next 2/ ;
/pcf2123
21 cs 10 spiw8 58 spiw8 -cs ;
rdt
27 -smhwdmy cs 92 spiw8 spir8 spir8 spir8
spir8 spir8 spir8 spir8 -cs ;

sdt
32 ymdwhms- cs 12 spiw8 spiw8 spiw8 spiw8
spiw8 spiw8 spiw8 spiw8 -cs ;
cr
3D                                            

Wednesday, February 08, 2012

arrayForth notes #3 - SPI

I've finally begun to talk to the PCF2123 from the G144A12 eval board.  The SPI code is not space optimized, so just the basics are taking up  almost a full node. (More on that later).
So far, I've got "reset" and a register read working (return data not validated).  I am using Node 8 and it's 4 GPIO lines (for MOSI, MISO, CLOCK and ENABLE/CS).  The PCF2123 is odd in that CS active is high, not low. I've got a tight for unext loop pulse the CLOCK line at around 2Mhz:


In the above Saleae Logic screenshot, I am tracing two CS sessions:  First a "reset" (0x10 and 0x58), and then a request to read register 4. I am not sure the data returned is correct (yet), but the fact that I am getting something must mean that the device is happy with my query.  Unfortunately, my register read isn't returning the value 0x15 yet, but at least I know that my GPIO pin writes are working.

As I said above, just basic support of SPI is taking up precious space (currently the SPI routines take 36 words of RAM!). I am planning on doing some optimizing, but I think that the actual PCF2123 functionality will need to live in a separate node.

I have a business trip planned for the next couple of days, so if I don't get the SPI "read" working correctly tonight it will have to wait until the weekend. However, the plane ride and hotel stay will afford me some time to look into space optimization of the code and perhaps I will finally tackle the simulator.

And, yes! Code will be posted... once the damn thing works.


Tuesday, February 07, 2012

arrayForth notes Part 2

I'm trying to get my G144A12 Eval board to talk SPI to a  Calendar chip (NXP PCF2123).  I've managed to get a 2Mhz(ish) clock pulse running from Node 8 on the Target chip.  (I've picked the Target chip because I am overwhelmed with all of the stuff the Host chip is connected to -- I'm better at learning stuff from the ground up).

Unfortunately, I've been trying to get a test harness up and running in a different Node (9) and have been crashing the system every few minutes with my clumsy attempts at wiring and routing.  Documentation regarding wiring Nodes is much lacking.

I'm obviously very confused about node direction. I've been referring to "right" as "left". Looking down upon the Node map, I've been wondering why I couldn't get Node 9 to talk to Node 8.  Apparently, Node 8 is to the "right" of Node 9. So, I suppose I should imagine "lying down on my back" on a Node.

I'd like to get something going between the Calendar and the Eval board this week, but I am flying out of town for a couple of days for a business meeting.

I wonder how airport security would react to a bare eval board stuffed into my back pack? (and to say nothing of the reaction if I were to try and use it in flight ;-)

Friday, February 03, 2012

My smallest SMD solder job yet...

Components are getting too small.  For your consideration, a really neat sounding temperature sensor from TI: TMP104.  It features look nice: 

  • Accuracy: ±0.5°C Typ (–10°C to +100°C)
  • 3 μA Active IQ at 0.25 Hz
  • 1 μA Shutdown
  • SMAART Wire Interface
  • Temperature range of –40°C to +125°C
  • Package: 0.8-mm (±5%) × 1-mm (±5%) 4-Ball WCSP (BSBGA)
What's there not to like? Wait a minute... 0.8-mm x 1-mm 4-Ball BGA?  Damn.
Okay, so how small could that really be?  I ordered a couple and I got this:
Yeah, that's it next to a grain of rice. A long grain of rice.

So, I figured I have to give it a shot.  I need a decent temperature sensor for my project, so I whipped out the fine tip soldering iron and the thinnest strands of wire I could snip...

and this is the result.  Yeah, it's that little guy up top above the massive MCU.

Once again, for a little perspective:
A quick view under a 10x microscope and it looks solid (if not pretty). I put a couple of drops of Krazy glue to hold the wires down to keep it safe.

Unfortunately, it will take a while to make sure it works... I have to figure out this SMAART wire protocol thingy.