Home |  Common Examples |  I2C

A Scheme Interpreter for ARM Microcontrollers:
Program Examples for Snapshot 00.0215

SourceForge.net Logo

Common Program Examples:

Program examples for this snapshot are identical to those of the previous snapshot, given here, except for the 'defined? function which now needs to be user-defined, for example:

; Armpit Scheme Example of user-defined defined? function

(define (defined? sym)
  (let ((been-here #f)
	(_catch #f))
    (call/cc (lambda (k) (set! _catch k)))
    (if been-here #f
	  (set! been-here #t)
	  (eval sym)


I2C Multiprocessing:

I2C multiprocessing has been fixed in this snapshot and allows remote code evaluation on those MCUs where the I2C susbsytem in enabled (LPC-2000, AT91SAM7, STR-711). The example below consists of two parts: 1) a boot file for the remote MCU, and; 2) code for the local MCU. The remote MCU boot file sets its MCU I2C ID and then starts a REP loop that reads from the I2C input port, evaluates the received expression and write the result to the I2C output port. The code updates prior I2C examples by adding a mild level of error recovery by catching thrown errors. The local MCU code example starts with enabling the subsystem and then sends expressions to the remote device for evaluation and reads the result back.

; Armpit Scheme I2C Example
; tested on TINY-2106, TINY-2138

; code for the slave (TINY-2138)
(let ((port (open-output-file "boot")))
  (if (zero? port) #f
	(define (current-output-port) port)
	(write '(write 40 #xE001C00 #x0C)) ; by itself here so parse doesn't str->sym new symbols before new mcu-id is set
	    (define i2c    #xE001C00)
	    (define (current-input-port) i2c)
	    (define (current-output-port) i2c)
	    (define pinsel #xE002C00)
	    (write (logior #x50 (logand #xFFFFFF0F (read pinsel 0))) pinsel 0)
	    (write 47   i2c #x10)
	    (write 103  i2c #x14)
	    (write #x28 i2c #x18)
	    (write #x44 i2c #x00)
	    (define (_prg)
	      (write (eval (read) (interaction-environment)))
	    (write (call/cc (lambda (_prg) (set! _catch _prg))))
	(close-output-port (current-output-port)))))

; code for master (TINY-2106)
  (define i2c    #xE001C00)
  (define pinsel #xE002C00)
  (write (logior #x50 (logand #xFFFFFF0F (read pinsel 0))) pinsel 0)
  (write 47   i2c #x10)
  (write 103  i2c #x14)
  (write #x28 i2c #x18)
  (write #x44 i2c #x00))

; remote evaluation of integer
(write 9 i2c '#(20))

; get result back
(read i2c '#(20)) ; -> 9

; remote evaluation of sum
(write '(+ 3 5 7 9 11 13 15) i2c '#(20))

; get result back
(read i2c '#(20)) ; -> 63

; remote evaluation of list
(write '(list 3 5 7 9 11 13 15) i2c '#(20))

; get result back
(read i2c '#(20)) ; -> (3 5 7 9 11 13 15)

; remote definition
; Notes: 1- mcu-id has its symbol-ID indexed on the local MCU
;        2- function references remote symbol 'i2c via string->symbol
(write '(define (mcu-id) (ash (read (eval (string->symbol "i2c")) #x0C) -1)) i2c '#(20))

; remote function call
(write '(mcu-id) i2c '#(20))

; get result back
(read i2c '#(20)) ; -> 20

; local definition
(define x 3+2i)

; remote eval with local environment
(write `(eval 'x ',(interaction-environment)) i2c '#(20))

; get result back
(read i2c '#(20)) ; -> 3+2i

; local variable definition
(define y 3/4)

; local closure that refers to local variable y
(define (py x) (+ x y))

; remote application of local closure
; Note: closure is transmitted with its environment
(write (list py 3/5) i2c '#(20))

; get result back
(read i2c '#(20)) ; -> 27/20

Last updated December 28, 2009