Hallo zusammen,
habe mir gedacht ich poste mal ein Problem, dessen Lösung mich gestern
Nacht fast um den Schlaf gebracht hat.
Problematik: SPI2 auf dem PIC32 der 1xx oder 2xx Serie in Kombination
mit dem XC32 Compiler und der SPI Lib.
Wenn man nun versucht auf dem SPI2 einen Interrupt mit folgenden
Funktionsaufrufen zu bekommen... Geht nicht. Beim SPI1 funktioniert das,
wenn man genau die selben Funktionsaufrufe durchführt.
1 | ...
|
2 |
|
3 | SpiChnOpenEx(SPI_CHANNEL2, c1, c2, div);
|
4 |
|
5 | //Enable SPI2 interrupt.
|
6 | INTSetVectorPriority(INT_SPI_2_VECTOR, INT_PRIORITY_LEVEL_3);
|
7 | INTSetVectorSubPriority(INT_SPI_2_VECTOR, INT_SUB_PRIORITY_LEVEL_0);
|
8 | INTEnable(INT_SPI2, INT_ENABLED);
|
9 |
|
10 | SpiChnPutC(SPI_CHANNEL2, 0); //starte transfer
|
11 |
|
12 | ...
|
soweit so gut, Ende vom Lied:
Ich habe gemerkt, dass in der "int_1xx_2xx.h" des compilers die
kompletten Makros für den SPI2 fehlen. Dementsprechend werden sie
vermutlich auch nicht hinter den "INTSetVector..." Funktionsaufrufen
implementiert sein.
Habe also nun die Makros per Hand eingepflegt und sie anschließend statt
der Compilerfunktionen aufgerufen.
Hier die erweiterten Makros
1 | #ifdef _SPI2
|
2 | #define mSPI2EClearIntFlag() (IFS1CLR = _IFS1_SPI2EIF_MASK)
|
3 | #define mSPI2EGetIntFlag() (IFS1bits.SPI2EIF)
|
4 | #define mSPI2EGetIntEnable() (IEC1bits.SPI2EIE)
|
5 | #define mSPI2EIntEnable(enable) (IEC1CLR = _IEC1_SPI2EIE_MASK, IEC1SET = ((enable) << _IEC1_SPI2EIE_POSITION))
|
6 | /*********************************************************************
|
7 | * SPI 2 Transfer
|
8 | ********************************************************************/
|
9 | #define mSPI2TXClearIntFlag() (IFS1CLR = _IFS1_SPI2TXIF_MASK)
|
10 | #define mSPI2TXGetIntFlag() (IFS1bits.SPI2TXIF)
|
11 | #define mSPI2TXGetIntEnable() (IEC1bits.SPI2TXIE)
|
12 | #define mSPI2TXIntEnable(enable) (IEC1CLR = _IEC1_SPI2TXIE_MASK, IEC1SET = ((enable) << _IEC1_SPI2TXIE_POSITION))
|
13 | /*********************************************************************
|
14 | * SPI 2 Receive
|
15 | ********************************************************************/
|
16 | #define mSPI2RXClearIntFlag() (IFS1CLR = _IFS1_SPI2RXIF_MASK)
|
17 | #define mSPI2RXGetIntFlag() (IFS1bits.SPI2RXIF)
|
18 | #define mSPI2RXGetIntEnable() (IEC1bits.SPI2RXIE)
|
19 | #define mSPI2RXIntEnable(enable) (IEC1CLR = _IEC1_SPI2RXIE_MASK, IEC1SET = ((enable) << _IEC1_SPI2RXIE_POSITION))
|
20 | /*********************************************************************
|
21 | * SPI 2 Vector
|
22 | ********************************************************************/
|
23 | #define mSPI2ClearAllIntFlags() ( IFS1CLR = (_IFS1_SPI2EIF_MASK | _IFS1_SPI2TXIF_MASK | _IFS1_SPI2RXIF_MASK))
|
24 | #define mSPI2IntDisable() ( IEC1CLR = (_IEC1_SPI2EIE_MASK | _IEC1_SPI2TXIE_MASK | _IEC1_SPI2RXIE_MASK))
|
25 | #define mSPI2SetIntEnable(flags) ( IEC1SET = (((flags) & 0x7) << _IEC1_SPI2EIE_POSITION))
|
26 | #define mSPI2SetIntPriority(priority) (IPC9CLR = _IPC9_SPI2IP_MASK, IPC9SET = ((priority) << _IPC9_SPI2IP_POSITION))
|
27 | #define mSPI2GetIntPriority() (IPC9bits.SPI2IP)
|
28 | #define mSPI2SetIntSubPriority(subPriority) (IPC9CLR = _IPC9_SPI2IS_MASK, IPC9SET = ((subPriority) << _IPC9_SPI2IS_POSITION))
|
29 | #define mSPI2GetIntSubPriority() (IPC9bits.SPI2IS)
|
30 | #endif
|
Aufruf für TX Interrupt dann so:
1 | ...
|
2 |
|
3 | SpiChnOpenEx(SPI_CHANNEL2, c1, c2, div);
|
4 |
|
5 | //Enable SPI2 interrupt.
|
6 | mSPI2SetIntPriority(3);
|
7 | mSPI2SetIntSubPriority(0)
|
8 | mSPI2TXIntEnable(1);
|
9 |
|
10 | SpiChnPutC(SPI_CHANNEL2, 0); //starte transfer
|
11 |
|
12 | ...
|
Falls jemand eine Erklärung dafür hat wäre ich dankbar, habe auch mal
Microchip geschrieben, ob es einen Grund für die fehlenden defines gibt,
oder ob ich es einfach nicht überrissen habe, die lib richtig zu
benutzen :)
Naja, falls jemand vor dem selben Problem steht, oben der WorkAround.
Liebe Grüße,
Daniel