CSC231 Lab 7 solution
Solution program for Lab #7
;;; talkToArduino.asm
;;; D. Thiebaut
;;; This program requires arduino-serial.c for handling the
;;; communication with an Arduino diecimila.
;;; This program uses strings (msg1, msg2, msg3, etc...)
;;; that contain canned commands of the form "w d 13 1" or
;;; "r d" that the sketch on the arduino understands, and
;;; will execute.
;;;
;;; To assemble and run
;;; nasm -f elf talkToArduino.asm
;;; gcc -o talkToArduino arduino-serial.c talkToArduino.o
;;; ./talkToArduino
;;;
;;; ----------------------- EXTERN LABELS -----------------------
extern serialport_writebyte ; int function
extern serialport_write ; int function
extern serialport_read_until ; int function
extern displayBuffer ; int function
extern buf
extern byte
;; -------------------------
;; data segment
;; -------------------------
section .data
msg1 db "w d 13 1", 0
msg1len equ $-msg1
msg2 db "w d 13 0", 0
msg2len equ $-msg2
msg3 db "r d", 0
msg3len equ $-msg3
msg4 db "w d 13 "
msg4val db '?', 0
msg4len equ $-msg4
section .bss
;; -------------------------
;; code area
;; -------------------------
section .text
global asm_main
asm_main:
;; turn Pin 13 On/Off a few times
mov eax, msg1
mov ecx, msg1len
call copyMsg
call serialport_write
call delay100ms
mov eax, msg2
mov ecx, msg2len
call copyMsg
call serialport_write
call delay100ms
mov eax, msg1
mov ecx, msg1len
call copyMsg
call serialport_write
call delay100ms
mov eax, msg2
mov ecx, msg2len
call copyMsg
call serialport_write
.for mov ecx, 1000 ; read/write switch 1000 times
call readPin2 ; get status of Pin 2 in al
call setPin13 ; set Pin 13 to value in al
loop .for
;; return to C program
ret
;;; ----------------------------------------------------------------
;;; copyMsg1: puts array whose address in eax in external buffer
;;; number of bytes shoudl be in ecx.
;;; ----------------------------------------------------------------
copyMsg:
pushad
mov esi, eax ; source buffer
mov edi, buf ; destination buffer in C program
.for mov al, [esi]
mov [edi], al
inc esi
inc edi
loop .for
popad
ret
;;; ----------------------------------------------------------------
;;; delay 100 ms.
;;; ----------------------------------------------------------------
delay100ms:
pushad
mov ecx, 100000000 ; 200,000,000 cycles (assuming 2GHz)
.for add eax, 1 ; 1 cycle
loop .for ; 1 cycle
popad
ret
;;; ----------------------------------------------------------------
;;; readPin2: sends the arduino a request for value of pins
;;; returns '0' or '1' in al as value of Pin 2
;;; ----------------------------------------------------------------
readPin2:
mov eax, msg3
mov ecx, msg3len ; "r d" read digital pins
call copyMsg ; now buf contains "r d"
call serialport_write
call serialport_read_until
;;; call displayBuffer
;;; get the value of input pin 2 as defined in buffer
;;; which contains "d 0 0 1 0 0 0 1 0 0 0 0 0"
;;; and first 0 is Pin 2, second 0 is Pin 3, etc.
mov al, [buf+2] ; get first digit and put it
; in al
ret
;;; ----------------------------------------------------------------
;;; SetPin13: sets pin 13 to the value '0' or '1' passed in al
;;; ----------------------------------------------------------------
setPin13:
pushad
mov [msg4val],al ; and embed '0' or '1' at right place
mov eax, msg4
mov ecx, msg4len ; copy msg4 in buf
call copyMsg
;;; call displayBuffer
call serialport_write; send message "w d 13 x" to arduino
popad ; restore registers
ret