Tuesday, March 24, 2009

To Find a Square-root with miniMIPS

###############################################################################
# To find a square-root of an integer
# (c) M. Lutfi, 2009
#
# Platform: miniMIPS
# tested on: MARS simulator
#
# Convention:
# $v0..$v1,$t0..$t9,$a0: destroyed during procedure calls
# $s0..$s9: saved during procedure calls
###############################################################################

.text
main:
la $a0, question
jal print_string # print(question)
addi $v0,$zero,5
syscall # read integer. v0 contains the integer read (x)
add $s0,$v0,$zero # s0 = x
bltu $s0,$zero,error # exit if x <>
beqz $s0,just_print # print "0" if x == 0
beq $s0,1,just_print # print "1" if x=1

addi $t1,$zero,0 # a = 0
add $t2,$s0,$zero # b = x

loop:
add $t3,$t1,$t2 # t3 = (a+b)
sra $t3,$t3,1 # mid = (a+b)/2
beq $t3,$t1,print_sqrt
beq $t3,$t2,print_sqrt # to prevent endless loop and give approx. result
multu $t3,$t3 #(hi,lo) = mid*mid
mflo $t4
mfhi $t5 # (t5,t4) = mid^2
beq $t4,$s0,print_sqrt # if (mid^2 == x) goto print_sqrt
bgtu $t4,$s0,set_b # if (mid^2 > x) goto set_b
bltu $t4,$s0,set_a # if (mid^2 <>

set_a:
add $t1,$t3,$zero # a = mid
j loop

set_b:
add $t2,$t3,$zero # b = mid
j loop

print_sqrt:
la $a0,answer
jal print_string # print "sqrt(x) = "
add $a0,$t3,$zero # mid is the sqrt(x)
jal print_integer # print the result
j main # do it again. To finish, just enter neg number
j exit

error:
la $a0, inv_num
addi $v0,$zero,4
syscall
j exit

just_print:
la $a0,answer
jal print_string # print "sqrt(x) = "
add $a0,$s0,$zero #print_integer(x)
jal print_integer

exit: # no param needed
addi $v0,$zero,10
syscall # exit


#---------------------------------subroutines----------------------------------
print_string: # string address in a0
addi $v0,$zero,4 # a0 and v0 are destroyed
syscall
jr $ra

print_integer: # integer value in a0
addi $v0,$zero,1
syscall
jr $ra



#-------------------data section-----------------

.data

question: .asciiz "\nEnter number to be square-rooted: "
inv_num: .asciiz "\nInvalid number (e.g, negative"
answer: .asciiz "Sqrt(x) = "

Monday, March 23, 2009

LED Blink on PICKit2 Demoboard

The following code will make LED 1 on PICKit2 demoboard (attached to PICKit2 programmer) to blink for about every 500 mSec. Tools needed are: gputils and sdcc (all of them are open sources), and pk2cmd freely available at Microchip website.

Source code:
__sfr __at (0x2007)  CONFIG = _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF &
   _CP_OFF & _IESO_OFF & _FCMEN_OFF & _BOR_OFF;



unsigned char delay1val;
unsigned char delay2val;

void delay()
{
    __asm
    CLRF        _delay1val
    CLRF        _delay2val
    loop:
    DECFSZ      _delay1val,f
    GOTO        loop
    DECFSZ      _delay2val,f
    GOTO        loop
    __endasm;
}

void main()
{
    // make C0 as output
    TRISC0 = 0;
    do {
       RC0 = 1;
       delay();
       RC0 = 0;
       delay();
    } while (1);
}


Makefile:

OBJS=demo1.o
PRJ=demo1
CHIP=690
ARCH=pic14
PLATFORM=16f$(CHIP)
LIBPATH=-I/usr/local/share/gputils/lkr -I/usr/local/share/sdcc/lib/pic
LINKSCRIPTPATH=/usr/local/share/gputils/lkr
LIBS=libsdcc.lib pic$(PLATFORM).lib libm.lib
CC=sdcc -V -m$(ARCH) -p$(PLATFORM)
LINKER=/usr/local/bin/gplink
CFLAGS=--opt-code-speed --stack-auto --main-return --profile --debug-xtra --no-pcode-opt --funsigned-char --Werror
CPPFLAGS=

.c.o:
  $(CC) $(CFLAGS) -D_16F$(CHIP) -c $<

$(PRJ).hex: $(OBJS)
        $(LINKER) -w -O1 -m -o $(PRJ).hex $(OBJS) $(LIBPATH) -f 0 $(LIBS) -s $(LINKSCRIPTPATH)/$(PLATFORM).lkr
   all: $(PRJ).hex
   clean:
        @echo "cleaning up all generated files..."
        @for obj in $(OBJS); do \             if [ -e $$obj ] ; then rm $$obj ; fi \         done
        @rm *.lst
        @if [ -e $(PRJ).cod ] ; then rm $(PRJ).cod ; fi
        @if [ -e $(PRJ).hex ] ; then rm $(PRJ).hex ; fi
        @echo "done."
install:
        pk2cmd -PPIC$(PLATFORM) -M -F$(PRJ).hex
        pk2cmd -PPIC$(PLATFORM) -T


To build:
make demo1.hex

To install:
make install

Sunday, March 22, 2009

PICKIT2 on OpenSUSE

First, create a new udev rules under /etc/udev/rules.d/, name it as "26-microchip.rules".
Add the following into the file:

# PicKit2
SUBSYSTEM=="usb_device", ACTION=="add", SYSFS{idVendor}=="04d8", SYSFS{idProduct}=="0033"
MODE="660", GROUP="microchip", RUN="/usr/local/bin/pk2cmd I /PPIC16F690", SYMLINK+="pickit2"

(do lsusb to verify the vendor and produc id)

Then, execute this on the shell:

sudo udevadm control --reload_rules

Then, download pk2cmd (search google. It should be linked to Microchip website. or try this: http://ww1.microchip.com/downloads/en/DeviceDoc/pk2cmdv1.20LinuxMacSource.tar.gz), compile and install.

When everything is complete with no error, plug in the PICkit2 USB to PC. Check that a new symbolic link was created under /dev as: pickit2. If it is there, you are good to go. Fire up the pk2cmd.

For example, assume the demo code has been there in the demo board and we just want to turn it on, we just need to type: pk2cmd -T /PPIC16F690. To get to know the attached chip on the demo board, try: pk2cmd -I -PPIC16F690

For example:
#> pk2cmd -I -PPIC16F690

Device ID = 1400
Revision = 0005
Device Name = PIC16F690

Operation Succeeded

Friday, March 20, 2009

SDCC Makefile for PIC14

OBJS=test.o
PRJ=test
PLATFORM=16f690
LIB=-I/usr/local/share/gputils/lkr -I/usr/local/share/sdcc/lib/pic

.c.o:
sdcc -V -mpic14 -p$(PLATFORM) --opt-code-speed --stack-auto --main-return -c $<

$(PRJ).hex: $(OBJS)
gplink -m -s $(PLATFORM).lkr -o $(PRJ).hex $(OBJS) $(LIB) -f 0 libsdcc.lib pic$(PLATFORM).lib libm.lib

clean:
rm $(OBJS)
rm $(PRJ).cod
rm $(PRJ).hex

Small Embedded Linux board

Beagleboard Site:
http://beagleboard.org/

BeagleBoard Shopping List
http://code.google.com/p/beagleboard/wiki/BeagleBoardShoppingList