Monday, September 21, 2009

Look-up tables from one-hot encoding inputs

In regards to manually scanning a matrix keypad with  M rows and N columns. 


Say we output on the columns and read in the rows which are pulled up high. We will pull one column low and see if one of the rows is also pulled low (we are only worried about one key).


So our output O bit string with (N-1) 1's and one 0 corresponding to the low column [n will be the value of the low bit].


Our input I also going to be bitstring with either all 1's or (M-1) 1's and the 0 corresponds to the low row [m will be the value of the low bit].


To make this manageable we make a look-up table that matches our keyboard layout:
key_lut .byte 'q','w','e','r',...'|'
            .byte 'a','s'
            ...
For convenience we can write each new row on a different line, but essentially this is a one dimensional array which can be indexed.

key_lut[row*N+column]

 We don't have a row and column, but instead a position of n and m. If we negate I and O then we have a one-hot (one high) bitstring which equals n or m. But we need the position of this bit, not its value. So we can take the log_2 of this value and get the position.

key_lut[log_2(m)*N+log_2(n)]

To take the log_2 of a bit string, we simple need to count the number division by 2 until the value is 1. We simply set up a loop to increment a counter and shift the register right until its 1. Remember log(0) is undefined!



Monday, September 14, 2009

Soldering Single Row Headers

Trick:
Slightly bend the inserted portion of the pins at the end of the row you are soldering opposite directions. Usually perpendicular to the row.
Here is an ASCII representation with them bent parallel to the row. Notice the short end is bent as we are using these as wire-wrap posts.
Ex:

||||  /||\
----  ----
||||  ||||
||||  ||||


This way the header doesn't fall out when you try to solder it from the other side.

Friday, September 11, 2009

Lab 3 Grading Rubric





Pre-Lab Materials
A. flow chart for Part I ASM program, 5%
B. flow chart for Part II ASM program, 5%
C. flow chart for Part III ASM program, 5%
D. assembly code printed in Courier 8pt font, 5%


In-Lab Participation
E. ability to debug and find errors, 10%
F. flexible input/output variable addressing assignment, 5%
G. modular & relocateable code (use of  .set instead of hard-coded length, addresses and clear concise program function) 10%
H. Part I, correct results for outputs from data given by TA & questions answered correctly, 25%
I. Part II, functional LED output port, 10%
J. Part III, functional input switches, 10%
K Part III, program that echoes input switches to output display, 10%

Accesing General Purpose I/O (GPIO) Peripheral Direct Addressing

Along with everything else the GPIO pins/ports are memory mapped.
Find the address peripherals you need at http://www.add.ece.ufl.edu/4744/references/tms320f28335_sprs439e.pdf  page 94,95.


Then since you are just using direct addressing we can just use some symbols for the addresses for less confusion.



GPADIR .set 0x6F8A ;used to set direction of GPIO[0:31]
GPADAT .set 0x6FC0 ;the actual pins/ports for GPIO[0:31]




To direct address with symbols/numbers we have set up the data-page pointer correctly (if we had defined labels the assembler would take care of the aligning of the data-page pointer itself see below).

A 32 bit data address
0000 0000|00XX XXXX|XXXX XXXX|XXYY YYYY


where {X} is the data-page (stored in DP) and {Y} is the offset stored as a 6-bit immediate in the opcode.


So the address (0x6FC0) is:


0000 0000|0000 0000|0110 1111|1100 0000
                    0110 1111 11 

We want DP to equal 0x6FC0>>6 = 0x1BF
We can let the assembler do the math for us:




MOV DP,#GPADAT>>6
                MOV @GPADAT,#0x0001 ;output a 1.


Some of you are thinking,"Hey why do you use another 16 bit number (GPADAT) for the direct addressing?" we really aren't, the format is to avoid confusion and the assembler truncates GPADAT to the 6-bits used to address the data-page. So the opcode for this looks like this:


0010 1000|0000 0000|0000 0000|0000 0001
0010 1000|00YY YYYY|ZZZZ ZZZZ|ZZZZ ZZZZ

where {Y} is the offset stored as a 6-bit immediate and {Z} is the 16-bit immediate value.


Using direct addressing with labels defined in .data or .bss
If there were a less complicated assembler/linker you could define label and locate them anywhere you please. Such as pointing a label at the GPIO. However, the assembler uses directives like .data, .text, .bss to define areas of memory and the linker command files assigns these sections to areas of memory.
The assembler does make it easy for use labels for direct addressing here's how it works. Define some variables, use the first variable name to set up the data-page pointer, now you can use the specific variable names for direct addressing without changing the data-page pointer as long as they are in the same 64-word data page range.

Example:

.data
val1    .word 0x000
val2    .word 0x001
...
val64   .word 0x020
val65   .word 0x021
...
val128  .word 0x040




         .text
main: 
         mov AL,#0
         mov DP,#val1 
         add AL,@val1 ;1
         add AL,@val2 ;2
...
         add AL,@val64
         add AL,@val65 ;1-this actually adds @val1 again
         mov DP,#val65 
         add AL,@val65 ;1-here we go
         add AL,@val66 ;2
...


The opcodes for the lines with matching numbers should be exactly the same...














Update to CCS v 4

There is an update for Code Composer Studio v. 4 to fix the issue with restarting the CPU.
Remember that we are only using the microcontroller core, and the XDS1000 simulator (follow tutorial 1 again). Except pick a new install folder (instead of default /Texas Instruments) try "/Texas Instruments2" or something. Once you install your start-menu shortcut will automatically be updated, and your license file will be too. Don't try to uninstall the old version, its not worth it and some of the components are reused.