Subversion Repositories HomeAutomation

Rev

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