⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpr084.c

📁 freescale badge board 开发板测试 源程序
💻 C
字号:
/*!
 * \file    mpr084.c
 * \brief   Simple driver MPR084 using I2C
 * \version $Revision: 1.3 $
 * \author  Anthony Huereca
 */

 #include "mpr084.h"

/*********************************** Variables ***********************************/
unsigned char SlaveID;
unsigned char MasterTransmission;

volatile unsigned char keylog[8];
volatile unsigned char keypressed;

/*******************************************************************/
/*!
 * I2C Initialization
 * Set Baud Rate and turn on I2C
 */
void init_I2C(void) 
{
  if(!PTGD_PTGD1) /* If connected to USB and thus 12MHz bus */ 
  {
    IIC1F  = 0x14;       /* set MULT and ICR */     
  } 
  else           /* 750kHz bus */
  {
    IIC1F  = 0x00;       /* set MULT and ICR */   
  }
  IIC1C1 = 0x80;       /* enable IIC */ 
}

/*******************************************************************/
/*!
 * MPR084 Initialization
 */
void MPR084_init(void) 
{   
  /* Delay Loop to ensure MPR084 is powered up */
  int i;


  for(i=0;i<10000;i++) {
    asm("nop");
  }

  /* Turn on I2C Clock */
  SCGC1_IIC1=1;
  
  /* Configure I2C */ 
  init_I2C();

  /* Turn on ATTN Pin */
  PTCDD_PTCDD6=1; 
  ATTN=1;

  /* Ensure MPR084 is awake */
  TOGGLE_ATTN
 
   /* Delay Loop to ensure MPR084 is powered up */
  for(i=0;i<10000;i++) {
    asm("nop");
  }
 
  /* Reset Touch Sensor */
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x04);
  for(i=0;i<10000;i++) {
    asm("nop");
  }   
  
  TOGGLE_ATTN
   
  for(i=0;i<10000;i++) {
    asm("nop");
  }

  /* Initialize key logger */
  for(i=0;i< LOG_LENGTH;i++) 
  {
    keylog[i]=0;
  }
  
  /* Put in Stop 1 Mode for initial Config */
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x14);

  /* Set maximum number of concurrent touches allowed to 1 */
  MPR084WriteRegister(MAX_TOUCH,0x01);  
  
  /* Set Sensitivity Threshold to 0x3F */
  MPR084WriteRegister(SENSITIVITY_REGISTER1,0x3F);  
  /* Set Sensitivity Threshold to 0x3F */
  MPR084WriteRegister(SENSITIVITY_REGISTER2,0x3F);  
  /* Set Sensitivity Threshold to 0x3F */
  MPR084WriteRegister(SENSITIVITY_REGISTER3,0x3F);  
  /* Set Sensitivity Threshold to 0x3F */
  MPR084WriteRegister(SENSITIVITY_REGISTER4,0x3F);  
  /* Set Sensitivity Threshold to 0x3F */
  MPR084WriteRegister(SENSITIVITY_REGISTER5,0x3F);  
  /* Set Sensitivity Threshold to 0x3F */
  MPR084WriteRegister(SENSITIVITY_REGISTER6,0x3F);  
  /* Set Sensitivity Threshold to 0x3F */
  MPR084WriteRegister(SENSITIVITY_REGISTER7,0x3F);  
  /* Set Sensitivity Threshold to 0x3F */
  MPR084WriteRegister(SENSITIVITY_REGISTER8,0x3F);  
  
  /* Turn off Sounder */
  MPR084WriteRegister(SOUNDER_CONFIGURATION_REGISTER,0x00);
  
  /* Sound On, Auto Calibration On, Touch and Release Buffer On, Sensor On */
  MPR084WriteRegister(TOUCH_CONFIGURATION_REGISTER, 0x1D); 

  /* Set 5ms Master Clock */
  MPR084WriteRegister(MASTER_TICK_COUNTER_REGISTER,0x00);
      
  /* TASP Multiplier to 2 */
  MPR084WriteRegister(TOUCH_ACQUISITION_SAMPLE_PERIOD_REGISTER,0x01);
  
  /* No Delay for Touches */  
  MPR084WriteRegister(LOW_POWER_CONFIGURATION_REGISTER, 0x00);     

  /* Turn on IRQ and put in Run 2 Mode */  
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x13);  

  /* Turn off I2C Clock */
  SCGC1_IIC1=0;
  
  /* Turn on IRQ */
  IRQSC=0x52;   
}


/*******************************************************************/
/*!
 * Read the Rotary Status Register to determine if have a touch
 * and if so, which button is touched
 * @return Status of Touch Pad
 */
byte ProximitySensorRead() 
{
  byte result;
  
  /* Get current status of touch pad */
  result=u8MPR084ReadRegister(TOUCH_STATUS_REGISTER);
   

  /* Determine if a key is currently being touched */  
  if(result&0xFF) 
  { 
    keypressed=1;

    /* If key is touched, figure out which one it is... */
    switch(result&0xFF) 
    {
        case 0x01:
          AddTouch(1);
          break;
        case 0x02:
          AddTouch(2);
          break; 
        case 0x04:
          AddTouch(3);
          break; 
        case 0x08:
          AddTouch(4);
          break;  
        case 0x10:
          AddTouch(5);
          break; 
        case 0x20:
          AddTouch(6);
          break;
        case 0x40:
          AddTouch(7);
          break; 
        case 0x80:
          AddTouch(8);
          break;  
        default:
          AddTouch(0);
          break;           
    }
  } 
  else 
  {
    /* No key touched */
    keypressed=0;
  }  
  return result; 
}



   
/*******************************************************************/
/*!
 * IRQ Service Routine
 * Toggles the Attention pin to wake up MPR084 for I2C communications
 * Then reads Status register, clears FIFO buffer, and put back in low power mode
 * Only executes when button is either pushed or released
 */
interrupt VectorNumber_Virq void IRQ_ISR (void) 
{
  byte fault; 
  
  /* Turn on I2C Clock and Re-init I2C */
  SCGC1_IIC1=1;
  init_I2C();  
  
  /* Put MPR084 into Run1 Mode for I2C Communication */
  TOGGLE_ATTN 

  /* Turn off interrupts */
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x15);

  /* Check for fault */
  fault=u8MPR084ReadRegister(FAULT_REGISTER);
  if(fault&0x00000007) 
  {   
    keypressed=0;
  } 
  else
  {
    /* Read Sensor and Display on LED */
    ProximitySensorRead();   
  }

  /* Clear interrupt signal */   
  while(IRQSC_IRQF) 
  {
    MPR084WriteRegister(FAULT_REGISTER,0x00);
    u8MPR084ReadRegister(FIFO_REGISTER);
        
    IRQSC_IRQACK=1; 
  } 
 

  /* Put back in Low Power Mode */
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x13);

  /* Turn off I2C Clock */ 
  SCGC1_IIC1=0;
}

/*******************************************************************/
/*!
 * Put the touch sensor into a low power mode. Drawback is that touches
 * take longer to register
 */
void MPR084SetLowPower() 
{
  /* Turn on I2C Clock and Re-init I2C */
  SCGC1_IIC1=1;
  init_I2C(); 

  /* Ensure MPR084 is awake */
  TOGGLE_ATTN

  /* Put in Stop 1 Mode for initial Config */
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x14);

  /* Sleep longer so require a long touch to wake up */  
  MPR084WriteRegister(LOW_POWER_CONFIGURATION_REGISTER, 0x2F);     

  /* Turn on IRQ and put in Run 2 Mode */  
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x13);  
  
    SCGC1_IIC1=0;
}

/*******************************************************************/
/*!
 * Put the touch sensor into normal mode. Touches respond much faster, 
 *  but draws about 400uA more current.
 */
void MPR084SetNormalPower() 
{
  /* Turn on I2C Clock and Re-init I2C */
  SCGC1_IIC1=1;
  init_I2C(); 

  /* Ensure MPR084 is awake */
  TOGGLE_ATTN

  /* Put in Stop 1 Mode for initial Config */
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x14);

  /* No Delay for Touches */  
  MPR084WriteRegister(LOW_POWER_CONFIGURATION_REGISTER, 0x00);     

  /* Turn on IRQ and put in Run 2 Mode */  
  MPR084WriteRegister(CONFIGURATION_REGISTER,0x13);  

    SCGC1_IIC1=0;

}


/*******************************************************************/
/*!
 * Return value of last key pressed
 * @return Number of the last button pressed
 */
byte LastKeyPressed() 
{
  return (byte)keylog[0] & 0x0000000F;
}

/*******************************************************************/
/*!
 * Return 1 if key is currently being pressed. 0 if no key is being pressed
 */
byte KeyPressed() 
{
  return keypressed & 0x0000000F;
}


/*******************************************************************/
/*!
 * Return True if Slide Up on Left Side occured
 */ 
byte SlideLeftUp() 
{
  return (keylog[0]==1) && (keylog[1]==2) && (keylog[2]==3) && (keylog[3]==4);
}

/*******************************************************************/
/*!
 * Return True if Slide Down on Left Side occured
 */ 
byte SlideLeftDown() 
{
  return (keylog[0]==4) && (keylog[1]==3) && (keylog[2]==2) && (keylog[3]==1);
}

/*******************************************************************/
/*!
 * Return True if Slide Up on Right Side occured
 */ 
byte SlideRightUp() 
{
  return (keylog[0]==5) && (keylog[1]==6) && (keylog[2]==7) && (keylog[3]==8);
}

/*******************************************************************/
/*!
 * Return True if Slide Down on Right Side occured
 */ 
byte SlideRightDown() 
{
  return (keylog[0]==8) && (keylog[1]==7) && (keylog[2]==6) && (keylog[3]==5);
}

/*******************************************************************/
/*!
 * Return True if Slide Down on Right Side occured
 */ 
byte ExitApp() 
{
  return (keylog[0]==8) && (keylog[1]==4) && (keylog[2]==5) && (keylog[3]==1);
}

/*******************************************************************/
/*!
 *  Check for secret code 
 *  Return True if you read this
 */ 
byte SecretCode(byte code) 
{
  switch (code) 
  {
    case 2:
      return ((keylog[6]==5) && 
              (keylog[5]==6) && 
              (keylog[4]==7) && 
              (keylog[3]==8) && 
              (keylog[2]==7) && 
              (keylog[1]==6) && 
              (keylog[0]==5));
    case 1:
      return ((keylog[3]==1) && 
              (keylog[2]==5) && 
              (keylog[1]==2) && 
              (keylog[0]==6));
    case 0:
    default: 
      return ((keylog[4]==3) && 
              (keylog[3]==1) && 
              (keylog[2]==3) && 
              (keylog[1]==3) && 
              (keylog[0]==7));
  }
}

/*******************************************************************/
/*!
 * Pause Routine
 */ 
void Pause(void){
    int n;
    for(n=1;n<50;n++) {
      asm("nop");
    }
}


/*******************************************************************/
/*!
 *  Add Key Press to Key History
 *  @param key is the key to add to queue
 */ 
void AddTouch(byte key) 
{
  unsigned char i=LOG_LENGTH-1;
  
  /* Shift queue over by 1 */
  while(i>0) 
  {
    keylog[i]=keylog[i-1];
    i--;
  }  
  keylog[0]=key;

}


/*******************************************************************/
/*!
 * Start I2C Transmision
 * @param SlaveID is the 7 bit Slave Address
 * @param Mode sets Read or Write Mode
 */
void IIC_StartTransmission (unsigned char SlaveID,unsigned char Mode)
{
  if(Mode == MWSR)
  {      
    /* set transmission mode */
    MasterTransmission = MWSR;
  }
  else
  {
    /* set transmission mode */
    MasterTransmission = MRSW;
  }
    
  /* shift ID in right possition */
  SlaveID = (byte) MPR084_I2C_ADDRESS << 1; 
  
  /* Set R/W bit at end of Slave Address */
  SlaveID |= (byte)MasterTransmission;

  /* send start signal */
  i2c_Start();

  /* send ID with W/R bit */
  i2c_write_byte(SlaveID);
}


/*******************************************************************/
/*!
 * Read a register from the MPR084
 * @param u8RegisterAddress is Register Address
 * @return Data stored in Register
 */
byte u8MPR084ReadRegister(byte u8RegisterAddress)
{
  byte result, result2;
  
  /* Set Register Pointer on MPR084 */
  IIC_StartTransmission(SlaveID,MWSR);  
  i2c_Wait();
  
  IIC1D = u8RegisterAddress;
  i2c_Wait();    
  
  i2c_Stop();     
  
  Pause();
          
  /* Request data from Register */         
  IIC_StartTransmission(SlaveID,MRSW);
  i2c_Wait();
   
  i2c_EnterRxMode(); 
  result2 = IIC1D;
  i2c_Wait();   
  
  result = IIC1D;
  i2c_DisableAck();
  i2c_Wait(); 
   
  i2c_Stop(); 
  result2 = IIC1D;
 
  Pause();

  return result;
}

/*******************************************************************/
/*!
 * Write a byte of Data to specified register on MPR084
 * @param u8RegisterAddress is Register Address
 * @param u8Data is Data to write
 */
void MPR084WriteRegister(byte u8RegisterAddress, byte u8Data)
{
  /* send data to slave */
  IIC_StartTransmission(SlaveID,MWSR);  
  i2c_Wait();
  
  IIC1D = u8RegisterAddress;
  i2c_Wait();
  
  IIC1D = u8Data;
  i2c_Wait();    
  
  i2c_Stop();        

  Pause();
}  


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -