Title: Input Laboratory: GPIO Pin control needed to have the Blackfin accept your commands
1Input Laboratory GPIO Pin control needed to
have the Blackfin accept your commands
- Re-uses information from ENEL353 and ENCM369
courses and text books combined with Blackfin
DATA manual to activate the Blackfin input device
(PF programmable flags)
2Reminder How does a switch work?The following
DOES NOT WORK
PRESS DOWN TO CLOSE
SPRINGTO CAUSESWITCH TOOPEN AFTERPUSH TO CLOSE
SWITCH OUTPUT
SWITCH INPUT
3One side of the switch must be pulled softly to
3 V / 5V (pull up resistor).
Softly avoid much current
3v
10k Pull-up resistorI V / R ?? mA?
BLACKFIN
INPUT IS 3VWHEN SWITCHOPEN
GPIO LINES PF8, PF9, PF10, PF11
INPUT IS 0VWHEN SWITCHCLOSED
GROUND (0V)
INPUT IS ???WHEN SWITCH OPEN
4Blackfin has a GPIO data registerGeneral purpose
input/output
- 16 GPIO lines come into the register
- Registers are based on flip-flops to store
whether the input is 3V (high) or zero (low) - 16 flip flops put together make the FIO_FLAG_D
register - The GPIO data register is memory mapped so no
special instructions needed, you treat it as if
it was the same as any other memory - When you read from the GPIO register, you cause
a load of the input values into the flip-flop
and out onto the microcontrollers data bus
5Registers used to control PF pins
- Flag Data register (FIO_FLAG_D) -- READABLE
- Used to read the PF bits as an input -- (1 or
0) - Need to read pins PF11 to PF8 ONLY , ignore all
other pins values - Read the value, AND off unwanted bits, then use
it
6What we know about the way front panel switches
connected to BF533
- SW1 is connected to PF8 input ofGPIO
- SW2 is connected to PF9 input ofGPIO
- SW3 is connected to PF10 input ofGPIO
- SW4 is connected to PF11 input ofGPIO
- The other pins in the GPIO interface are used for
other purposes on the Blackfin board and MUST
not have their values changed e.g. Video device
input port
7What we want to do?
- Read the GPIO data register
- Return ONLY the values in pins 8 to 11 which
means removing (masking out) the other values
which might have 1s or 0s in them - Value read from GPIO data register 0x4723
- We only want to get the bits 0x0700 (SW1, SW2,
SW3) - Value read from GPIO data register 0x4023
- We only want to get the bits 0x0000 (no switches)
- Value read from GPIO data register 0x4823
- We only want to get the bits 0x0800 (SW4)
8What we have to code using AND
instructions
- MASK bit set to 1 for bits we keep, 0 for bits
removed - MASK 0x0F00 (Bits 8, 9, 10, 11 are 1, other
bits are zero) - Value read from data register 0x4623 (want
PF8, 9, 10) - MASK set to 0x0700 -- Result value MASK
- bit value result 0x0600 (SW2, SW3 on, SW1 off)
- Value read from data register 0x4123 (PF9 )
- MASK set to 0x0200 -- Result value MASK
- Bit value results 0x0000 -- (SW2 off)
- Value read from data register 0x4923 (PF11)
- MASK set to 0x0800 -- Result value MASK
- Bit value result 0x0800 SW4 on)
9So the assembly code should look something like
this
include ltblackfin.hgt .section
program .global _ReadGPIOFlagsASM _ReadGPIOFla
gsASM P0.L lo(FIO_FLAG_D) P0.H
R0 WP0 (Z) // Convert 16 bits to
32 bits via zero extension
// These are bit settings
not a number define AND_MASK 0x0F00 R1
AND_MASK // Keep only bits 8, 9, 10, 11
//
(connected to switches) R0 R0
R1 _ReadGPIOFlagsASM.END RTS
10DOES NOT WORK -- We have not initialized the
GPIO device interface
- Initialize device means prepare the device to
make work, in this case I / O - Always initialize device registers (part of
driver code)
include ltblackfin.hgt .section
program .global _ReadGPIOFlagsASM _ReadGPIOFla
gsASM P0.L lo(FIO_FLAG_D) P0.H
R0 R0 R1 _ReadGPIOFlagsASM.END
RTS
11Initialize the GPIO interface requires change to
many control registers
- Turn the interrupts OFF for PF8 to PF11. Do this
WITHOUT changing the interrupt behaviour for the
other pins 0 to 7 and 12 to 15 - Set the POLARITY register so that a 1 coming into
pins PF8 to PF11 is read as a HIGH (1). Do this
without changing the POLARITY behaviour of the
other GPIO pins 0 to 7 and 12 to 15 - Etc. etc.
12- If leave interrupts on, then a stray signal at
the GPIO will cause the processor to stop - The POLAR register plays a big part of how the
processor reads values - Get the POLAR settings wrong causes very strange
behaviour where the processor thinks things are
working when they are not, and thinks things are
not working when they are - Problems with Real-time operating system lab.
13Initialize the GPIO interface
- Set the DIRECTION register so that PF8 to PF11
pins can be used as INPUT pinswithout changing
the behaviour of the other GPIO pins. - IF DONE INCORRECTLY CAN BURN OUT THE CHIP. You
dont want a device sending a 1 to the GPIO
interface, while the interface is trying to
output a 0. Human microprocessor demo ? - AFTER all other initialization steps are complete
- Set the ENABLE register so that pins PF8 to PF11
work without changing the behaviour of the other
GPIO pins. Power saving feature
14So the assembly code looks something like this.
PPPP activated
include ltblackfin.hgt .section
program .global _InitGPIOFlagsASM _InitGPIOFla
gsASM CALL TurnInterruptsOff_PF8to11 //
WHAT IS A CALL? CALL SetPolarity_PF8to11 CALL
OtherStuff_PF8to11 CALL SetDirection_PF8to1 C
ALL Enable__PF8to11 _InitGPIOFlagsASM.END
RTS // WHAT IS A RTS?
15Review how does the processor handle
instructions
- Repeat for ever
- Fetch an instruction (pointed to by PC at
address N) - Increment the PC to point to the next
instruction (N 1) - Decode the fetched instruction (work out what to
do) - Execute the fetched instruction
- Write the instruction results back to registers
or memory as needed
16What if instruction in a JUMP instruction?
- Repeat for ever
- Fetch an instruction (pointed to by PC)
- Increment the PC to point to the next
instruction - Decode the instruction (work out what to do)
- Execute the instruction
- Write the instruction results back to registers
or memory as needed - If the instruction is a jump, then part of the
instruction is a label (address) which must be
put into PC so we dont fetch the NEXT
instruction but one further away in the code
17What if instruction in a JUMP TO SUBROUTINE
(CALL) instruction?
- Repeat for ever
- Fetch an instruction (pointed to by PC)
- Increment the PC to point to the next
instruction - Decode the instruction (work out what to do)
- Execute the instruction
- Write the instruction results back to registers
or memory as needed - If the instruction is a jump or jump to
subroutine, then part of the instruction is a
label (address) which must be put into PC so we
dont fetch the NEXT instruction but one further
away in the code
18What if instruction in a JUMP TO SUBROUTINE
(CALL) instruction?
- Fetch an instruction (pointed to by PC)
- Increment the PC to point to the next
instruction - Decode the instruction (work out what to do)
- Execute the instruction
- Write the instruction results back to registers
or memory as needed - If the instruction is a jump or jump to
subroutine (CALL) , then part of the instruction
is a label (address) which must be put into PC so
we dont fetch the NEXT instruction but one
further away in the code - If the instruction is a jump to subroutine
instruction (CALL) then remember the next
instruction you were planning to call in the
RETS register (link) - If the instruction is return from subroutine
instruction (RTS), put stored value in RETS
register back into PC, which causes a jump back
to the next instruction which we were going to
do before the CALL happened
19Incorrect code contains a hidden defect which
stops the proper program operation
include ltblackfin.hgt .section
program .global _InitGPIOFlagsASM _InitGPIOFla
gsASM CALL TurnInterruptsOff_PF8to11
// CALL means set RETS register --
link register on MIPS //
to point to instruction after
CALL // RETS register address
of instruction labelled nextnext CALL
SetPolarity_PF8to11next2 CALL
OtherStuff_PF8to11 Next3 CALL
SetDirection_PF8to1 Next4 CALL
Enable__PF8to11 // Set RETS register to
_InitGPIOFlagsASM.END _InitGPIOFlagsASM.END
RTS // RTS means JUMP RETS
// or Change the PC to the value
stored in RETS register // What line of code
will be executed when the RTS instruction
finishes? // meaning where does the code jump
to -- ANSWER PC _InitGPIOFlagsASM.END -- Code
is now in a for-ever nowhere loop ?
20Correct code LINK and UNLINK should be a part
of ALL subroutines
include ltblackfin.hgt .section
program .global _InitGPIOFlagsASM _InitGPIOFla
gsASM LINK 16 // Save (write)
RETS to the memory stack CALL TurnInterruptsOff_P
F8to11 // CALL means set
RETS register //
to point to instruction after CALL
// RETS next in this
casenext CALL SetPolarity_PF8to11next2 CALL
OtherStuff_PF8to11 Next3 CALL
SetDirection_PF8to1 Next4 CALL
Enable__PF8to11 UNLINK //
Recover (get back) RETS from the
stack _InitGPIOFlagsASM.END RTS // This
means JUMP RETS // PC set to saved RETS so
code returns to the function that called it
21Other GPIO register flip flopsFIO_MASKA_D and
FIO_MASKB_D
- Stop this from happening unintentionally
- If bit X 1, tell processor to cause an
interrupt (change program operation) when
FIO_FLAG_D bit X is active (changes to a 1 value)
22CALL TurnInterruptsOff_PF8to11ASMBAD CODING
PRACTICE
include ltblackfin.hgt .section
program .global _TurnInterruptsOff_PF8to11ASM
_ TurnInterruptsOff_PF8to11ASM P0.L
lo(FIO_MASK_A) P0.H R1
0 WP0 R0
ssync // Tell processor to do
the write operation NOW
// REMEMBER This processor
does not
// treat WRITEs as high priority
//
UNLESS 2 writes are waiting to happen
// and
a 3rd write is requested!!!!! // DO same thing
for FIO_MASK_B TurnInterruptsOff_PF8to11ASM.END
RTS
23P0.L lo(FIO_MASK_A) P0.H R1 0WP0
R0
- This puts a 0 in every bit and turns ALL
interrupts off not just bits 8 to 11
24CALL TurnInterruptsOff_PF8to11GOOD CODING USING
BITWISE INSTRUCTION TO CLEAR BITS TO ZERO
include ltblackfin.hgt .section
program .global _TurnInterruptsOff_PF8to11 _
TurnInterruptsOff_PF8to11 P0.L
lo(FIO_MASK_A) P0.H R0
WP0 (Z) // Read all the bits define
MASK_NOCHANGE_VALUES 0xF0FF R1
MASK_NOCHANGE_VALUES R0 R1 R1 // Bits 8
to 11 zero WP0 R0 // But other bits still
the same // DO same thing for FIO_MASK_B TurnI
nterruptsOff_PF8to11 RTS
25Lets call a C function instead of writing the
code in assembly code
include ltblackfin.hgt .section
program .global _InitGPIOFlagsASM _InitGPIOFla
gsASM LINK 16 CALL
TurnInterruptsOff_PF8to11CPP__Fv
// We must use name mangling to call
C code next CALL SetPolarity_PF8to11next2
CALL OtherStuff_PF8to11 Next3 CALL
SetDirection_PF8to1 Next4 CALL
Enable__PF8to11
UNLINK _InitGPIOFlagsASM.END RTS
26Lets write this code in C instead
TurnInterruptsOff_PF8to11CPP__Fv
Place code in InitGPIO.cpp include
ltblackfin.hgt void TurnInterruptsOff_PF8to11CPP(vo
id) pFIO_MASK_A 0 // WRONG
need to use AND operation ssync( )
// pFIO_MASK_A pFIO_MASK_A
0x0F00
// What does the (twiddle) operation
perform? // DO same thing for FIO_MASK_B In
assembly code the C function TurnInterruptsOff_P
F8to11CPP( ) becomes named
_TurnInterruptsOff_PF8to11CPP__Fv (name
mangled) In assembly code the C function
TurnInterruptsOff_PF8to11C ( ) becomes named
_TurnInterruptsOff_PF8to11C This convention
allows the overloading of C functions (but not
C)
27Another GPIO register we need to set correctly
28Another flip-flop group controls whether the
flip-flop outputs follow the flip-flop inputs or
are high impedance off no useful value
29CALL EnablePins_PF8to11
include ltblackfin.hgt .section
program .global _EnablePins_PF8to11 _
EnablePins_PF8to11 P0.L lo(FIO_INEN) P0.H
define MASK_CHANGE_VALUES 0x0F00 R1
MASK_CHANGE_VALUES WP0 R1
EnablePins_PF8to11.END RTS WRONG True this
enables bits 8 to 11, but it also DISABLES all
the other bits Need to use OR instruction
after reading the enable register
30- A key issue with GPIO is whether a pin is to act
as an input device (bringing things in from the
outside world into the Blackfin) or as an output
device (sending things from the Blackfin to the
outside world)
31Why do you need to know how to do read (load)
and write (store) on internal registers?
- Flag Direction register (FIO_DIR)
- Used to determine if the PF bit is to be used for
input or output -- WARNING SMOKE POSSIBLE
ISSUE - Need to set pins PF11 to PF8 for input, leave all
other pins unchanged
32Making sure that the FIO_DIR is correct for LAB.
1 NOTE may need to change for later
labaoratories
Write the Blackfin assembly language
instruction(s) to load the address of the
internal programmable flag FIO_DIR register into
pointer register P1 then SET the Blackfin PF
lines to act as inputs
include ltblackfin.hgt P1.L lo (FIO_DIR) P1.H . // Check the requirements need to have all input // Manual says setting a line for input means setting bit values to 0 R0 0 WP1 R0 // This changes All pins ssync // Force Blackfin to do the write (store) NOW not later
Design Error Changes all pins
33Notice that previous slide WARNS you about a
design error in the code
- We cant do things this way as it changes all the
bits in the 16 flip-flops and we only want to
change 4 values in the flip-flops - The same design error is introduced into Lab. 1
Task 3 - However, the same design error is found during
the TDD tests provided you look at the test
code to see what was being tested
34These tests DONOT find the design error
35These tests DO find the design errorand in fact
explain to you why it is likely that your tests
have failed. But you have to read the message
about the Test and not ignore it
36Extra ideas you can use
- Echoing Values from the switches to the LED
- Can be used to copy the switch presses to the
LED. If the LED outputs are connected to the
radio controlled car inputs, then we can drive
the car using the switches(Last part of Lab. 1)
37Echoing the switches to the LEDCode in main( )
written in C
int main( ) InitializeGPIOInterface( ) //
Check Lab. 1 for exact name needed InitializeFl
ashLEDInterface( ) // Check Lab. 1 for exact
name needed define SWITCHBITS 0x0F00
// Look in MIPs notes about
//
using a mask and the
// AND
bit-wise operation //
to select desired bits while
(1) // Forever loop
int GPIO_value ReadBlackfinGPIOFlagsASM ( )
int desired_bits GPIO_value
SWITCHBITS int
LED_light_values desired_bits gtgt 8 // Bits
in wrong position
WriteFlashLEDLights(LED_light_values) // to
display on LEDS
38Building a radio controlled car4 Threads at least
SWITCHES ON FRONT PANELINPUT COMMANDS
LED LIGHTS ON FRONT PANELCONTROLSIGNALS TO RF
TRANS
PROGRAMMABLE FLAGS
LED-CONTROLREGISTER
FIO_FLAG_D Register
EBIU INTERFACE
YOUR PROGRAM RUNNING ON THE BLACKFIN
int ReadSwitches( )
void WriteLED(int )
ProcessDataASM( ) subroutine
D/A
EARPHONES
A/D
VOICE
A/D D/A Interrupt routine
39LEDs connected to FLASH port
BACKFORWARDRIGHTLEFT??? CONTROL ON Might be
connected to other thingsDONT CHANGEBEHAVIOUR