Subversion Repositories HomeAutomation

Rev

Rev 1202 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

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