etherforth_logo

Node 417

This node drives a ceramic resonator attached to its GPIO pin to generate clock signal for USB and Video modules.

Source code

clock node 416 node 317 node 417
417 12 mhz clock
drive 00 drop !b . . . !b for unext ;
ring 03 !b @ drop drop drop drop ;
pump 05 !b @ drop !b !b drop ;
go 07 @ drop 1E5 r-lu a!
49 for . drive next
begin ring dup ! ring dup !
pump dup ! pump dup ! end 16

init up a! io b! 1 dup dup or 20000 800
1 dup dup or 30000 over dup dup drop drop go ; 24

5 d 9 r 2 u ether

Definitions

drive
Set GPIO pin high/low, then wait for about 4 ns (three nop instructions), set GPIO pin to high impedance, and wait for two micronext loops. This code drives the resonator high and low at frequency close to 12 MHz.
ring
Set GPIO pin to high impedance and WD bit low/high. Then fetch from LEFT, i.e. suspend until GPIO pin is high (WD = 0) or low (WD = 1). Discard the value read from LEFT as well as next three values from pattern on stack. This word basically waits for the GPIO pin to toggle due to free‑oscillating resonator.
pump
Set GPIO pin to high impedance and WD bit low/high. Then fetch from LEFT, i.e. suspend until GPIO pin is high/low. Discard the value read from LEFT, drive the GPIO pin high/low, then switch it back to high impedance, and drop the next value from pattern on stack. This word waits for the GPIO pin to toggle, then drives it in the same direction, thus compensating for oscillation damping.
go
Suspend until receiving a signal from UP. Then set A to multiport RIGHT, LEFT, and UP. Run 50 times drive, then continue to an endless loop. In this loop call twice ring, and after each call send a signal (duplicate anything that's on stack and send it) to UP and RIGHT (whoever is reading). Then repeat the same, this time calling pump.
init
Set registers A and B, and prefills stack with values 1 0 20000 800 1 0 30000 0. Instructions dup dup drop drop assure the 10‑position stack is full. Then jump to go.

Description

This is a classical Chuck's code for driving resonators and watch crystals. The resonator is attached with its one end to a GPIO pin (see hardware section), while its other end is grounded. Driving the resonator high and low at the resonance frequency makes it resonate, which is then used to trigger code at regular intervals and keep the oscillator running. More information about this approach can by found in GreenArrays' application note AN002 Simple Oscillators.

Driving the resonator properly may be challenging. It is important to set the GPIO pin high/low at the right moment. This is best checked with a scope. In this code I had to place one nop operation inside the loop in go to comply with timing requirements. You may change that if needed. See manual for detailed procedure.

Node 417 can start execution only when other parts of the system have been loaded. Thus, it waits in go until receiving signal from nodes that are loaded later.

The use of multiport write and read is also noteworthy. When reading LEFT port (in words ring and pump), the node 417 suspends until the level on its GPIO pin is different from WD bit. Since nodes 416 and 317 always read RIGHT and UP ports, respectively, only change of GPIO pin level can wake up node 417. Similarly, when writing to multiport address, signal is sent to nodes 416 and 317 only, because writing to LEFT has no effect.

Code in this node uses circular character of data stack. Values on stack are discarded (sent to ports or dropped), while new copy of discarded values is continuously being generated. The values on stack represent (from top to bottom):

0
WD bit clear (suspend till GPIO pin high), GPIO pin in high impedance
30000
GPIO pin driven high
0
GPIO pin in high impedance
1
loop parameter in drive
800
WD bit set (suspend till GPIO pin low), GPIO pin in high impedance
20000
GPIO pin driven low
0
GPIO pin in high impedance
1
loop parameter in drive

Code in go writes to RIGHT and UP at twice the resonator frequency since it sends signal at both rising and falling edge. Thus, the pulse train leaving node 417 is at rate of 24 Mpulses/s.