Rev 1202 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 1125 | linlun | 1 | /** |
| 2 | * ... |
||
| 3 | * |
||
| 1466 | arune | 4 | * @author Linus Lundin, Anders Runeson |
| 1125 | linlun | 5 | * |
| 6 | * @date 2009-03-01 |
||
| 7 | */ |
||
| 8 | |||
| 9 | /*----------------------------------------------------------------------------- |
||
| 10 | * Includes |
||
| 1138 | linlun | 11 | *---------------------------------------------------------------------------*/ |
| 1136 | arune | 12 | |
| 1138 | linlun | 13 | #include <config.h> |
| 14 | #if PCINT_NUM_PCINTS > 0 |
||
| 15 | |||
| 1125 | linlun | 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; |
||
| 1466 | arune | 28 | uint8_t pcintMask; |
| 1136 | arune | 29 | uint8_t lastStatus; |
| 1125 | linlun | 30 | pcintCallback_t callback; |
| 31 | } pcints[PCINT_NUM_PCINTS]; |
||
| 1138 | linlun | 32 | |
| 1125 | linlun | 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) { |
||
| 1138 | linlun | 44 | uint8_t p; |
| 45 | uint8_t rPinB=PINB; |
||
| 46 | uint8_t rPinC=PINC; |
||
| 47 | uint8_t rPinD=PIND; |
||
| 48 | |||
| 1125 | linlun | 49 | /* Check which pin that have had a change and call the callback.*/ |
| 1129 | linlun | 50 | //printf("I\n"); |
| 1125 | linlun | 51 | for (p = 0; p < PCINT_NUM_PCINTS; p++) |
| 1138 | linlun | 52 | { |
| 1136 | arune | 53 | if (pcints[p].pcintBit < 8) { |
| 1466 | arune | 54 | if (pcints[p].lastStatus != (rPinB & pcints[p].pcintMask)) { |
| 55 | pcints[p].lastStatus = (rPinB & pcints[p].pcintMask); |
||
| 1136 | arune | 56 | pcints[p].callback(p, pcints[p].lastStatus); |
| 1125 | linlun | 57 | } |
| 58 | } else if (pcints[p].pcintBit < 16) { |
||
| 1466 | arune | 59 | if (pcints[p].lastStatus != (rPinC & pcints[p].pcintMask)) { |
| 60 | pcints[p].lastStatus = (rPinC & pcints[p].pcintMask); |
||
| 1136 | arune | 61 | pcints[p].callback(p, pcints[p].lastStatus); |
| 1125 | linlun | 62 | } |
| 63 | } else if (pcints[p].pcintBit < 24) { |
||
| 1466 | arune | 64 | if (pcints[p].lastStatus != (rPinD & pcints[p].pcintMask)) { |
| 65 | pcints[p].lastStatus = (rPinD & pcints[p].pcintMask); |
||
| 1136 | arune | 66 | pcints[p].callback(p, pcints[p].lastStatus); |
| 1125 | linlun | 67 | } |
| 1136 | arune | 68 | } |
| 1138 | linlun | 69 | } |
| 70 | |||
| 1125 | linlun | 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 | **************************************************************************/ |
||
| 1202 | arune | 80 | #if ((__GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ > 2)||(__GNUC__ == 4 && __GNUC_MINOR__ > 2)||__GNUC__ > 4) |
| 1125 | linlun | 81 | ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect)); |
| 1129 | linlun | 82 | #else |
| 83 | ISR_ALIAS(PCINT1_vect, PCINT0_vect); |
||
| 84 | #endif |
||
| 1125 | linlun | 85 | /*********************************************************************//** |
| 86 | Function: ISR(PCINT0_vect) |
||
| 87 | Purpose: Executed when pin change on PCINT2. |
||
| 88 | Input: - |
||
| 89 | Returns: - |
||
| 90 | **************************************************************************/ |
||
| 1202 | arune | 91 | #if ((__GNUC__ == 4 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ > 2)||(__GNUC__ == 4 && __GNUC_MINOR__ > 2)||__GNUC__ > 4) |
| 1125 | linlun | 92 | ISR(PCINT2_vect, ISR_ALIASOF(PCINT0_vect)); |
| 1129 | linlun | 93 | #else |
| 94 | ISR_ALIAS(PCINT2_vect, PCINT0_vect); |
||
| 95 | #endif |
||
| 1125 | linlun | 96 | /*----------------------------------------------------------------------------- |
| 97 | * Public Functions |
||
| 98 | *---------------------------------------------------------------------------*/ |
||
| 99 | |||
| 100 | void Pcint_SetCallback(uint8_t pcint_id, uint8_t pcintBit, pcintCallback_t callback) |
||
| 101 | { |
||
| 1129 | linlun | 102 | //printf("Test\n"); |
| 1125 | linlun | 103 | if (pcint_id<PCINT_NUM_PCINTS) |
| 104 | { |
||
| 105 | uint8_t sreg = SREG; |
||
| 106 | cli(); |
||
| 107 | |||
| 1134 | arune | 108 | PCIFR=(1<<PCIF0|1<<PCIF1|1<<PCIF2); /* clear any pending interrupt before enabling interrupts */ |
| 1138 | linlun | 109 | PCICR|=(1<<PCIE0|1<<PCIE1|1<<PCIE2); /* enable interrupt for PCINT0-2 */ |
| 1466 | arune | 110 | |
| 1125 | linlun | 111 | pcints[pcint_id].pcintBit = pcintBit; |
| 1466 | arune | 112 | pcints[pcint_id].pcintMask = 1<<pcints[pcint_id].pcintBit%8; |
| 1136 | arune | 113 | pcints[pcint_id].lastStatus = 0; |
| 1125 | linlun | 114 | if (callback != 0) { |
| 115 | if (pcints[pcint_id].pcintBit < 8) { |
||
| 1466 | arune | 116 | pcints[pcint_id].lastStatus = (PINB & pcints[pcint_id].pcintMask); |
| 117 | PCMSK0 |= pcints[pcint_id].pcintMask; |
||
| 1129 | linlun | 118 | //printf("PCMSK %u\n", PCMSK0); |
| 1125 | linlun | 119 | } else if (pcints[pcint_id].pcintBit < 16) { |
| 1466 | arune | 120 | pcints[pcint_id].lastStatus = (PINC & pcints[pcint_id].pcintMask); |
| 121 | PCMSK1 |= pcints[pcint_id].pcintMask; |
||
| 1129 | linlun | 122 | //printf("PCMSK1 %u\n", PCMSK1); |
| 1125 | linlun | 123 | } else if (pcints[pcint_id].pcintBit < 24) { |
| 1466 | arune | 124 | pcints[pcint_id].lastStatus = (PIND & pcints[pcint_id].pcintMask); |
| 125 | PCMSK2 |= pcints[pcint_id].pcintMask; |
||
| 1129 | linlun | 126 | //printf("PCMSK2 %u\n", PCMSK2); |
| 1125 | linlun | 127 | } |
| 128 | } else { //turn off interupt |
||
| 129 | if (pcints[pcint_id].pcintBit < 8) { |
||
| 1466 | arune | 130 | PCMSK0 &= ~pcints[pcint_id].pcintMask; |
| 1125 | linlun | 131 | } else if (pcints[pcint_id].pcintBit < 16) { |
| 1466 | arune | 132 | PCMSK1 &= ~pcints[pcint_id].pcintMask; |
| 1125 | linlun | 133 | } else if (pcints[pcint_id].pcintBit < 24) { |
| 1466 | arune | 134 | PCMSK2 &= ~pcints[pcint_id].pcintMask; |
| 1125 | linlun | 135 | } |
| 1138 | linlun | 136 | } |
| 137 | |||
| 1125 | linlun | 138 | pcints[pcint_id].callback = callback; |
| 139 | SREG = sreg; |
||
| 140 | } |
||
| 141 | } |
||
| 142 | |||
| 1138 | linlun | 143 | #endif /*PCINT_NUM_PCINTS > 0*/ |
| 144 | |||
| 1125 | linlun | 145 | /*---------------------------------------------------------------------------*/ |
| 146 |