New work version with additional functions

Dependencies:   4DGL-UC ConfigFile MODSERIAL mbed mbos

Fork of CDU_Mbed_35 by Engravity-CDU

keyboard2.cpp

Committer:
WillemBraat
Date:
2014-08-26
Revision:
17:b3545e9d38f7
Parent:
13:d60c746c097c
Child:
20:2d6ac4577e68

File content as of revision 17:b3545e9d38f7:

/* File: keyboard2.cpp   W. Braat */
/* Keyboard chip TCA8418 control */

#include "mbed.h"
#include "MODSERIAL.h"
#include "keyboard.h"
#include "mbos.h"
#include "mbos_def2.h"
#include "pins.h"
 
const int CDU_KB_ADRS  = 0x68;  //Base address TCA8418 keypad scanner
const int I2C_ACK  = 0x00;
//const int NACK = 0x01;
 
extern int key_hit_ID;
extern mbos CDU_OS;
extern MODSERIAL SERIAL_DEBUG;
 
//CDU Keyboard communications KEYBOARD_INT
InterruptIn CDU_KB_INT( KBD_INT );  //Set CDU keyboard interrupt line
I2C CDU_I2C(I2C_SDA, I2C_SCL);         //I2C bus for keyboard/temp chip.
 
//CDU Keyboard LEDS
DigitalOut EXEC( LED_EXEC );
DigitalOut FAIL( LED_FAIL );
DigitalOut DSPY( LED_DSPY ); 
DigitalOut  MSG( LED_MSG  );
DigitalOut OFST( LED_OFST );
 
//CDU background lighting
AnalogIn BGL_POT( BACKLIGHT_SET ); //background light control potmeter
PwmOut BGL_LED( BACKLIGHT_DRIVE );   //PWM output background lighting

// ---- added by LvdK : -----------------------------------------------------------
DigitalOut Key_led( KEY_PRESSED ); // : LED 2 on Mbed board toggles when CDU key is pressed
// --------------------------------------------------------------------------------
 
void CDU_KB_COMM_INIT()
{   //initialize communication with TCA84818
    char cmd[2];
    Key_led = 0;
    cmd[0] = REG_CFG; //pointer byte to CFG register
    cmd[1] = 0x01; //data for CFG register KE_IEN set to 1
    if ( CDU_I2C.write(CDU_KB_ADRS,cmd, 2) == I2C_ACK ) //initiate write cycle and check for ACK
    {
        //intialize all registers from TCA8418 here
        cmd[0] = REG_INT_STAT; //pointer byte to Interrupt Status Register
        cmd[1] = 0x01; //Reset KE-INT flag      
        CDU_I2C.write(CDU_KB_ADRS,cmd, 2 );  //Write to Interrupt Status Register from TCA4818 
        
        //Set TCA8418 to Keypad mode
        cmd[0]=REG_KP_GPIO1; //KP_GIO1
        cmd[1]=0xFF; //Set to Keypad mode
        CDU_I2C.write(CDU_KB_ADRS,cmd, 2);
       
        cmd[0]=REG_KP_GPIO2; //KP_GIO2
        cmd[1]=0xFF; //Set to Keypad mode
        CDU_I2C.write(CDU_KB_ADRS,cmd, 2);
      
        cmd[0]=REG_KP_GPIO3; //KP_GIO3
        cmd[1]=0xFF; //Set to Keypad mode
        CDU_I2C.write(CDU_KB_ADRS,cmd, 2);
       
    }
    else
    {
        //No response from TCA8418 keyboard chip
        FAIL = 1; //Switch on FAIL indicator
    }  
}
 
void CDU_KB_GET_KEY()
{
        
    Key_led = !Key_led;  // : toggle LED 2
          
    char cmd[2];
    //Read interrupt status flag
    cmd[0] = REG_INT_STAT; //pointer byte to Interrupt Status Register
    CDU_I2C.write(CDU_KB_ADRS, cmd, 1); //initiate read cycle
    CDU_I2C.read(CDU_KB_ADRS, cmd, 1);  //read key value
    
    //Read Key Lock and Event Counter
    cmd[0] = REG_KEY_LCK_EC; //pointer byte KEY_LCK_EC
    CDU_I2C.write(CDU_KB_ADRS, cmd, 1); //initiate read cycle
    CDU_I2C.read(CDU_KB_ADRS, cmd, 1);  //read key value
          
    //Keypress --> read data from keybuffer
    cmd[0] = REG_KEY_EVENT_A; //pointer to Key Event Register KEY_EVENT_A
    CDU_I2C.write(CDU_KB_ADRS, cmd, 1); //initiate read cycle
    CDU_I2C.read(CDU_KB_ADRS, cmd, 2);  //read key value (=2 words)
    
    key_hit_ID =  int(cmd[0]);
    
        //SERIAL_DEBUG.printf("keynumber : %d,%d\r\n",key_hit_ID,cmd[1] ); // : TEST only !
 
    //Reset interrupt flag
    cmd[0] = REG_INT_STAT; //pointer byte to Interrupt Status Register
    cmd[1] = 0x01; //Reset KE-INT flag
    CDU_I2C.write(CDU_KB_ADRS,cmd, 2);
    
     //Read interrupt status flag   
    cmd[0] = 0x02; //pointer byte to Interrupt Status Register
    CDU_I2C.write(CDU_KB_ADRS, cmd, 1); //initiate read cycle
    CDU_I2C.read(CDU_KB_ADRS, cmd, 1);  //read interrupt value
   
    if ( cmd[0] == 1 )
    { //reset INT flag failed!
        while (1)
        {
            cmd[0] = 0x04; //pointer to Key Event Register KEY_EVENT_A
            CDU_I2C.write(CDU_KB_ADRS, cmd, 1); //initiate read cycle
            CDU_I2C.read(CDU_KB_ADRS, cmd, 2);  //read key value (=2 words)
       
            //Reset interrupt flag
            cmd[0] = 0x02; //pointer byte to Interrupt Status Register
            cmd[1] = 0x01; //Reset KE-INT flag
            CDU_I2C.write(CDU_KB_ADRS,cmd, 2 );
   
            //Read interrupt status flag   
            cmd[0] = 0x02; //pointer byte to Interrupt Status Register
            CDU_I2C.write(CDU_KB_ADRS, cmd, 1); //initiate read cycle
            CDU_I2C.read(CDU_KB_ADRS, cmd, 1);  //read interrupt value
           
            if ( cmd[0] == 0 ) break;
        }   
    }
} 
 
void SET_KEY_EVENT()
{
    // set KEY_EVENT to wakeup SEND_KEYMESSAGE_TASK :
    CDU_OS.SetEvent(KEY_EVENT,SEND_KEYMESSAGE_TASK_ID );
}

void CDU_KB_INT_START()
{
    CDU_KB_INT.mode( PullUp );          //Keyboard chip pulls this line to 0 on a keypress
    CDU_KB_INT.fall(&SET_KEY_EVENT);   //Bind function to handle interrupt
}

void CDU_SET_BGL_INTENSITY( int nVal=255 )
{
    //This routine must be called 5-10x per second. Manual test to see what is pleasant to see
    //AnalogIn BGL_POT( p15 ); //background light control potmeter. Returns a value between 0.0 and 1.0
    //PwmOut BGL_LED( p21 );   //PWM output
    //calculate required brightness in percentage from 0%-100%
    //nVal 255     --> calculate brightness from potmeter value (default value if no parameter is passed)
    //nVal = 0     --> switch off backlight
    //nVal = 100   --> switch on backlight max

    static int LightOn    = 1;
    static int FullBright = 0;

    switch (nVal) 
    {
        case 0:
        {
            //switch off backlighting
            BGL_LED = 0.0 ;
            LightOn = 0;
            FullBright = 0;
            break;
        }
        case 100:
        {
            //switch on backlighting to normal
            BGL_LED = BGL_POT;
            LightOn = 1;
            FullBright = 0;
            break;
        }
        
        case 128:
        {
            //switch backlighting to MAX
            BGL_LED= 1;
            FullBright = 1;   
        }
    
        case 255:
        {
            //calculate percentage from potmeter value
            if ( ( LightOn == 1) && (FullBright== 0) )
            {
                if ( BGL_POT < 0.01 )
                    {
                        BGL_LED = 0.0; //prevents flickering when low intensity
                    }
                else
                    {
                        BGL_LED = BGL_POT; 
                    }
            }
            else  if ( ( LightOn == 1) && (FullBright== 1) ) 
            {
                BGL_LED = 1;
                
            }
        }
    }
}