Title: Lab. 1
1Lab. 1 GPIO Pin control
- Using information ENEL353 and ENCM369 text books
combined with Blackfin DATA manual
2What is a switch?
PRESS DOWN TO CLOSE
SPRINGTO CAUSESWITCH TOOPEN AFTERPUSH TO CLOSE
SWITCH OUTPUT
SWITCH INPUT
3Normally one side of switch is grounded, the
other side connected to microcontroller GPIO
input
INPUT IS ?????FLOATING
BLACKFIN
INPUT IS 0V
GPIO LINES PF8, PF9, PF10, PF11
GROUND (0V)
4One side of the switch must be pulled softly to
3 V / 5V (pull up resistor)
3v
10k Pull-upresistor
BLACKFIN
INPUT IS 5V
INPUT IS 0V
GPIO LINES PF8, PF9, PF10, PF11
GROUND (0V)
5Blackfin has a GPIO data register
- 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
6Registers used to control PF pins
- Flag Data register (FIO_FLAG_D)
- 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
7What we know about the way front panel switches
connected to BF533
- SW1 is connected to PF8
- SW2 is connected to PF9
- SW3 is connected to PF10
- SW4 is connected to PF11
- 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
8What 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 - 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)
9What we have to code
- 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 0x4723 (PF8, 9,
10) - We only want to get the bits 0x0700 -- MASK
- Result value MASK (and operation)
- Value read from data register 0x4023 (none)
- We only want to get the bits 0x0000
- Result value MASK (and operation)
- Value read from data register 0x4823 (PF11)
- We only want to get the bits 0x0500
- Result value MASK (and operation)
10So the code required is
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 R0 R0 R1 _ReadGPIOFlagsASM.END
RTS
11DOES NOT WORK
- We have not initialized the GPIO device
interface - Initialize device means prepare the device to
make work, in this case I / O
include ltblackfin.hgt .section
program .global _ReadGPIOFlagsASM _ReadGPIOFla
gsASM P0.L lo(FIO_FLAG_D) P0.H
R0 R0 R1 _ReadGPIOFlagsASM.END
RTS
12Initialize 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 - 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. - Etc. etc.
13Initialize the GPIO interface
- Set the DIRECTION register so that PF8 to PF11
pins are INPUT without 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. - 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 code required is
include ltblackfin.hgt .section
program .global _InitGPIOFlagsASM _InitGPIOFla
gsASM CALL TurnInterruptsOff_PF8to11 CALL
SetPolarity_PF8to11 CALL OtherStuff_PF8to11 C
ALL SetDirection_PF8to1 CALL
Enable__PF8to11 _InitGPIOFlagsASM.END
RTS
15Incorrect 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
// 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 _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? //
meaning where does the code jump to?
16Correct code
include ltblackfin.hgt .section
program .global _InitGPIOFlagsASM _InitGPIOFla
gsASM LINK 16 // Save (write)
RETS to the stack CALL TurnInterruptsOff_PF8to11
// 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
17Other GPIO register flip flopsFIO_MASKA_D and
FIO_MASKB_D
- 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)
18CALL TurnInterruptsOff_PF8to11ASM
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 // DO same thing for
FIO_MASK_B TurnInterruptsOff_PF8to11ASM.END
RTS
19P0.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
20CALL TurnInterruptsOff_PF8to11
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
21Lets call a C function instead of writing the
code in assembly code
NEW SLIDE
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
22Lets write this code in C instead
TurnInterruptsOff_PF8to11CPP__Fv
NEW SLIDE
Place code in InitGPIO.cpp include
ltblackfin.hgt void TurnInterruptsOff_PF8to11CPP(vo
id) pFIO_MASK_A 0 // WRONG
need to use AND operation Ssync( ) //
DO same thing for FIO_MASK_B In assembly code
the C function TurnInterruptsOff_PF8to11CPP( )
becomes named
_TurnInterruptsOff_PF8to11CPP__Fv In assembly
code the C function TurnInterruptsOff_PF8to11C (
) becomes named _TurnInterruptsOff_PF8to11C This
convention allows the overloading of C
functions (but not C)
23Another GPIO register we need to set correctly
24Another flip-flop group controls whether the
flip-flop outputs follow the flip-flop inputs or
are high impedance off no useful value
25CALL 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
26- 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)
27Why 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
28Making 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
29Notice 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 to look at the test code
to see what was being tested
30These tests DONOT find the design error
31These 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
32Extra ideas you can use
- Echoing Values from the switches to the LED
33Echoing 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
34Building 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
35LEDs connected to FLASH port
BACKFORWARDRIGHTLEFT??? CONTROL ON Might be
connected to other thingsDONT CHANGEBEHAVIOUR