16.Input Output‎ > ‎

NXP LPC1768 IO

  1. NXP LPC1768 Pins
  2. NXP LPC1768 Peripheral Memory Map
  3. Detailed GPIO Register Address Map
  4. Configuring the NXP LPC1768 as used in the MBED system.
  5. Reading and writing the GPIO
  6. Input Examples
  7. Output Atomic Operations
  8. Bit Banding
  9. Alternate Functions
  10. Example: Simulating traffic lights

  1. NXP LPC1768 Pins
  2. Pin No Function 1 Function 2 Function 3 Function 4 MBED Application Board
    1 TDO SW0        
    2 TDI          
    3 TMS SWIO        
    4 nTRST          
    5 TCLK SWDCLK;        
    6 P0.26 AD0.1 AOUT RXD3 P18 Analogue Out
    7 P0.25 AD0.2 I2SRX_SDA TXD3 P17 Analogue In
    8 P0.24 AD0.3 I2SRX_WS CAP3.1 P16 Switch Right
    9 P0.23 AD0.4 I2SRX_CLK CAP3.0 P15 Switch Up
    10 VDDA          
    11 VSSA          
    12 VREFP          
    13 N.C.          
    14 nRSTOUT          
    15 VREFN          
    16 RTCX1          
    17 nRESET          
    18 RTCX2          
    19 VBAT          
    20 P1.31 Reserved SCLK  AD0.5 Pin 20 Pot 2
    21 P1.30 Reserved VBUS  AD0.4 Pin 19 Pot 1
    22 XTAL1          
    23 XTAL2          
    24 P0.28 SCL0 USB_SCL      
    25 P0.27 SDA0 USB_SDA      
    26 P3.26 STCLK MAT0.1 PWM1.3    
    27 P3.25 MAT0.0 PWM1.2      
    28 VDD          
    29 P0.29 USBD+     USB+  
    30 P0.30 USBD-     USB-  
    31 VSS          
    32 P1.18 USB_UP PWM1.1 CAP1.0 LED1  
    33 P1.19 MC0A USB_PPWR CAP1.1    
    34 P1.20 MCFB0 PWM1.2 SCK0 LED2  
    35 P1.21 MCABORT PWM1.3 SSEL0 LED3  
    36 P1.22 MC0B USB_PWRD MAT1.0    
    37 P1.23 MCFB1 PWM1.4 MISO0 LED4  
    38 P1.24 MCFB2 PWM1.5 MOSI0    
    39 P1.25 MC1A MAT1.1      
    40 P1.26 MC1B PWM1.6 CAP0.0    
    41 VSS          
    42 VDD          
    43 P1.27 CLKOUT USB_OVRCR CAP0.1 Wired to EN of Ethernet Clock  
    44 P1.28 MC2A PCAP1.0 MAT0.0    
    45 P1.29 MC2B PCAP1.1 MAT0.1    
    46 P0.0 CAN_RX1 TXD3 SDA1 Pin 9 XBee Tx
    47 P0.1 CAN_TX1 RXD3 SCL1 Pin 10 XBee Rx
    48 P0.10 TXD2 SDA2 MAT3.0 Pin 28 SDA  Temperature Sensor
    Accelerometer
    49 P0.11 RXD2 SCL2 MAT3.1 Pin 27 SCL  Temperature Sensor
    Accelerometer
    50 P2.13 EINT3N I2SX_SDA      
    51 P2.12 EINT2N I2STX_WS      
    52 P2.11 EINT1N I2STX_CLK      
    53 P2.10 EINT0N NMI      
    54 VDD          
    55 VSS          
    56 P0.22 RTS1 CAN_TX1      
    57 P0.21 RI1 CAN_RX1      
    58 P0.20 DTR1 SCL1      
    59 P0.19 DSR1 MCICLK SDA1    
    60 P0.18 DCD1 MOSI0 MOSI Pin 11 LCDCS_N
    61 P0.17 CTS1 MISO0 MISO Pin 12 Switch Down
    62 P0.15 TXD1 SCK0 SCK Pin 13 Switch Left
    63 P0.16 RXD1 SSEL0 SSEL Pin 14 Switch Centre
    64 P2.9 USB_CONNECT RXD2      
    65 P2.8 CAN_TX2 TXD2      
    66 P2.7 CAN_RX2 RTS1      
    67 P2.6 PCAP1.0 RI1 TRACECLK    
    68 P2.5 PWM1.6 DTR1 TRACEDATA0 Pin 21 PWM_1
    69 P2.4 PWM1.5 DSR1 TRACEDATA1 Pin 22 PWM_2
    70 P2.3 PWM1.4 DCD1 TRACEDATA2 Pin 23 LED Green
    71 VDD          
    72 VSS          
    73 P2.2 PWM1.3 CTS1 TRACEDATA3 Pin 24 LED Red
    74 P2.1 PWM1.2 RXD1   Pin 25 LED Blue
    75 P2.0 PWM1.1 TXD1 TRACECLK Pin 26 Speaker
    76 P0.9 I2STX_SDA MOSI1 MAT2.3 Pin 5 LCD MOSI
    77 P0.8 I2STX_WS MISO1 MAT2.2 Pin 6 LCD Reset
    78 P0.7 I2STX_CLK SCLK1 MAT2.1 Pin 7 LCD Clock
    79 P0.6 I2SRX_SDA SSEL1 MAT2.0 Pin 8 LCD AS
    80 P0.5 I2SRX_WS CAN_TX2 CAP2.1 Pin 29 XBee Status
    81 P0.4 I2SRX_CLK CAN_RX2 CAP2.0 Pin 30 XBee Reset (NRST)
    82 P4.28 RX_MCLK MAT2.0 TXD3    
    83 VSS          
    84 VDD          
    85 P4.29 TX_MCLK MAT2.1 RXD3    
    86 P1.17 ENET_MDIO     Ethernet  
    87 P1.16 ENET_MOC     Ethernet  
    88 P1.15 ENET_RX_CLK     500MHz Clock  
    89 P1.14 ENET_RC_ER     Ethernet  
    90 P1.10 ENET_RXD1     Ethernet  
    91 P1.9 ENET_RXD0     Ethernet  
    92 P1.8 ENET_CRS     Ethernet  
    93 P1.4 ENET_TX_EN     Ethernet  
    94 P1.1 ENET_TXD1     Ethernet  
    95 P1.0 ENET_TXD0     Ethernet  
    96 VDD          
    97 VSS          
    98 P0.2 TXD0 AD0.7      
    99 P0.3 RXD0 AD0.6      
    100 RTCK          

    NXP LPC 1768 pins and functions. Based on page by Christian Lerche


  3. NXP LPC1768 Peripheral Memory Map
  4. The peripherals in the LPC1768 are allocated the memory ranges indicated below. The LPC1768 nominally has 5 GPIO ports of varying sizes that fall in the address range 0x2009C000 through 0x2009CFFF.

        Advanced Bus   Region       Address Boundaries Registers
    AHB Peripherals 4-127 50010000-5001FFFF Reserved
    3 5000C000 - 5000FFFF USB Controller
    2 50008000 - 5000BFFF Reserved
    1 50004000 - 50007FFF GPDMA controller
    0 50000000 - 50003FFF Ethernet controller
    APB1 peripherals 31 400FC000 - 400FFFFF System control
    16-30 400C0000 - 400FBFFF Reserved
    15 400BC000 - 400BFFFF QEI
    14 400B8000 - 400BBFFF motor control PWM
    13 400B4000 - 400B7FFF Reserved
    12 400B0000 - 400B3FFF repetitive interrupt timer
    11 400AC000 - 400AFFFF Reserved
    10 400A8000 - 400ABFFF I2S
    9 400A4000 - 400A7FFF Reserved
    8 400A0000 - 400A3FFF I2C2
    7 4009C000 - 4009FFFF UART3
    6 40098000 - 4009BFFF UART2
    5 40094000 - 40097FFF Timer 3
    4 40090000 - 40093FFF Timer 2
    3 4008C000 - 4008FFFF DAC
    2 40088000 - 4008BFFF SSP0
    0-1 40080000 - 40087FFF Reserved
    APB0 peripherals 24-31 400xx000 - 400xxFFF Reserved
    23 4005C000 - 4007FFFF I2C1
    19-22 4004C000 - 4005BFFF Reserved
    18 40048000 - 4004BxFFF CAN2
    17 40044000 - 40047FFF CAN1
    16 40040000 - 40043FFF CAN common
    15 4003C000 - 4003FFFF CAN AF registers
    14 40038000 - 4003BFFF CAN AF RAM
    13 40034000 - 40037FFF ADC
    12 40030000 - 40033FFF SSP1
    11 4002C000 - 4002FFFF pin connect
    10 40028000 - 4002BFFF GPIO interrupts
    9 40024000 - 40027FFF RTC + backup registers
    8 40020000 - 40023FFF SPI
    7 4001C000 - 4001FFFF I2C0
    6 40018000 - 4001BFFF PWM1
    5 40014000 - 40017FFF Reserved
    4 40010000 - 40013FFF UART1
    3 4000C000 - 4000FFFF UART0
    2 40008000 - 4000BFFF TIMER1
    1 40004000 - 40007FFF TIMER0
    0 40000000 - 40003FFF WDT
    AHB GPIO 2009C000 - 200BFFFF  
    RAM 2007C0000 - 20083FFF  
      8kB boot ROM 1FFFF0000 - 1FFF1FFF  
    32kB static RAM 10000000 - 10007FFF  
    512kB on chip flash 00000000 - 0007FFFF  

    NXP LPC1768 Peripheral Memory Map


  5. Detailed GPIO Register Address Map
  6. To monitor/control the LPC1768 GPIO there are 5 registers mapped as shown below. The operation of the different registers will be described in the following sections.

    ../NXP_GPIO_002.gif

    Address map for LPC1768 GPIO Registers

    At power up each pin will be by default dedicated to the digital input-output function. However other alternate functions may be selected using the PINSEL registers in the Pin Connect Block.

    ../NXP_GPIO_004.gif

    Address map for the LPC1768 Pin Select Registers

    If the GPIO is programmed as an input (via the FIODIR register) there is the choice of pull-up/pull-down or no resistors programmed via the Pin Mode registers illustrated in the figure below.

    ../NXP_GPIO_003.gif

    Address map for the LPC1768 Pin Mode registers.

    If the GPIO is programmed as an output (via the FIODIR register) there is the choice of a push-pull or an open drain configuration programmed via the Pin Mode Open Drain registers illustrated in the figure below.

    ../NXP_GPIO_001.gif

    Address map for the LPC1768 open drain mode register.


  7. Configuring the NXP LPC1768 as used in the MBED system.
  8. Following reset by default the general purpose input-output pins come up in the input state. For many micro-controllers to use the pins as inputs no further action is required.

    Associated with each pin there will be a bit in a register that will be set to configure the pin as an output. With the ARM the configuration of the input-output pins is quite flexible so the pins must be programmed to give the required functions/capability.

    In contrast to the STM devices the clock to the GPIO is enabled by default.

    Normally the configuration will be performed only once as part of initialisation routines.

    A simplified block diagram of one input-output pin for the NXP LPC1768 is given below.

    ../NXP_IOPIN.gif

    Simplified circuit representing a IO Pin for the NXP LPC1768

    By default at reset all the registers are cleared. Except for programming the direction of any output pins the default configuration will give the desired conditions for many applications so no further action will be required.

    The registers perform the following functions:

    Register Description Logic Default
    FIODIR Sets port as input/output 0:input. 1: output Pin is input
    PINMODE Enables pullup pulldown resistor. 00: Pull up 01:repeater mode 10: No pull up or pull down 11: Pull down Pull up active
    FIOMASK Masks signal to/from pin. 0: Signal enabled. 1: signal masked Signals all enabled
    PINSEL Selects function to drive output 00: GPIO 01: AF1 selected 10: AF2 selected 11: AF3 selected GPIO selected
    PINMODE_OD Open drain on driver transistors. 0: Push pull 1: Open drain Push pull output
    PIN Fast I/P Read pin.   Pin input
    SET Set output pin 0: no effect 1: Sets output if PINDIR set No effect. Pin an input.
    CLEAR Clears output pin. 0: no effect. 1: Clears output if PINDIR set No effect. Pin an input

     

    The registers are distributed across two blocks.

    1. Pin Control Block: PINSEL, PINMODE and PINMODE_OD are included in the Pin Control Block. With 5 general purpose input-output ports numbered GPIO0 through GPIO4 there will be a corresponding PINMODE_OD register numbered 0 through 4. However for each port there will be two PINMODE and PINSEL registers numbered 0 through 9. PINMODE0 and PINMODE1 will configure the pull up / pull down resistors for GPIO0 with PINMODE0 configuring GPIO0 bits 0 through 15 while PINMODE1 configures GPIO0 bits 16 through 31. PINMODE2 and PINMODE3 will refer to GPIO1 bits 0-15 and bits 16-31 etc.

    Example: Enable the pull down resistor on PIN 0.16.

    Solution: The pin pull up/pull down resisters for pin 0.16 are controlled by bits 0 and 1 of register PINMODE1 which is associated with the Pin Control Block (PCON). The required code will be: See Detailed GPIO Register Address Map

    PINCON_PINMODE1 EQU 0x4002C044
         LDR R6,=PINCON_PINMODE1
         MOV R7,#3
         STR R7,[R6]

    LPC_PINCON->PINMODE1= 3;

    Example: Configure pin P1.31 as an open-drain.

    Solution: To configure P1.31 as an open drain bit 31 of PINMODE_OD1 must be set. The code will be:

    PINCON_PINMODE_OD1 EQU 0x4002C066 
         LDR R6,=PINCON_PINMODE_OD1
         MOV R7,#(1<<31)
         STR R7,[R6]

    LPC_PINCON->PINMODE_OD1= 1<<31;

    2. The GPIO Block: The remaining 5 registers, FIODIR, FIOMASK, FIOPIN. FIOSET and FIOCLR are associated with the GPIO ports.

    Example: Enable pin P1.31 as an output pin

    Solution: To change P1.31 to an output bit 31 of the FIODIR register associated with GPIO1 must be set. That is:

    GPIO1_FIODIR EQU 0x2009C020
         LDR R6,=GPIO1_FIODIR
         MOV R7,#(1<<31)
         STR R7,[R6]

    LPC_GPIO1->FIODIR = 1<<31;

    Note the differences in numbering in the above examples.

    • There is only ONE Pin Control Block so each has FIVE (TEN) registers to control each function. That is PINMODE_OD0 ... 5 for the open drain, PINMODE0 .. 9 for the pull up/pull down restors. Also registers 0..9 for PINSEL.
    • With the GPIO there are FIVE ports GPIO0..4 each with ONE register to control each function.

    Hence in the last two examples above the code is configuring PIN1.31 in both cases but the "1" is located at different points (GPIO1 vs PIN_MODE_OD1).

    The fexibility of accessing the GPIO registers may add an extra level of confusion to the naming. As illustrated below the NXP LPC1768 IO registers may be accessed as a byte, half word or word. For example bit 31 maybe tested using REG&(1<<31), REGU&(1<<15) or REG3&(1<<7). Alternatively bit 31 may be set using REG = (1<<31), REGU = (1<<15) or REG3 = (1<<7).

    ../NXP_regdefns.gif

    Example: Repeating an earlier example to enable pin P1.31 as an output pin

    Solution: To change P1.31 to an output bit 31 of the DIRection register associated with GPIO1 must be set. There are 3 alternate solutions:

    1. Treat the direction register as a 32 bit register. The code will be LPC_GPIO1->FIODIR = 1<<31;
    2. Treat the direction register as two 16 bit or half word registers. The code will be LPC_GPIO1->FIODIRH = 1<<15;
    3. Treat the direction register as four 8 bit or byte registers. The code will be LPC_GPIO1->FIODIR3 = 1<<7;

    NXP LPC1768 Input Configuration Example:

    With the MBED there are no switches to demonstrate simple inputs. However the MBED Application Board does have a joystick that may be used.

    Joystick interface to the MBED board (NXP LPC1768)

    On the application board a pull up resistor pulls the joystick to the 3.3 supply voltage. At the NXP LPC1768 the input pins by default also float high. Applying the joystick will put the two resistors in parallel and will not have any impact on the logic level - it will still be a high. The microcontroller pull down resistor must be activated for the joystick to have any effect.

    ie. to activate the pull down resistor on pin P0.16 the code will be LPC_PINCON->PINMODE1= 3;

    NXP LPC1768 Output Configuration Example

    The MBED has LEDs connected to port P1.18, P1.20, P1.21 and P1.23.

    ../NXP_BlueLED.gif

    Basic circuit of the LED Micro-controller Interface

    The following code illustrates how the LEDs may be toggled. This example was also used to perform timing measurements on the micro-controller. Since it was difficult to probe the LEDs pins P1.30 and P1.31 were also toggled These outputs are available on MBED pins 19 and 20.

     

    LPC_GPIO1->FIODIR2 |= 0xb4; //make LEDs output
    LPC_GPIO1->FIODIR3 |= 0xc0; //MBED pins 19 & 20 output
    LPC_GPIO1->FIOSET2 = 0xb4; //LEDs ON
    LPC_GPIO1->FIOSET3 = 0xC0; //Pins 19 & 20 high
    LPC_GPIO1->FIOCLR2 = 0xb4; //LEDs OFF
    LPC_GPIO1->FIOCLR3 = 0xc0; //Pins 19 & 20 low

    In this example the first two lines configure the 6 pins as outputs. The 3rd and 4th lines set the 6 pins high turning on the 4 LEDs. Note while the instruction is an assign rather than a read-modify-write instruction none of the other pins are cleared since a zero will not alter the corresponding output pin. Lines 5 and 6 clear the 6 addressed pins and have no impact on the remaining pins.


  9. Reading and writing the GPIO
  10. The input/output may be accessed as a byte, half word or word. If so the code will be a simple assign statement. However in practice the information of interest may be contained in just a single bit. While the remaining bits are not of any interest their actual values may not be known so must be masked in the case of an input read and not modified in the case of an output write. Hence the resulting code is more than a simple assign statement.

    In the case of the STM32F107 the input data will be captured in the (IDR) Input Data Register and for writes the data will be stored in the ODR (Output Data Register). These registers may be read and controlled using simple assign statements.

    stick = GPIOD->IDR; //read joystick on GPIOD
    GPIOE->ODR = 0xFF00;      //turn LEDs on GPIOE bits 8-15 ON
    GPIOE->ODR = 0x0000; //turn LEDs on GPIOE bits 8-15 OFF

    In general each input-output pin will monitor/control different independent operations so the chosen pins must be isolated from the remaining pins.

    As illustrated the variable "stick" will not only contain the values of the joystick but also the values of the other pins. The program firmware can make no assumptions about the values on these pins. They must be masked out as illustrated in the input examples.

    For the output assignment the LEDs on pins 8 through 15 will be turned on and off as expected. However if the pins 0 through 7 are used to control other functions the above code will resets these pins. The firmware will need to generate code that does not alter the values on those pins. See Output examples and Atomic operations.

    The NXP LPC1768 contains SET and CLEAR registers that allow individual bits to be set and cleared independent of other bits. This is known as an ATOMIC operation. The STM devices also contain registers Bit_Reset and Bit_Set_Reset that permit atomic operations.

  11. Input Example:
  12. With the STM devices firmware must be used to mask the input. For the NXP LPC1768 in addition to firmware there is a mask register that may be used.

    NXP LPC1768 Input Example : Software Filtering

    With the MBED there are no switches to demonstrate simple inputs. However the MBED Application Board does have a joystick that may be used.

    Joystick interface to the MBED board (NXP LPC1768)

    On the application board a pull up resistor pulls the joystick to the 3.3 supply voltage. At the NXP LPC1768 the input pins by default also float high. Applying the joystick will put the two resistors in parallel and will not have any impact on the logic level - it will still be a high. The microcontroller pull down resistors must be activated for the joystick to have any effect.

    LPC_PINCON->PINMODE1= 3; //bit 16 centre joystick
    stick = LPC_GPIO0->FIOPIN;
    stick &= 1<<16; //mask out centre joystick

    In the above program the first line will activate the pull down resistor on pin P0.16. This is the pin wired to the centre of the joystick. The second line reads the 32 bit input for port 0. Sample values were 0x27FE8FFF and 0x27FF8FFF when the centre key was pressed. The final line masks out bit 16, the centre joystick switch, and gives values of 0x00000000 or 0x00010000 (key pressed). In general the final line will be some form of test such as

    if (stick & (1<<16)) { } else { }.

    NXP LPC1768 Input using Mask Register.

    The same result as previous may be obtained using the mask register FIOMASK. Following reset all bits in FIOMASK are cleared which will enable reading all bits on the GPIO port. To mask out any bits the corresponding bits in FIOMASK must be set. For example to read only the centre key of the joystick all but bit 16 of FIOMASK must be set. That is the initialisation routine will include the statement:

    LPC_GPIO0->FIOMASK = ~(1 <<16);

    The full code will be as shown below where lines 1 and 2 will be executed once as part of the initialisation and line 3 will normally be part of a program loop.

    LPC_PINCON->PINMODE1= 3; //bit 16 centre joystick
    LPC_GPIO0->FIOMASK = ~(1 <<16); //Mask set during initialisation
    stick = LPC_GPIO0->FIOPIN; //Main program - reads 1 or 0 in bit 16

    Note this trivial example is not really practical as the remaining 31 bits of GPIO0 have been masked out.


  13. Output Atomic Operations with the NXP LPC1768
  14. It is often desirable to modify a single output bit without modifying other bits. This may be performed with read-modify-write operations (eg GPIOE->ODR |=1<<15;). One alternative is to use the Bit Reset and Bit Set-Reset registers - this is known as an Atomic Operation. For the NXP LPC1768 the output registers are atomic. In addition the mask register may be used.

    Toggling output pins using the NXP LPC1768 microcontroller.

    For the NXP LPC1768 writing to the input register FIOPIN will modify those pins programmed as outputs. This has the advantage of setting and clearing all the bits simultaneously. However this is not recomended due to the possibility of unexpected/undesirable interactions.

    Atomic Example using the MBED board.

    As illustrated below the NXP LPC1768 IO registers may be accessed as a byte, half word or word. For example bit 31 maybe tested using REG&(1<<31), REGU&(1<<15) or REG3&(1<<7). Alternatively bit 31 may be set using REG = (1<<31), REGU = (1<<15) or REG3 = (1<<7).

    ../NXP_regdefns.gif

    The MBED has LEDs connected to port P1.18, P1.20, P1.21 and P1.23. The follow code illustrates how the LEDs may be toggled. This example was also used to perform timing measurements on the microcontroller. Since it was difficult to probe the LEDs pins P1.30 and P1.31 were also toggled These outputs were available on MBED pins 19 and 20.

     

    LPC_GPIO1->FIODIR2 |= 0xb4; //make LEDs output
    LPC_GPIO1->FIODIR3 |= 0xc0; //MBED pins 19 & 20 output
    LPC_GPIO1->FIOSET2 = 0xb4; //LEDs ON
    LPC_GPIO1->FIOSET3 = 0xC0; //Pins 19 & 20 high
    LPC_GPIO1->FIOCLR2 = 0xb4; //LEDs OFF
    LPC_GPIO1->FIOCLR3 = 0xc0; //Pins 19 & 20 low

     

    In this example the first two lines configure the 6 pins as outputs. The 3rd and 4th lines set the 6 pins high turning on the 4 LEDs. Note while the instruction is an assign rather than a read-modify-write instruction none of the other pins are cleared since a zero will not alter the corresponding output pin. Lines 5 and 6 clear the 6 addressed pins and have no impact on the remaining pins.

    Output Masking and the NXP LPC1768

    In the above example all four LEDs are turned ON and OFF. The mask register FIOMASK maybe used to modify the active LEDs. For example adding the code

    LPC_GPIO1->FIOMASK2 = ~4;

    will mask out all the bits except bit 2 (weight 4) . That is only the LED corresponding to bit 2 in REG2 will be toggled in the previous program. That is pin P1.18.



  15. Bit Banding
  16. With bit banding writing a word in the bit band alias is the same as writing to a bit in the bit band area. The advantage of using the bit banding alias is that it is possible to write to a bit without impacting on any neighbouring bits.

    The figure shows the memory map for the ARM microcontrollers highlighting the bit band regions for the peripherals.

    As illustrated the ARM includes bit banding on the SRAM and the peripherals. Writing a word in the bit band alias is the same as writing to a bit in the bit band area. Note with the NXP LPC1768 the GPIO is in the high speed SRAM area.

    ../BitBand.gif

    ARM Memory Map illustrating Bit Banding

    The mapping formula to reference each word in the alias region to a bit in the bit-band region is:

    bit_word_offset = (byte_offset x 32) + (bit_number × 4)
    bit_word_addr = bit_band_base + bit_word_offset

    where:

    Bit_word_offset is the position of the target bit in the bit-band memory region.
    Bit_word_addr is the address of the word in the alias memory region that maps to the targeted bit.
    Bit_band_base is the starting address of the alias region. 0x42000000 for peripherals
                               0x22000000 for SRAM and NXP LPC1768 GPIO
    Byte_offset is the number of the byte in the bit-band region that contains the targeted bit.
    Bit_number is the bit position (0-7) of the targeted bit.

    Note the above formula apply for the STM and NXP microcontrollers.

    To calculate the alias address the base address and off sets of the registers must be known.

    GPIO Base Address

       GPIO Port       STM32F10xx       STM32F40xx      NXP LPC1768  
    A/0 0x4001 0800    0x4002 0000    0x2009 C0000
    B/1 0x4001 0C00    0x4002 0400    0x2009 C0020
    C/2 0x4001 1000    0x4002 0800    0x2009 C0040
    D/3 0x4001 1400    0x4002 0C00    0x2009 C0060
    E/4 0x4001 1800    0x4002 1000    0x2009 C0080
    F 0x4001 1C80    0x4002 1400   
    G 0x4001 2000    0x4002 1800   
    H      0x4002 1C00   
    I      0x4002 2000   

    Register Offset Address

       Offset       STM32F10xx       STM32F40xx      NXP LPC1768  
    0x00 CRL    MODER    FIODIR
    0x04 CRH    OTYPER    -
    0x08 IDR    OSPEEDR    -
    0x0C ODR    PUPDR    -
    0x10 BSRR    IDR    FIOMASK
    0x14 BRR    ODR    FIOPIN
    0x18 LCKR    BSRR    FIOSET
    0x1C      LCKR    FIOCLR
    0x20      AFRL   
    0x24      AFRH   

      Bit-banding Example. On the MBED board there is a LED wired to pin P1.23. Use the alias address to turn the LED on and off.

    Solution: To toggle the LED bit 23 of the GPIO1_FIOSET and GPIO1_FIOCLR registers will both need to be set. The base address of GPIO1 is 0x2009C020 and the offset for FIOSET 0x18.(FIOCLR will be 0x2009C03C.)

    Since GPIO registers may be addressed as bytes and half words 0x209C038 is the address of GPIO1_FIOSET0 and GPIO_FIOSETL also. Using bytes the next address is 0x2009C039 corresponding to GPIO1_FIOSET1 followed by 0x2009C03A (GPIO1_FIOSET2) and 0x2009C03B (GPIO1_FIOSET3). If half words are used 0x2009C03A corresponds to GPIO1_FIOSETU.

    ../BitBandFIOSet.gif

    Bit-band example

    To obtain the bit band alias the base address must be multiplied by 32.

    • 0x9C038 will give an alias address of 0x01380700 with the bit-band alias becomes 0x23380700 (see figure)
      Since the relevant bit is bit 23 the offset will be 23*4 = 92dec =0x5C making the target address 0x2338075C as shown.
    • Using FIOSET2 or FIOSETU as the base the bit band alias becomes 0x23380740
      For each bit the offset is 4 bytes so bit 17 becomes 0x23380744. Bit 23 will be offset by 7*4 = 28dec = 0x1C making the target address 0x2338075C as above.

    The test program will include the following code:

    LPC_GPIO1->FIODIR2 |= 0x80; //Make P1.23 an output
    int *Bit = (int *) 0x2338075C; //alias address for GPIO1_FIOSET bit 23
    int *nBit = (int *) 0x233807DC; //alias address for GPIO1_FIOCLR bit 23
    *Bit = 1; //Turn LED at P1.23 ON
    *nBit = 1; //Turn LED at P1.23 OFF

    Note: The direction register could also be set up using bit banding.


  17. Alternate Functions with the NXP LPC1768 Microcontroller
  18. Like all microcontrollers, in addition to conventional or general purpose digital input and output the ARM subsystem implements a number of specialised input output functions. In the ARM these are known as alternative functions (AF) since the normal pin function is traded for an alternative function.

    A simplified diagram of an IO pin of the NXP LPC1768 is shown:

    ../NXP_IOPIN.gif

    General diagram of an NXP LPC1768 I/O pin.

    There are 4 source/targets for the data to/from each I/O pin which is controlled by the register PINSEL which is part of the Pin Control Block. By default at reset PINSEL is cleared selecting function 1 the GPIO port. Pattern 01 selects function 2, 10 will select function 3 and 11 function 4.

    Each I/O pin will require require 2 bits to select the function. Thus register PINSEL0 will control pins P0.0 through P0.15, PINSEL1 pins P0.16 to P0.31, PINSEL2 pins P1.0 through P1.15 etc.

    Function 2 for pin P1.27 is the Clock out. This pin is controlled by bits 2*(27-16) and 2*(27-16)+1. To select function 2 the pattern 01 must be placed into bits 23,22.

    //Code for CLKOUT on pin p1.27  
    LPC_PINCON->PINSEL3 = 1<<22; //connect CLK
    LPC_SC->CLKOUTCFG = 0xf<<4; //divide by 16
    LPC_SC->CLKOUTCFG |= 1<<8; //enable cclk

    Configuring the actual or specific AF functions is discussed in the following chapters.

  19. Example: Simulating traffic lights
  20. ../Traffic_Layout.gif

    The simulated intersection and traffic lights.

    This example is based on a traffic light controller/simulator used in the Micro-controller Laboratories at RMIT Melbourne, RMIT Vietnam and anticipated to be used at RMIT Hong Kong.The design uses the MBED Application Board with the provision for driving the lights on a model intersection. Note for simplicity the lights are only either red or green - there is no amber.

    ../Traffic_2180016.jpg

    The traffic light controller as simulated on the MBED application board.

    The software is broken into four as illustrated below:

    ../LCD_Traffic_SW.gif

    Structure of traffic light controller software.

    1. The traffic controller logic.
    2. The road sensors simulated by the application board joystick and LEDs to indicate a turn request is pending.
    3. The LCD display that pictorially represents the intersection.
    4. A model of the intersection that includes the traffic lights.

    Communication between each block is via a series of functions that isolate the implementation details of each block from the other blocks.

    Functions Controller Sensor LCD Model Comments
    Read_Sensor( ) Request Input     Controller requests a read of joystick
    If a request this is placed in status register using an OR operation
    ie rapid pulse is remembered.
    s=NReq_status(), s=WReq_status(),s=SReq_status(),s=EReq_status() Request Output     Status of joystick returned to controller.
    Returned value will be REQ or NREQ
    In this example this function will also clear status
    NReq( ),EReq( ),SReq( ),WReq( )   Output Input   Sensor gives request status to LCD
    Parameter will be REQ or NREQ
    North_Light( ),SN_Light(),East_Light(),WE_Light() Output   Input   Controller controls ahead lights on LCD
    Parameter will be RED, GREEN
    NorthA_Light( ),EastA_Light( ),SouthA_Light( ),WestA_Light( ) Output   Input   Controller controls turning (arrow) lights on LCD
    Parameter will be RED, GREEN
    Serial Data Output     Input Controller controls individual lights on model.

    Note definitions: Direction is the traffic heading.

    Summary of software functions for traffic light controller.

    This section is concerned with the joystick and LEDs. That is the digital input output.

    The circuit for the joystick is repeated below:

    Joystick interface to the MBED board (NXP LPC1768)

    For the example the pins will be redefined as follows:

    P0.24 right NReq Traffic going north requesting to turn east.
    P0.17 down EReq Traffic going east requesting to turn south.
    P0.15 left SReq Traffic going south requesting to turn west.
    P0.23 up WReq Traffic going west requesting to turn north.
    Initialisation Code: Init_Sensors( )

    As illustrated in the figure (see also input example) by default the input pull up resistors are active so for the joystick to operate correctly the inputs must be programmed as PULL-DOWN. This is part of the initialisation routine and is illustrated below. In addition a variable sensor is declared to save the value of the joystick/sensors.

    #include "LPC17xx.h"
    int sensor;
    void Init_Sensors( ) {
    LPC_GPIO1->FIODIR2 |= 0xb4; //LEDs
    LPC_PINCON->PINMODE0 |= 0xC0000000; //3<<30 -P0.15 PULL DOWN
    LPC_PINCON->PINMODE1 |= 3<<2; //P0.17 PULL DOWN
    LPC_PINCON->PINMODE1 |= 3<<14; //P0.23 PULL DOWN
    LPC_PINCON->PINMODE1 |= 3<<16; //P0.24 PULL DOWN
    sensor = 0;
    }

    Initialisation code for joystick and LEDs as part of the sensor/joystick software module.

    Read Sensors Code: Read_Sensors( )

    In the design the sensors will only be read when requested. The results will be ORd with a variable "sensor" simulating a car crossing a sensor but not actually stopping on the sensor. In addition the status of the joystick will be indicated on individual LEDs and the LCD display module.

    Definition Joystick Joystick Pin LED LED pin
    NReq Right P0.24 2nd top P1.5
    EReq Down P0.17 Top P1.7
    SRreq Left P0.15 3rd top P1.4
    WReq Up P0.23 Bottom P1.2

    Definitions of pins used in Read_Sensors code.

    Possible code is given below. The routines WReq( ), NWreq( ), NReq( ) and EReq( ) use the LCD so use the lights module. Hence "Lights.h" is specified as an include file.

    #include "Lights.h"
    void Read_Sensors( ) {
    sensor |= (LPC_GPIO0->FIOPIN); //OR remembers if sensor ever hit
    if (sensor & (1<<23)) {
             LPC_GPIO1->FIOSET2 = 1<<2; //WRequest
             WReq(REQ); //set request in LCD module
    }
    if (sensor & (1<<15)) {
             LPC_GPIO1->FIOSET2 = 1<<4; //NWrequest
             SReq(REQ); //set request in LCD module
    }
    if (sensor & (1<<24)) {
             LPC_GPIO1->FIOSET2 = 1<<5; //NRequest
             NReq(REQ); //set request in LCD module
    } if (sensor & (1<<17)) {
             LPC_GPIO1->FIOSET2 = 1<<7; //ERequest
             EReq(REQ); //set request in LCD module
    }
    }

    Code to read the sensors and indicate turning requests.

    Code to read the status of individual requests. s=NReq_status(), s=WReq_status(),s=SReq_status(),s=EReq_status()

    These 4 routines will return the status of the selected request. If there is an active request the request pending indicators (LED and LCD) along with the request (bit in variable sensor) will be cleared. The routines will also (first thing) re-read the sensors to ensure there are no "late arrivals."

    int NReq_status( ) {
    Read_Sensors( ); //capture late arrivals
    if (sensor & (1<<24)) { //bit 24 for SE requests
          sensor &= ~ (1<<24);
          LPC_GPIO1->FIOCLR2 = 1<<5; //Clear N Request
          NReq(NREQ); //Clear request in LCD module
          return (REQ);
    }
    else return(NREQ);
    }
    int SReq_status( ) {
    Read_Sensors( ); //capture late arrivals
    if (sensor & (1<<15)) { //bit 15 for S requests
          sensor &= ~ (1<<15);
          LPC_GPIO1->FIOCLR2 = 1<<4; //Clear S request
          SReq(NREQ); //Clear request in LCD module
          return (REQ);
    }
    else return(NREQ);
    }
    int WReq_status( ) {
    Read_Sensors( ); //capture late arrivals
    if (sensor & (1<<23)) { //bit 24 for W requests
          sensor &= ~ (1<<23);
          LPC_GPIO1->FIOCLR2 = 1<<2; //Clear W Request
          WReq(NREQ); //Clear request in LCD module
          return (REQ);
    }
    else return(NREQ);
    }
    int EReq_status( ) {
    Read_Sensors( ); //capture late arrivals
    if (sensor & (1<<17)) { //bit 17 for East requests
          sensor &= ~ (1<<17);
          LPC_GPIO1->FIOCLR2 = 1<<7; //Clear East Request
          EReq(NREQ); //Clear request in LCD module
          return (REQ);
    }
    else return(NREQ);
    }

    Routines to return sensor/joystick status. Also clear status and visual status indicators.

    Header File: "sensors.h"

    Associated with the previous code will be a header file that documents the routines that will be used by other files.

    void Init_Sensors(void);
    void Read_Sensors(void);
    int NReq_status(void);
    int WReq_status(void);
    int SReq_status(void);
    int EReq_status(void);

    Header file: "sensors.h"

    Test Code

    This page is concerned with the input-output, that is the joystick and the LEDs. The LCD and traffic controller routines are considered in a page dedicated to the LCD. For testing two minimum codes "traffic.c" and "lights.c" are required.

    #include "LPC17xx.h"
    #include "sensors.h"
    #define State_Time 100000 //100,000 good value for testing joystick
    void SystemInit( ){ //required by compiler
    }
    void Monitor_Sensors(int Count ) {
    int i;
    for (i=0; i&LT;Count; i++)
            Read_Sensors( );
    }
    int main( ) {
    int s;
    Init_Sensors( );
    while (1) {
          Monitor_Sensors(State_Time);
          s = NReq_status(); //dummy read
          s = SReq_status(); //dummy read
          s = EReq_status(); //dummy read
          s = WReq_status(); //dummy read
    }
    }

    Mininum code for traffic.c to exercise sensor routines.

    The routine "traffic.c" will invoke the sensors initialisation routine, it will continuously monitor the status of the joystick for a time(**) determined by the value State_Time and will read the status of the individual joystick requests. Reading the status will clear the LEDs.

    ** Note The value State_Time actually specifies the number of times the joystick is read. If the key has been pressed the Read_Sensors( ) function initiates further actions thus increasing the execution time.This time will be further increased as the code for the LCD is added. Since this page is basically concerned with reading the digital-input operations no further action is taken. However for a real traffic light the time of the routine Monitor_Sensors( ) will need to be determined by for example the real-time clock.

    The following empty functions will be provided to permit the code to run.

    #include "LPC17xx.h"
    #include "Lights.h"
    void WReq(int but) { };
    void NReq(int but) { };
    void NWreq(int but){ };
    void EReq(int but){ };
    void WReq(int but);
    void NReq(int but);
    void NWreq(int but);
    void EReq(int but);

    Minimun code for "Lights.c" and "Lights.h" to allow testing the code "sensor.c"

    At this point toggling the joystick will pulse the corresponding LED. The implementation of the code for the LCD display is discussed on a separate page.


Generated by John Kneen RMIT University Monday, October 14, 2013. Updated Wednesday, February 19, 2014


ċ
Traffic.zip
(7k)
John Kneen,
Feb 23, 2014, 8:04 PM
Comments