input laboratory: gpio pin control needed to have the blackfin accept your commands

39
Input 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)

Upload: alexandra-york

Post on 03-Jan-2016

22 views

Category:

Documents


0 download

DESCRIPTION

Input 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). - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Input 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)

Page 2: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Reminder: How does a switch work?The following – DOES NOT WORK

2 /25

SPRINGTO CAUSESWITCH TOOPEN AFTERPUSH TO CLOSE

PRESS DOWN TO CLOSE

SWITCH OUTPUT

SWITCH INPUT

Page 3: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

One side of the switch must be pulled “softly” to 3 V / 5V (pull up resistor)

3 /25

BLACKFIN

GPIO LINES PF8, PF9, PF10, PF11GROUND (0V)

INPUT IS 0VWHEN SWITCHCLOSED

10k “Pull-up”resistor

3v

INPUT IS 5VWHEN SWITCHOPEN

Page 4: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Blackfin has a GPIO data registerGeneral purpose input/output16 GPIO lines come into the registerRegisters 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

registerThe 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 microcontroller’s data bus

4 /25

Page 5: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

5 /25

Registers 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

Page 6: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

What we know about the way “front panel” switches connected to BF533SW1 is connected to PF8 input ofGPIOSW2 is connected to PF9 input ofGPIOSW3 is connected to PF10 input ofGPIOSW4 is connected to PF11 input ofGPIOThe 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

6 /25

Page 7: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

What we want to do

Read the GPIO data registerReturn ONLY the values in pins 8 to 11 which

means removing (masking out) the other values which might have 1’s or 0’s in themValue read from GPIO data register = 0x4723

We only want to get the bits 0x0700 (SW1, SW2, SW3)

Value read from GPIO data register = 0x4023We only want to get the bits 0x0000 (no switches)

Value read from GPIO data register = 0x4823We only want to get the bits 0x0800 (SW4)

7 /25

Page 8: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

What we have to code using AND instructions

MASK bit set to 1 for bits we keep, 0 for bits removedMASK = 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 & MASKbit value result 0x0600 (SW2, SW3 on, SW1 off)

Value read from data register = 0x4123 (PF9 )MASK set to 0x0200 -- Result = value & MASKBit 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)

8 /25

Page 9: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

So the assembly code should look something like this

9 /25

#include <blackfin.h>

.section program;

.global _ReadGPIOFlagsASM;_ReadGPIOFlagsASM:

P0.L = lo(FIO_FLAG_D); P0.H = …… R0 = W[P0] (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;

Page 10: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

DOES 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)

10 /25

#include <blackfin.h>

.section program;

.global _ReadGPIOFlagsASM;_ReadGPIOFlagsASM:

P0.L = lo(FIO_FLAG_D); P0.H = …… ………;

R0 = R0 & R1;_ReadGPIOFlagsASM.END: RTS;

Page 11: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Initialize the GPIO interface requires change to many control registersTurn 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.

11 /25

Page 12: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

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 valuesGet 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.

12 /25

Page 13: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Initialize 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 don’t 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

13 /25

Page 14: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

So the assembly code looks something like this. PPPP activated

14 /25

#include <blackfin.h>

.section program;

.global _InitGPIOFlagsASM;_InitGPIOFlagsASM:

CALL TurnInterruptsOff_PF8to11; // WHAT IS A CALL?CALL SetPolarity_PF8to11;

CALL OtherStuff_PF8to11;CALL SetDirection_PF8to1;

CALL Enable__PF8to11;

_InitGPIOFlagsASM.END: RTS; // WHAT IS A RTS?

Page 15: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Review – how does the processor handle instructionsRepeat 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 needed15 /25

Page 16: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

What 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 don’t fetch the NEXT instruction but one further away in the code

16 /25

Page 17: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

What 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 don’t fetch the NEXT instruction but one further away in the code

17 /25

Page 18: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

What 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 don’t 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

18 /25

Page 19: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Incorrect code – contains a hidden defect which stops the proper program operation

19 /25

#include <blackfin.h>

.section program;

.global _InitGPIOFlagsASM;_InitGPIOFlagsASM:

CALL TurnInterruptsOff_PF8to11; // CALL means set RETS register -- link register on MIPS // to point to instruction after CALL

// RETS register = address of instruction labelled “next:”next: CALL SetPolarity_PF8to11;next2: 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 ?

Page 20: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Correct code; LINK and UNLINK should be a part of ALL subroutines

20 /25

#include <blackfin.h>

.section program;

.global _InitGPIOFlagsASM;_InitGPIOFlagsASM: LINK 16; // Save (write) RETS to the memory stack

CALL TurnInterruptsOff_PF8to11; // CALL means set RETS register // to point to instruction after CALL

// RETS = next: in this casenext: CALL SetPolarity_PF8to11;next2: 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

Page 21: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Other GPIO register flip flopsFIO_MASKA_D and FIO_MASKB_D

Stop this from happening unintentionallyIf 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)

21 /25

Page 22: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

CALL TurnInterruptsOff_PF8to11ASM;BAD CODING PRACTICE

22 /25

#include <blackfin.h>

.section program;

.global _TurnInterruptsOff_PF8to11ASM;_ TurnInterruptsOff_PF8to11ASM:

P0.L = lo(FIO_MASK_A); P0.H = …… R1 = 0;

W[P0] = R0; ssync; // Tell processor to do the write operation NOW

// DO same thing for FIO_MASK_B

TurnInterruptsOff_PF8to11ASM.END: RTS

Page 23: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

P0.L = lo(FIO_MASK_A); P0.H = …… R1 = 0;W[P0] = R0;

This puts a 0 in every bit and turns ALL interrupts off – not just bits 8 to 11

23 /25

Page 24: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

CALL TurnInterruptsOff_PF8to11;GOOD CODING USING BITWISE & INSTRUCTION TO CLEAR BITS TO ZERO

24 /25

#include <blackfin.h>

.section program;

.global _TurnInterruptsOff_PF8to11;_ TurnInterruptsOff_PF8to11:

P0.L = lo(FIO_MASK_A); P0.H = …… R0 = W[P0] (Z); // Read all the bits#define MASK_NOCHANGE_VALUES 0xF0FF

R1 = MASK_NOCHANGE_VALUESR0 = R1 & R1; // Bits 8 to 11 zeroW[P0] = R0; // But other bits still the same

// DO same thing for FIO_MASK_B

TurnInterruptsOff_PF8to11: RTS

Page 25: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Lets call a “C++” function instead of writing the code in assembly code

25 /25

#include <blackfin.h>

.section program;

.global _InitGPIOFlagsASM;_InitGPIOFlagsASM: LINK 16;

CALL TurnInterruptsOff_PF8to11CPP__Fv; // We must use “name mangling” to call C++ code

next: CALL SetPolarity_PF8to11;next2: CALL OtherStuff_PF8to11;Next3: CALL SetDirection_PF8to1;

Next4: CALL Enable__PF8to11; UNLINK;_InitGPIOFlagsASM.END: RTS;

Page 26: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Lets write this code in C instead TurnInterruptsOff_PF8to11CPP__Fv;

26 /25

Place code in “InitGPIO.cpp

#include <blackfin.h>

void TurnInterruptsOff_PF8to11CPP(void) { *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_PF8to11CPP( ) 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)

Page 27: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Another GPIO register we need to set correctly

27 /25

Page 28: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Another flip-flop group controls whether the flip-flop outputs follow the flip-flop inputs or are “high impedance” – off – no useful value

28 /25

Page 29: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

CALL EnablePins_PF8to11;

29 /25

#include <blackfin.h>

.section program;

.global _EnablePins_PF8to11;_ EnablePins_PF8to11:

P0.L = lo(FIO_INEN); P0.H = ……

#define MASK_CHANGE_VALUES 0x0F00;R1 = MASK_CHANGE_VALUESW[P0] = 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

Page 30: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

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)

30 /25

Page 31: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

31 /25

Why 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

Page 32: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

32 /25

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 <blackfin.h>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;

W[P1] = R0; // This changes “All pins”

ssync; // Force Blackfin to do the write (store) NOW not later

Making sure that the FIO_DIR is correct for LAB. 1 – NOTE may need to change for later labaoratories

Design Error

“Changes all pins

Page 33: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Notice that previous slide WARNS you about a design error in the codeWe can’t 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

33 /25

Page 34: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

These tests DONOT find the design error

34 /25

Page 35: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

These 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

35 /25

Page 36: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Extra 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)

36 /25

Page 37: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

37 /25

Echoing the switches to the LEDCode in main( ) – written in C++

int main( ) {

InitializeGPIOInterface( ); // Check Lab. 1 for “exact name needed”InitializeFlashLEDInterface( ); // 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 >> 8; // Bits in wrong position

WriteFlashLEDLights(LED_light_values); // to display on LEDS

}

}

Page 38: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

38 /25

Building a radio controlled car4 Threads at least

SWITCHES ON FRONT PANEL“INPUT COMMANDS:

PROGRAMMABLE FLAGS

FIO_FLAG_D Register

YOUR PROGRAM RUNNING ON THE BLACKFIN

LED LIGHTS ON FRONT PANEL“CONTROLSIGNALS TO RF TRANS:

LED-CONTROLREGISTER

EBIU INTERFACE

ProcessDataASM( ) subroutine

A/D D/A Interrupt routine D/AEAR

PHONESA/DVOICE

int ReadSwitches( ) void WriteLED(int )

Page 39: Input Laboratory:  GPIO Pin control needed to have the Blackfin accept your commands

Blackfin BF533 I/O 39

LEDs connected to FLASH port BACKFORWARDRIGHTLEFT???

CONTROL ON

Might be connected to other things

DON’T CHANGEBEHAVIOUR