Forth Lesson 22

From OLPC

Jump to: navigation, search
Mitch Bradley's Forth and
Open Firmware Lessons:

Contents

[edit] Using Forth Under Linux

You can run Forth under Linux and use it to inspect I/O devices.

[edit] On XO-1.75 and XO-4

On OLPC OS builds, Forth is in /runin/sdkit-arm and can be started from Terminal:

 $ su
 # cd /runin/sdkit-arm
 # RUNIN_PATH=/runin ./sdkit.sh
 ok 

Or download http://dev.laptop.org/~wmb/sdkit-arm.tgz . Unpack it into your home directory:

 $ tar xfz sdkit-arm.tgz

Then:

 $ cd sdkit-arm
 $ su
 # ./sdkit.sh
 ok

sdkit comes up in hex mode, so you can enter and display numbers in hex without additional qualifiers. To enter a decimal number, precede it with "d# ", e.g. "d# 123"

[edit] GPIO Access

Command Stack Description Example
gpio-pin@ ( gpio# -- flag ) Flag is true if GPIO pin is high d# 108 gpio-pin@ .
gpio-out? ( gpio# -- flag ) Flag is true if GPIO is an output d# 108 gpio-out? .
gpio-set ( gpio# -- ) Drives GPIO high d# 108 gpio-set
gpio-clr ( gpio# -- ) Drives GPIO low d# 108 gpio-clr
gpio-rise@ ( gpio# -- flag ) Flag is true if rising edge detected d# 108 gpio-rise@ .
gpio-fall@ ( gpio# -- flag ) Flag is true if falling edge detected d# 108 gpio-fall@ .
gpio-edge@ ( gpio# -- flag ) Flag is true if edge detected d# 108 gpio-edge@ .
gpio-clr-edge ( gpio# -- ) Clears GPIO edge detector d# 108 gpio-clr-edge
gpio-dir-out ( gpio# -- ) Sets GPIO direction to output d# 108 gpio-dir-out
gpio-dir-in ( gpio# -- ) Sets GPIO direction to input d# 108 gpio-dir-out
gpio-set-rer ( gpio# -- ) Enables rising edge detection d# 108 gpio-set-rer
gpio-clr-rer ( gpio# -- ) Disables rising edge detection d# 108 gpio-set-rer
gpio-set-fer ( gpio# -- ) Enables falling edge detection d# 108 gpio-set-fer
gpio-clr-fer ( gpio# -- ) Disables falling edge detection d# 108 gpio-set-fer

[edit] Multi-Function Pin Register Access

The Multi-Function Pin Registers (MFPRs) control the assignment of chip pins to internal functions, and also control characteristics of those pins, such as drive strength, pull up/down resistors, etc. Since each multi-function pins can be used as a GPIO, we use the GPIO number to designate which pin we are interested in.

Command Stack Description Example
af@ ( gpio# -- function ) Returns the MFPR setting for gpio# d# 108 af@ .
af! ( function gpio# -- ) Sets the MFPR for gpio# h# a0c0 d# 108 af!
dump-mfprs ( -- ) Displays a table of all MFPR settings dump-mfprs
gpio>mfpr ( gpio# -- address ) Returns the address of the MFPR register for gpio# d# 108 gpio>mfpr .

[edit] Camera Test

The camera test turns on the camera chip and lets you access internal camera chip registers via its I2C bus interface.

Command Stack Description Example
test-camera-i2c ( -- ) Turns on the camera and dumps its internal registers test-camera-i2c
start-camera ( -- ) Sets up the camera clocks and pads, powers on and resets the camera sensor chip start-camera
ov@ ( reg# -- value ) Reads an internal camera register via I2C 5 ov@ .
ov! ( value reg# -- ) Writes an internal camera register via I2C 4 12 ov!
ov-dump ( -- ) Displays a bunch of camera registers ov-dump

[edit] Accelerometer

Command Stack Description Example
select /accelerometer ( -- ) Activate accelerometer device driver select /accelerometer
acceleration@ ( -- x y z ) Read acceleration values acceleration@ .d .d .d

acceleration@ .d .d .d cr many

unselect ( -- ) Deactivate the current device driver unselect

[edit] Two-Wire Serial Interface (I2C/SMBUS) Hardware

Command Stack Description Example
set-twsi-target ( slave channel -- ) Select a TWSI channel and slave address for subsequent access h# 3a 6 set-twsi-target
twsi-b@ ( reg -- byte ) Read a byte h# 20 twsi-b@ .
twsi-b! ( byte reg -- byte ) Write a byte h# 47 h# 20 twsi-b!
twsi-write ( byte_n-1 .. byte0 n -- ) Write n bytes from the stack 33 22 11 00 4 twsi-write
twsi-get ( reg#_n-1 .. reg#0 #reg-bytes #data-bytes -- data_n-1 .. data0 ) Send #reg-bytes register address bytes from the stack, then read #data-bytes onto the stack. h# 23 h# 01 2 4 twsi-get . . . .


[edit] Accessing Arbitrary Devices

In addition to the "canned" access words for specific devices, you can manually access any device you wish, using the "mmap" command to assign a virtual address to the I/O device's physical address.

Command Stack Description Example
mmap ( phys-addr size -- virt-addr ) Assigns a page-aligned virtual address to a physical device address range d4050000 1000 mmap constant clock-unit-base
unaligned-mmap ( phys-addr -- virt-addr ) Assigns a possibly-unaligned virtual address to a physical device address d4033800 unaligned-mmap constant twsi5-base

For mmap, the physical address and size must both be multiples of 0x1000 (the CPU page size), i.e. their low three hex digits must be 0.

For unaligned-mmap, the physical address need not be page-aligned. Unaligned-mmap calls mmap with a page-aligned address (mapping a single page) and then adds the offset into the virtual address.

You can add offsets to the virtual address to access registers within the range {virtual-address .. virtual-address+size-1}. For example:

 ok d4050000 1000 mmap  constant clock-unit
 ok clock-unit 24 + l@ .

You could use unaligned-mmap to get an address that points to an individual register within a register block, but it's usually better to map the base address of the register block and then apply small offsets to the virtual address to access individual registers.

[edit] Recipes

[edit] Storage LED

Useful for checking that sdkit-arm is functioning.

 ok d# 10 gpio-set  \ turn on the LED
 ok d# 10 gpio-clr  \ turn off the LED
 ok d# 10 0 do d# 10 gpio-set d# 100 ms d# 10 gpio-clr d# 400 ms loop  \ blink the LED ten times
[edit] Thermal Sensor

Obtains the temperature from the CPU, until ticket #10954 is fixed.

 d4013200 unaligned-mmap constant thermal-base
 : cpu-temperature  ( -- celcius )
    0                     ( acc )
    d# 100 0  do          ( acc )  \ Accumulate 100 samples
       thermal-base @     ( acc reg )
       h# 3ff and         ( acc val )
       +                  ( acc' )
    loop                  ( acc )
    d# 52940 -  d# 196 /  ( convert to celcius )
 ;
 cpu-temperature .d

Thus endeth the lesson.

Personal tools
  • Log in / create account
  • Login with OpenID
About OLPC
About the XO
Projects
OLPC wiki
Toolbox