Subversion Repositories HomeAutomation

Rev

Rev 1130 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /**
  2.  * ...
  3.  *
  4.  * @author  Linus Lundin
  5.  *
  6.  * @date    2009-03-01
  7.  */
  8.  
  9. /*-----------------------------------------------------------------------------
  10.  * Includes
  11.  *---------------------------------------------------------------------------*/
  12. #include <inttypes.h>
  13. #include <avr/io.h>
  14. #include <avr/interrupt.h>
  15.  
  16. #include <drivers/mcu/pcint.h>
  17.  
  18. /*-----------------------------------------------------------------------------
  19.  * Globals
  20.  *---------------------------------------------------------------------------*/
  21.  
  22. struct {
  23.     uint8_t pcintBit;
  24.     uint8_t lastStatus;
  25.     pcintCallback_t callback;
  26. } pcints[PCINT_NUM_PCINTS];
  27.  
  28. /*-----------------------------------------------------------------------------
  29.  * Interrupt Service Routines
  30.  *---------------------------------------------------------------------------*/
  31.  
  32. /*********************************************************************//**
  33. Function: ISR(PCINT0_vect)
  34. Purpose:  Executed when pin change on PCINT0.
  35. Input:    -
  36. Returns:  -
  37. **************************************************************************/
  38. ISR(PCINT0_vect) {
  39.     uint8_t p;
  40.     /* Check which pin that have had a change and call the callback.*/
  41.     for (p = 0; p < PCINT_NUM_PCINTS; p++)
  42.     {
  43.         if (pcints[p].pcintBit < 8) {
  44.             if (pcints[p].lastStatus != ((PINB & (1 << pcints[p].pcintBit)) != 0)) {
  45.                 pcints[p].callback(p);
  46.                 pcints[p].lastStatus = ((PINB & (1 << pcints[p].pcintBit)) != 0);
  47.             }
  48.         } else if (pcints[p].pcintBit < 16) {
  49.             if (pcints[p].lastStatus != ((PINC & (1 << pcints[p].pcintBit%8)) != 0)) {
  50.                 pcints[p].callback(p);
  51.                 pcints[p].lastStatus = ((PINC & (1 << pcints[p].pcintBit%8)) != 0);
  52.             }
  53.         } else if (pcints[p].pcintBit < 24) {
  54.             if (pcints[p].lastStatus != ((PIND & (1 << pcints[p].pcintBit%8)) != 0)) {
  55.                 pcints[p].callback(p);
  56.                 pcints[p].lastStatus = ((PIND & (1 << pcints[p].pcintBit%8)) != 0);
  57.             }
  58.         }
  59.     }
  60. } /* ISR(PCINT0_vect) */
  61.  
  62.  
  63. /*********************************************************************//**
  64. Function: ISR(PCINT1_vect)
  65. Purpose:  Executed when pin change on PCINT1.
  66. Input:    -
  67. Returns:  -
  68. **************************************************************************/
  69. ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect));
  70.  
  71. /*********************************************************************//**
  72. Function: ISR(PCINT0_vect)
  73. Purpose:  Executed when pin change on PCINT2.
  74. Input:    -
  75. Returns:  -
  76. **************************************************************************/
  77. ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect));
  78.  
  79. /*-----------------------------------------------------------------------------
  80.  * Public Functions
  81.  *---------------------------------------------------------------------------*/
  82.  
  83. void Pcint_SetCallback(uint8_t pcint_id, uint8_t pcintBit, pcintCallback_t callback)
  84. {
  85.     if (pcint_id<PCINT_NUM_PCINTS)
  86.     {
  87.         uint8_t sreg = SREG;
  88.         cli();
  89.  
  90.         PCIFR=(1<<PCIF0);   /* clear any pending interrupt before enabling interrupts */
  91.         PCICR|=(1<<PCIE0);  /* enable interrupt for PCINT0 */
  92.         PCIFR=(1<<PCIF1);   /* clear any pending interrupt before enabling interrupts */
  93.         PCICR|=(1<<PCIE1);  /* enable interrupt for PCINT1 */
  94.         PCIFR=(1<<PCIF2);   /* clear any pending interrupt before enabling interrupts */
  95.         PCICR|=(1<<PCIE2);  /* enable interrupt for PCINT2 */
  96.         pcints[pcint_id].pcintBit = pcintBit;
  97.         pcints[pcint_id].lastStatus = 0;
  98.         if (callback != 0) {
  99.             if (pcints[pcint_id].pcintBit < 8) {
  100.                 pcints[pcint_id].lastStatus = ((PINB & (1 << pcints[pcint_id].pcintBit%8)) != 0);
  101.                 PCMSK0 |= (1<<pcints[pcint_id].pcintBit%8);
  102.             } else if (pcints[pcint_id].pcintBit < 16) {
  103.                 pcints[pcint_id].lastStatus = ((PINC & (1 << pcints[pcint_id].pcintBit%8)) != 0);
  104.                 PCMSK1 |= (1<<pcints[pcint_id].pcintBit%8);
  105.             } else if (pcints[pcint_id].pcintBit < 24) {
  106.                 pcints[pcint_id].lastStatus = ((PIND & (1 << pcints[pcint_id].pcintBit%8)) != 0);
  107.                 PCMSK2 |= (1<<pcints[pcint_id].pcintBit%8);
  108.             }
  109.         } else { //turn off interupt
  110.             if (pcints[pcint_id].pcintBit < 8) {
  111.                 PCMSK0 &= ~(1<<(pcints[pcint_id].pcintBit%8));
  112.             } else if (pcints[pcint_id].pcintBit < 16) {
  113.                 PCMSK1 &= ~(1<<(pcints[pcint_id].pcintBit%8));
  114.             } else if (pcints[pcint_id].pcintBit < 24) {
  115.                 PCMSK2 &= ~(1<<(pcints[pcint_id].pcintBit%8));
  116.             }
  117.         }
  118.         pcints[pcint_id].callback = callback;
  119.         SREG = sreg;
  120.     }
  121. }
  122.  
  123. /*---------------------------------------------------------------------------*/
  124.  
  125.