Library used during 1 day workshops presented by Skool and ARM Hungary in 2015.

Fork of Skool_wkshp_lib2015 by Laszlo Vagasi

keypad.cpp

Committer:
lvagasi
Date:
2015-10-01
Revision:
1:68d1a8c4970b
Parent:
0:3ad0af8abf43

File content as of revision 1:68d1a8c4970b:

#include "mbed.h"
#include "keypad.h"

GPIO_InitTypeDef keypadInit;
volatile uint32_t Index = 0xFF;
volatile uint32_t new_key = 0;


void EXTI9_5_IRQHandler(void) {
    HAL_NVIC_DisableIRQ(EXTI9_5_IRQn);
    if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_5) != 0) {
        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_5);
        HAL_GPIO_EXTI_Callback(0);
    } else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_6) != 0) {
        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_6);
        HAL_GPIO_EXTI_Callback(1);
    } else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_7) != 0) {
        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_7);
        HAL_GPIO_EXTI_Callback(4);
    } else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_8) != 0) {
        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_8);
        HAL_GPIO_EXTI_Callback(2);
    } else if (__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_9) != 0) {
        __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_9);
        HAL_GPIO_EXTI_Callback(3);
    }
    HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_RESET);  // All cols are driven Low for resume IRQ operation
    HAL_NVIC_ClearPendingIRQ(EXTI9_5_IRQn);
}

void HAL_GPIO_EXTI_Callback(uint16_t pin) {
    int col;
    int temp;

    keypadInit.Pin = rows[0] | rows[1] | rows[2] | rows[3];
    keypadInit.Mode = GPIO_MODE_INPUT;
    keypadInit.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOC, &keypadInit);
    for (col = 0; col < ncols; col++) {
        HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);  // All cols are driven High
        HAL_GPIO_WritePin(GPIOC, cols[col], GPIO_PIN_RESET);                  // 1 col is driven Low
        wait_ms(25);
        temp = (GPIOC->IDR & 0x0360);
        switch (temp) {
            case 0x0340: Index = col;
                         break;
            case 0x0320: Index = 4 + col;
                         break;
            case 0x0260: Index = 8 + col;
                         break;
            case 0x0160: Index = 12 + col;
                         break;
            default:     Index = 0xFF;
                         break;
        }
        if (Index != 0xFF) {
            break;
        }
    }
    // Wait for the release of the key
    while ((GPIOC->IDR & 0x0360) != 0x0360) {}
    new_key++;
}

void Init_keypad(void) {
    __GPIOC_CLK_ENABLE();
    keypadInit.Pin = cols[0] | cols[1] | cols[2];
    keypadInit.Mode = GPIO_MODE_OUTPUT_OD;
    keypadInit.Pull = GPIO_NOPULL;
    keypadInit.Speed = GPIO_SPEED_MEDIUM;
    HAL_GPIO_Init(GPIOC, &keypadInit);

    HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);
    HAL_GPIO_WritePin(GPIOC, cols[2], GPIO_PIN_RESET);

    keypadInit.Pin = rows[0] | rows[1] | rows[2] | rows[3];
    keypadInit.Mode = GPIO_MODE_INPUT;
    keypadInit.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOC, &keypadInit);
    keypadInit.Pin = rows[3];
    keypadInit.Mode = GPIO_MODE_IT_FALLING;
    keypadInit.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOC, &keypadInit);
    NVIC_SetVector(EXTI9_5_IRQn, (uint32_t)EXTI9_5_IRQHandler);
    HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
}

int Poll_keypad_vert(void) {
    int temp;
    int retval = 0xFF;

    keypadInit.Pin = rows[0] | rows[1] | rows[2] | rows[3];
    keypadInit.Mode = GPIO_MODE_INPUT;
    keypadInit.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOC, &keypadInit);
    //Poll the keys
    while (retval == 0xFF) {
        HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOC, cols[1], GPIO_PIN_RESET);
        wait_ms(25);
        temp = (GPIOC->IDR & 0x0360);
        switch (temp) {
            case 0x0340: retval = 0x01;
                         break;
            case 0x0320: retval = 0x05;
                         break;
            case 0x0260: retval = 0x09;
                         break;
            case 0x0160: retval = 0x0D;
                         break;
            default:     retval = 0xFF;
                         break;
        }
        HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOC, cols[2], GPIO_PIN_RESET);
        wait_ms(25);
        temp = (GPIOC->IDR & 0x0360);
        if (temp == 0x0160) {retval = 0x0E;}
    }
    // Wait for the release of the key
    HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);
    if (retval < 0x0E) {
        HAL_GPIO_WritePin(GPIOC, cols[1], GPIO_PIN_RESET);
    } else {
        HAL_GPIO_WritePin(GPIOC, cols[2], GPIO_PIN_RESET);
    }
    while ((GPIOC->IDR & 0x0360) != 0x0360) {}
    return retval;
}

int Poll_keypad_yesno(void) {
    int retval = 0xFF;

    keypadInit.Pin = rows[0] | rows[1] | rows[2] | rows[3];
    keypadInit.Mode = GPIO_MODE_INPUT;
    keypadInit.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOC, &keypadInit);

    while (retval == 0xFF) {
        HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOC, cols[0], GPIO_PIN_RESET);
        wait_ms(25);
        if ((GPIOC->IDR & 0x0200) == 0x0000) retval = 0x0C;
        HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOC, cols[2], GPIO_PIN_RESET);
        wait_ms(25);
        if ((GPIOC->IDR & 0x0200) == 0x0000) retval = 0x0E;
    }
    // Wait for the release of the key
    HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);
    if (retval == 0x0C) {
        HAL_GPIO_WritePin(GPIOC, cols[0], GPIO_PIN_RESET);
    } else {
        HAL_GPIO_WritePin(GPIOC, cols[2], GPIO_PIN_RESET);
    }
    while ((GPIOC->IDR & 0x0360) != 0x0360) {}
    return retval;
}

int Poll_keypad_full(void) {
    int col, temp;
    int retval = 0xFF;

    keypadInit.Pin = rows[0] | rows[1] | rows[2] | rows[3];
    keypadInit.Mode = GPIO_MODE_INPUT;
    keypadInit.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOC, &keypadInit);
    //Poll the keys
    while (retval == 0xFF) {
        for (col = 0; col < ncols; col++) {
            HAL_GPIO_WritePin(GPIOC, cols[0] | cols[1] | cols[2], GPIO_PIN_SET);  // All cols are driven High
            HAL_GPIO_WritePin(GPIOC, cols[col], GPIO_PIN_RESET);                  // 1 col is driven Low
            wait_ms(25);
            temp = (GPIOC->IDR & 0x0360);
            switch (temp) {
                case 0x0340: retval = col;
                             break;
                case 0x0320: retval = 4 + col;
                             break;
                case 0x0260: retval = 8 + col;
                             break;
                case 0x0160: retval = 12 + col;
                             break;
                default:     retval = 0xFF;
                             break;
            }
            if (retval != 0xFF) {
                break;
            }
        }
    }
    // Wait for the release of the key
    while ((GPIOC->IDR & 0x0360) != 0x0360) {}
    return Keytable[retval];
}