HP Forums

Full Version: monic part 2: connecting the keypad
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Previous: monic part 1: connecting the display

This thread shows how to connect a 4x4 matrix keypad and two push buttons. The keypad and push buttons are part of a virtual 6 column, 8 row matrix keypad to be added in the future.

A typical 4x4 matrix keypad has the following pinout:

[Image: 50028414746_935fedb522_z.jpg]

[Image: 50028676562_5f599e20c5_z.jpg]

Thus 8 pins are required to connect the keypad: 4 pins for the rows and 4 for the columns. Also 4 pins are required for the two push buttons. Since 10 pins are used for the display this gives a total of 22 GPIO pins.

However the EVK has only 16 GPIO pins, so the pins connected to D2-D7 on the display are also connected to the rows of the keypad and the push buttons:

[Image: 50042024928_34234800d8_z.jpg]

[Image: 50042560691_59d14d3b0e_z.jpg]

For some reason certain GPIO pins configured as inputs were being pulled low, even with internal pull-up resistors activated. For this reason the following changes (in bold) were made to the connections between the display and EVK:

[Image: 50035351923_a7c6fca3a6_z.jpg]

The connections between the keypad/push button input pins and EVK are:

[Image: 50042803466_4120238ba6_z.jpg]

The pins are reconfigured in the Config Tools as per the table below:

[Image: 50042981677_a086eb9946_z.jpg]
[Image: 50042166648_c3ca334f44_z.jpg]

The header file “display.h” was moved to the “display” folder and the “header” folder in "source" deleted. A new folder “keypad” was created in "source" and a header file “keypad.h” placed in it.

Therefore #include "../header/display.h" at the beginning of "GLCD.c" is changed to #include "display.h".

"keypad.h" is:

Code:

#define keyHeld  38

Replace the code in "HX8357D.c" with:

Code:

//Port of Adafruit code to i.MX RT1010

/*Copyright (c) 2013 Adafruit Industries.  All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.*/

//includes

#include <stdint.h>
#include <stdbool.h>

#include "board.h"

#include "pin_mux.h"
#include "clock_config.h"

#include "display.h"

//variables

extern int width;
extern int height;

//functions

void writeRegister32(uint8_t, uint32_t);
void writeRegister8(uint8_t, uint8_t);
void setAddrWindow(int, int, int, int);
void flood(uint16_t, uint32_t);
void setLR(void);
void writeRegisterPair(uint8_t, uint8_t, uint16_t);
void displayPortWrite(unsigned int);
void delayms(unsigned int);

///////////////////////////////////////////////////////////////////////////////

void initDisp(void) {
    uint8_t i;

    GPIO_PinWrite(BOARD_INITPINS_WR_GPIO, BOARD_INITPINS_WR_PIN, 1U);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(0x00);
    for (i = 0; i < 3; i++) displayPortWrite(0x00);

    //write to LCD registers

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_SWRESET);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357D_SETC);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0xFF);
    displayPortWrite(0x83);
    displayPortWrite(0x57);

    delayms(250);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_SETRGB);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x00);
    displayPortWrite(0x00);
    displayPortWrite(0x06);
    displayPortWrite(0x06);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357D_SETCOM);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x25);                                                           //-1.52V

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_SETOSC);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x68);                                                           //Normal mode 70Hz, Idle mode 55 Hz

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_SETPANEL);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x05);                                                           //BGR, gate direction swapped

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_SETPWR1);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x00);
    displayPortWrite(0x15);
    displayPortWrite(0x1C);
    displayPortWrite(0x1C);
    displayPortWrite(0x83);
    displayPortWrite(0xAA);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357D_SETSTBA);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x50);
    displayPortWrite(0x50);
    displayPortWrite(0x01);
    displayPortWrite(0x3C);
    displayPortWrite(0x1E);
    displayPortWrite(0x08);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357D_SETCYC);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x02);
    displayPortWrite(0x40);
    displayPortWrite(0x00);
    displayPortWrite(0x2A);
    displayPortWrite(0x2A);
    displayPortWrite(0x0D);
    displayPortWrite(0x78);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_COLMOD);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x55);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_MADCTL);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0xC0);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_TEON);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x00);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_TEARLINE);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(0x00);
    displayPortWrite(0x02);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_SLPOUT);

    delayms(150);

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(HX8357_DISPON);

    delayms(50);
}

void setAddrWindow(int x1,int y1, int x2, int y2) {
    uint32_t t;

    t = x1;
    t <<= 16;
    t |= x2;
    writeRegister32(ILI9341_COLADDRSET, t);                                    // HX8357D uses same registers!
    t = y1;
    t <<= 16;
    t |= y2;
    writeRegister32(ILI9341_PAGEADDRSET, t);                                   // HX8357D uses same registers!
}

void writeRegister8(uint8_t a, uint8_t d) {
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(a);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(d);
}

void writeRegister32(uint8_t r, uint32_t d) {
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(r);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    __asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");

    displayPortWrite(d >> 24);
    __asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");

    displayPortWrite(d >> 16);
    __asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");

    displayPortWrite(d >> 8);
    __asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");__asm volatile ("nop");

    displayPortWrite(d);
}

void flood(uint16_t colour, uint32_t len) {
    uint16_t blocks;
    uint8_t  i, hi = colour >> 8, lo = colour;

    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND

    displayPortWrite(HX8357_RAMWR);

    // Write first pixel normally, decrement counter by 1
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(hi);
    displayPortWrite(lo);
    len--;

    blocks = (uint16_t)(len / 64);                                             //64 pixels/block
    if(hi == lo) {
        // High and low bytes are identical.  Leave prior data
        // on the port(s) and just toggle the write strobe.
        while(blocks--) {
            i = 16;                                                            //64 pixels/block/4 pixels/pass
            do {
                displayPortWrite(lo); displayPortWrite(lo); displayPortWrite(lo); displayPortWrite(lo);    //2 bytes/pixel
                displayPortWrite(lo); displayPortWrite(lo); displayPortWrite(lo); displayPortWrite(lo);    //x 4 pixels
            } while(--i);
        }
        // Fill any remaining pixels (1 to 64)
        for(i = (uint8_t)len & 63; i--; ) {
            displayPortWrite(lo);
            displayPortWrite(lo);
        }
    } else {
        while(blocks--) {
            i = 16; // 64 pixels/block / 4 pixels/pass
            do {
                displayPortWrite(hi); displayPortWrite(lo); displayPortWrite(hi); displayPortWrite(lo);
                displayPortWrite(hi); displayPortWrite(lo); displayPortWrite(hi); displayPortWrite(lo);
            } while(--i);
        }
        for(i = (uint8_t)len & 63; i--; ) {
            displayPortWrite(hi);
            displayPortWrite(lo);
        }
    }
}

void drawFastVLine(int16_t x, int16_t y, int16_t length, uint16_t colour) {
    int16_t y2;

    // Initial off-screen clipping
    if((length <= 0) || (x<0) || ( x>= width) || (y>= height) || ((y2 = (y+length-1)) < 0)) return;
    if(y < 0) {                                                                // Clip top
        length += y;
        y = 0;
    }

    if(y2 >= height) {                                                      // Clip bottom
        y2 = height - 1;
        length  = y2 - y + 1;
    }

    setAddrWindow(x, y, x, y2);
    flood(colour, length);
    setLR();
}

void drawFastHLine(int16_t x, int16_t y, int16_t length, uint16_t colour) {
    int16_t x2;

    // Initial off-screen clipping
    if((length <= 0) || (y<0) || (y>= height) || (x>= width) || ((x2 = (x+length-1)) <  0)) return;
    if(x < 0) {                                                                // Clip left
        length += x;
        x = 0;
    }
    if(x2 >= width) {                                                       // Clip right
        x2 = width - 1;
        length = x2 - x + 1;
    }

    setAddrWindow(x, y, x2, y);
    flood(colour, length);
    setLR();
}

void setLR(void) {
    writeRegisterPair(HX8347G_COLADDREND_HI, HX8347G_COLADDREND_LO, width  - 1);
    writeRegisterPair(HX8347G_ROWADDREND_HI, HX8347G_ROWADDREND_LO, height - 1);
}

void writeRegisterPair(uint8_t aH, uint8_t aL, uint16_t d) {
    uint8_t hi = (d) >> 8, lo = (d);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(aH);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(hi);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(aL);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(lo);
}

void drawPixel(int16_t x, int16_t y, uint16_t colour) {

    // Clip
    if((x < 0) || (y < 0) || (x >= width) || (y >= height)) return;

    setAddrWindow(x, y, width-1, height-1);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 0U);                                 //COMMAND
    displayPortWrite(0x2C);
    GPIO_PinWrite(BOARD_INITPINS_CD_PERIPHERAL, BOARD_INITPINS_CD_CHANNEL, 1U);                           //DATA
    displayPortWrite(colour >> 8);
    displayPortWrite(colour);
}

void setRotation(uint8_t x) {
    uint8_t t;

    x = (x & 3);

    switch (x) {
    case 0:
    case 2:
        width = TFTWIDTH;
        height = TFTHEIGHT;
        break;
    case 1:
    case 3:
        width = TFTHEIGHT;
        height = TFTWIDTH;
        break;
    }

    //HX8357D uses same registers as 9341 but different values
    switch (x) {
    case 2:
        t = HX8357B_MADCTL_RGB;
        break;
    case 3:
        t = HX8357B_MADCTL_MX | HX8357B_MADCTL_MV | HX8357B_MADCTL_RGB;
        break;
    case 0:
        t = HX8357B_MADCTL_MX | HX8357B_MADCTL_MY | HX8357B_MADCTL_RGB;
        break;
    case 1:
        t = HX8357B_MADCTL_MY | HX8357B_MADCTL_MV | HX8357B_MADCTL_RGB;
        break;
    }
    writeRegister8(ILI9341_MADCTL, t);                                         //MADCTL

    // For 8357, init default full-screen address window:
    setAddrWindow(0, 0, width - 1, height - 1);
}

void displayPortWrite(unsigned int x) {
    uint32_t setBitMask;
    uint32_t clrBitMask;

    setBitMask = ((x & 0x01) << 11) | ((x & 0x02) << (15-1)) | ((x & 0x04) << (16-2)) | ((x & 0x08) << (17-3)) | ((x & 0x10) << (18-4)) | ((x & 0x20) << (20-5)) | ((x & 0x40) << (21-6)) | ((x & 0x80) << (23-7));
    clrBitMask = ((~x & 0x01) << 11) | ((~x & 0x02) << (15-1)) | ((~x & 0x04) << (16-2)) | ((~x & 0x08) << (17-3)) | ((~x & 0x10) << (18-4)) | ((~x & 0x20) << (20-5)) | ((~x & 0x40) << (21-6)) | ((~x & 0x80) << (23-7));

    GPIO_PortSet(GPIO1, setBitMask);
    GPIO_PortClear(GPIO1, clrBitMask);

    GPIO_PinWrite(BOARD_INITPINS_WR_GPIO, BOARD_INITPINS_WR_PIN, 0U);
    GPIO_PinWrite(BOARD_INITPINS_WR_GPIO, BOARD_INITPINS_WR_PIN, 1U);
}

Replace the code in "monic.c" with:

Code:

//monic 1.0

//includes

#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "MIMXRT1011.h"
#include "fsl_debug_console.h"

#include <stdbool.h>
#include "display/display.h"
#include "keypad/keypad.h"

//variables

uint16_t keyNumber;
uint16_t keyHeldCtr;

int16_t xCoordinate;
int16_t yCoordinate;
uint16_t fontColour;

int width;
int height;

uint8_t const *fontData;
uint32_t const *fontOffset;

int16_t xCoordinateCursor;
int16_t yCoordinateCursor;

uint8_t size;

extern uint8_t AdafruitClassicData[];

_Bool shift;

//functions

void initDisp(void);
void setRotation(uint8_t);
void fillScreen(uint16_t);
void fillRect(int16_t, int16_t, int16_t, int16_t, uint16_t);
void printString(char*);

void scanKp(void);
_Bool scanColumn(void);

void delay1ms(void);
void delayms(unsigned int);

void delay1us(void);
void delayus(unsigned int);

int main(void) {

#ifdef FIXED_WIDTH_FONT
    fontData = AdafruitClassicData;
    size = 4;
#else
    //fontData = fontVW_1data;           //variable-width font data
    //fontOffset = fontVW_1Offset;
#endif

      BOARD_InitPins();
    BOARD_BootClockRUN();
    BOARD_InitDebugConsole();

    SysTick->CTRL = 0;                                                         //disable SysTick

    initDisp();
    setRotation(3);
    fillScreen(BLACK);

    fontColour = BLUE;
    xCoordinate = 130;
    yCoordinate = 0;
    printString("monic 1.0");

    fontColour = GREEN;
    xCoordinate = 0;
    yCoordinate = 29;
    printString("key pressed:");

    fontColour = RED;
    size = 3;
    xCoordinate = 0;
    yCoordinate = 64;

    while (1) {
        scanKp();
        if (xCoordinate > 400) {
            xCoordinate = 0;
            yCoordinate +=24;
            if (yCoordinate > 294) {
                yCoordinate = 64;
                fillRect(0, 64, 480, 256, BLACK);
            }
        }
        switch (keyNumber) {
        case 0:
            if (keyHeldCtr == keyHeld) printString("0 H,");
            else printString("0,");
            break;
        case 1:
            if (keyHeldCtr == keyHeld) printString("1 H,");
            else printString("1,");
            break;
        case 2:
            if (keyHeldCtr == keyHeld) printString("2 H,");
            else printString("2,");
            break;
        case 3:
            if (keyHeldCtr == keyHeld) printString("3 H,");
            else printString("3,");
            break;
        case 6:
            if (keyHeldCtr == keyHeld) printString("6 H,");
            else printString("6,");
            break;
        case 7:
            if (keyHeldCtr == keyHeld) printString("7 H,");
            else printString("7,");
            break;
        case 8:
            if (keyHeldCtr == keyHeld) printString("8 H,");
            else printString("8,");
            break;
        case 9:
            if (keyHeldCtr == keyHeld) printString("9 H,");
            else printString("9,");
            break;
        case 12:
            if (keyHeldCtr == keyHeld) printString("12 H,");
            else printString("12,");
            break;
        case 13:
            if (keyHeldCtr == keyHeld) printString("13 H,");
            else printString("13,");
            break;
        case 14:
            if (keyHeldCtr == keyHeld) printString("14 H,");
            else printString("14,");
            break;
        case 15:
            if (keyHeldCtr == keyHeld) printString("15 H,");
            else printString("15,");
            break;
        case 18:
            if (keyHeldCtr == keyHeld) printString("18 H,");
            else printString("18,");
            break;
        case 19:
            if (keyHeldCtr == keyHeld) printString("19 H,");
            else printString("19,");
            break;
        case 20:
            if (keyHeldCtr == keyHeld) printString("20 H,");
            else printString("20,");
            break;
        case 21:
            if (keyHeldCtr == keyHeld) printString("21 H,");
            else printString("21,");
            break;
        case 28:
            if (keyHeldCtr == keyHeld) printString("28 H,");
            else printString("28,");
            break;
        case 35:
            if (keyHeldCtr == keyHeld) printString("35 H,");
            else printString("35,");
            break;
        default:
            if (keyHeldCtr == keyHeld) printString("NF H,");
            else printString("NF,");
        }
    }
}

void delay1us(void) {
    SysTick->VAL = 0;
    SysTick->CTRL = 5;

    while((SysTick->CTRL & 0x00010000) == 0);

    SysTick->CTRL = 0;
}

void delayus(unsigned int max) {
    unsigned int i;

    SysTick->LOAD = 0x000001F4;                                                //reload value for 1us

    for (i=0; i<max; i++) delay1us();
}

void delay1ms(void) {
    SysTick->VAL = 0;
    SysTick->CTRL = 5;

    while((SysTick->CTRL & 0x00010000) == 0);

    SysTick->CTRL = 0;
}

void delayms(unsigned int max) {
    unsigned int i;

    SysTick->LOAD = 0x0007A120;                                                //reload value for 1ms

    for (i=0; i<max; i++) delay1ms();
}

void scanKp(void) {

    GPIO_PinWrite(BOARD_INITPINS_D0_PERIPHERAL, BOARD_INITPINS_D0_CHANNEL, 0U);
    GPIO_PinWrite(BOARD_INITPINS_D1_PERIPHERAL, BOARD_INITPINS_D1_CHANNEL, 0U);
    GPIO_PinWrite(BOARD_INITPINS_D2_PERIPHERAL, BOARD_INITPINS_D2_CHANNEL, 0U);
    GPIO_PinWrite(BOARD_INITPINS_D3_PERIPHERAL, BOARD_INITPINS_D3_CHANNEL, 0U);
    GPIO_PinWrite(BOARD_INITPINS_D4_PERIPHERAL, BOARD_INITPINS_D4_CHANNEL, 0U);
    GPIO_PinWrite(BOARD_INITPINS_D5_PERIPHERAL, BOARD_INITPINS_D5_CHANNEL, 0U);
    GPIO_PinWrite(BOARD_INITPINS_D6_PERIPHERAL, BOARD_INITPINS_D6_CHANNEL, 0U);
    GPIO_PinWrite(BOARD_INITPINS_D7_PERIPHERAL, BOARD_INITPINS_D7_CHANNEL, 0U);

    delayus(100);

    while ((GPIO_PinRead(BOARD_INITPINS_COL0_PERIPHERAL, BOARD_INITPINS_COL0_CHANNEL) == 0) ||
           (GPIO_PinRead(BOARD_INITPINS_COL1_PERIPHERAL, BOARD_INITPINS_COL1_CHANNEL) == 0) ||
           (GPIO_PinRead(BOARD_INITPINS_COL2_PERIPHERAL, BOARD_INITPINS_COL2_CHANNEL) == 0) ||
           (GPIO_PinRead(BOARD_INITPINS_COL3_PERIPHERAL, BOARD_INITPINS_COL3_CHANNEL) == 0) ||
           (GPIO_PinRead(BOARD_INITPINS_COL4_PERIPHERAL, BOARD_INITPINS_COL4_CHANNEL) == 0) ||
           (GPIO_PinRead(BOARD_INITPINS_COL5_PERIPHERAL, BOARD_INITPINS_COL5_CHANNEL) == 0)) {     //wait for key to be released
    };

    delayms(2);  //debounce

    while ((GPIO_PinRead(BOARD_INITPINS_COL0_PERIPHERAL, BOARD_INITPINS_COL0_CHANNEL)) &&
           (GPIO_PinRead(BOARD_INITPINS_COL1_PERIPHERAL, BOARD_INITPINS_COL1_CHANNEL)) &&
           (GPIO_PinRead(BOARD_INITPINS_COL2_PERIPHERAL, BOARD_INITPINS_COL2_CHANNEL)) &&
           (GPIO_PinRead(BOARD_INITPINS_COL3_PERIPHERAL, BOARD_INITPINS_COL3_CHANNEL)) &&
           (GPIO_PinRead(BOARD_INITPINS_COL4_PERIPHERAL, BOARD_INITPINS_COL4_CHANNEL)) &&
           (GPIO_PinRead(BOARD_INITPINS_COL5_PERIPHERAL, BOARD_INITPINS_COL5_CHANNEL))) {     //wait for key to be pressed
    };

    GPIO_PinWrite(BOARD_INITPINS_D0_PERIPHERAL, BOARD_INITPINS_D0_CHANNEL, 1U);
    GPIO_PinWrite(BOARD_INITPINS_D1_PERIPHERAL, BOARD_INITPINS_D1_CHANNEL, 1U);
    GPIO_PinWrite(BOARD_INITPINS_D2_PERIPHERAL, BOARD_INITPINS_D2_CHANNEL, 1U);
    GPIO_PinWrite(BOARD_INITPINS_D3_PERIPHERAL, BOARD_INITPINS_D3_CHANNEL, 1U);
    GPIO_PinWrite(BOARD_INITPINS_D4_PERIPHERAL, BOARD_INITPINS_D4_CHANNEL, 1U);
    GPIO_PinWrite(BOARD_INITPINS_D5_PERIPHERAL, BOARD_INITPINS_D5_CHANNEL, 1U);
    GPIO_PinWrite(BOARD_INITPINS_D6_PERIPHERAL, BOARD_INITPINS_D6_CHANNEL, 1U);

    while (1) {
        delayms(2);  //debounce

        keyNumber = 0;

        //scan row A - bottom of 4x4 matrix keypad
        GPIO_PinWrite(BOARD_INITPINS_D0_PERIPHERAL, BOARD_INITPINS_D0_CHANNEL, 1U);
        GPIO_PinWrite(BOARD_INITPINS_D7_PERIPHERAL, BOARD_INITPINS_D7_CHANNEL, 0U);
        delayus(100);

        if (scanColumn()) break;

        //scan row B
        GPIO_PinWrite(BOARD_INITPINS_D7_PERIPHERAL, BOARD_INITPINS_D7_CHANNEL, 1U);
        GPIO_PinWrite(BOARD_INITPINS_D6_PERIPHERAL, BOARD_INITPINS_D6_CHANNEL, 0U);
        delayus(100);

        if (scanColumn()) break;

        //scan row C
        GPIO_PinWrite(BOARD_INITPINS_D6_PERIPHERAL, BOARD_INITPINS_D6_CHANNEL, 1U);
        GPIO_PinWrite(BOARD_INITPINS_D5_PERIPHERAL, BOARD_INITPINS_D5_CHANNEL, 0U);
        delayus(100);

        if (scanColumn()) break;

        //scan row D - top row of 4x4 matrix keypad
        GPIO_PinWrite(BOARD_INITPINS_D5_PERIPHERAL, BOARD_INITPINS_D5_CHANNEL, 1U);
        GPIO_PinWrite(BOARD_INITPINS_D4_PERIPHERAL, BOARD_INITPINS_D4_CHANNEL, 0U);
        delayus(100);

        if (scanColumn()) break;

        //scan row E
        GPIO_PinWrite(BOARD_INITPINS_D4_PERIPHERAL, BOARD_INITPINS_D4_CHANNEL, 1U);
        GPIO_PinWrite(BOARD_INITPINS_D3_PERIPHERAL, BOARD_INITPINS_D3_CHANNEL, 0U);
        delayus(100);

        if (scanColumn()) break;

        //scan row F
        GPIO_PinWrite(BOARD_INITPINS_D3_PERIPHERAL, BOARD_INITPINS_D3_CHANNEL, 1U);
        GPIO_PinWrite(BOARD_INITPINS_D2_PERIPHERAL, BOARD_INITPINS_D2_CHANNEL, 0U);
        delayus(100);

        if (scanColumn()) break;

        //scan row G
        GPIO_PinWrite(BOARD_INITPINS_D2_PERIPHERAL, BOARD_INITPINS_D2_CHANNEL, 1U);
        GPIO_PinWrite(BOARD_INITPINS_D1_PERIPHERAL, BOARD_INITPINS_D1_CHANNEL, 0U);
        delayus(100);

        if (scanColumn()) break;

        //scan row H
        GPIO_PinWrite(BOARD_INITPINS_D1_PERIPHERAL, BOARD_INITPINS_D1_CHANNEL, 1U);
        GPIO_PinWrite(BOARD_INITPINS_D0_PERIPHERAL, BOARD_INITPINS_D0_CHANNEL, 0U);
        delayus(100);

        if (scanColumn()) break;

        break;            //keyNumber = 48, key not found
    }

    for (keyHeldCtr = 0; keyHeldCtr < keyHeld; keyHeldCtr++) {                 //determine if key held

        if ((GPIO_PinRead(BOARD_INITPINS_COL0_PERIPHERAL, BOARD_INITPINS_COL0_CHANNEL)) &&
            (GPIO_PinRead(BOARD_INITPINS_COL1_PERIPHERAL, BOARD_INITPINS_COL1_CHANNEL)) &&
            (GPIO_PinRead(BOARD_INITPINS_COL2_PERIPHERAL, BOARD_INITPINS_COL2_CHANNEL)) &&
            (GPIO_PinRead(BOARD_INITPINS_COL3_PERIPHERAL, BOARD_INITPINS_COL3_CHANNEL)) &&
            (GPIO_PinRead(BOARD_INITPINS_COL4_PERIPHERAL, BOARD_INITPINS_COL4_CHANNEL)) &&
            (GPIO_PinRead(BOARD_INITPINS_COL5_PERIPHERAL, BOARD_INITPINS_COL5_CHANNEL))) break;    //exit if key released

        delayms(30);
    }

}

_Bool scanColumn(void) {
    if (GPIO_PinRead(BOARD_INITPINS_COL0_PERIPHERAL, BOARD_INITPINS_COL0_CHANNEL)==0) return true;
    keyNumber++;
    if (GPIO_PinRead(BOARD_INITPINS_COL1_PERIPHERAL, BOARD_INITPINS_COL1_CHANNEL)==0) return true;
    keyNumber++;
    if (GPIO_PinRead(BOARD_INITPINS_COL2_PERIPHERAL, BOARD_INITPINS_COL2_CHANNEL)==0) return true;
    keyNumber++;
    if (GPIO_PinRead(BOARD_INITPINS_COL3_PERIPHERAL, BOARD_INITPINS_COL3_CHANNEL)==0) return true;
    keyNumber++;
    if (GPIO_PinRead(BOARD_INITPINS_COL4_PERIPHERAL, BOARD_INITPINS_COL4_CHANNEL)==0) return true;
    keyNumber++;
    if (GPIO_PinRead(BOARD_INITPINS_COL5_PERIPHERAL, BOARD_INITPINS_COL5_CHANNEL)==0) return true;
    keyNumber++;
    return false;
}


The test code displays the number of the key pressed (followed by "H" if the key was being held down):

[Image: 50035919691_77c8837ccd_z.jpg]

According to the datasheets the rebound time for the keys on the keypad is not more than 2ms and not more than 5ms for the Omron B3F-1052 push buttons. Using a debounce delay of 2ms gives good results - the keys can be pressed quite quickly without misses or bouncing.

Next: monic part 3: towards a handheld
Reference URL's