Subversion Repositories HomeAutomation

Rev

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