Anyway, the existing code uses the GLCD library. The only interrupt the code used was the ISRRX.OnData interrupt. Serial traffic is minimal.
I've taken a sledge-hammer to the design and added a low-priority ISR that runs ADC acquisition triggered off TIMER1/CCP2 and also TIMER0 (10ms). The ISR appears to work and I'm able to change the frequency of acquisitions as expected via CCPR2H/L.
The problem is, the interrupts appear to be corrupting the display. At very low frequency (of interrupt), the worst appears to be either side of the display (page) shifting up and down via a single pixel row. As I increase the frequency, the corruption worsens and at anything near the frequency I require for decent touch screen operation, it's totally corrupt and completely unreadable. Disabling the interrupt results in a perfect display.
Now I can't see why I shouldn't be able to interrupt the GLCD routines. Looking at the bus timing diagrams for the LCD module there don't appear to be any signals/operations that couldn't - in theory - be extended indefinitely without corrupting the display. I should also mention that the ADC plays with RBPU# (same port as LCD control bus) but all control signals are outputs so that shouldn't be an issue. Regardless, removing the code that toggles RBPU# has no effect. So I'm at a loss to explain what could be causing this.
My question at the end of all this is, can anyone think of why the GLCD routines can't be interrupted? There's still the possibility that I'm doing something stupid of course, but if they can't be interrupted, then it's going to be a nightmare getting this working properly, and then shouldn't the ISRRX interrupt also cause occasional corruption?
EDIT: I should probably include some code snippets...
The options for the GLCD module:
Code: Select all
#Option GLCD_MODEL = KS0108 #option GLCD_SCREEN_WIDTH = 128 #option GLCD_SCREEN_HEIGHT = 64 #Option GLCD_DATA = PORTD #Option GLCD_RS = PORTB.2 #Option GLCD_RW = PORTB.1 #Option GLCD_EN = PORTB.0 #Option GLCD_CS1 = PORTB.4 #Option GLCD_CS2 = PORTB.3 #Option GLCD_RST = PORTE.3 #Option GLCD_ASPECT_RATIO = 100 #Option GLCD_INIT_DELAY = 200
Code: Select all
Public Sub Initialise() state = 0 #ifdef ADC_ENABLE_ADC #ifdef ADC_USE_CCP2 // CCP2 configuration for the ADC T3CON = %00000000 // Timer1 is compare clock CCPR2H = $10 // CCPR2 is timer period CCPR2L = 0 CCP2CON = %00001011 // Special Event Trigger (ADC) // TIMER1 configuration for the ADC T1CON = %10110101 // 16-bit,1:8 prescale #endif // ADC configuration Input(PEN) TRISA = %00001111 // AN3-0 on PORTA ADCON1 = %00001011 // CCP2,AVss-AVdd, AN3-0 // start (dummy) read on AN3 ADCON0 = %00001100 // AN3,disabled ADCON2 = %10111010 // Right,20Tad,Fosc/32 ADCON0.0 = 1 // enabled // ADC interrupt ADIP = 0 // Low priority interrupt ADIF = 0 // Clear any pending ADC interrupt flag ADIE = 1 // Enable ADC interrupt #ifndef ADC_USE_CCP2 ADCON0.1 = 1 // GO #endif #endif // ADC_ENABLE_ADC ...
Code: Select all
Interrupt OnTS(ipLow) #ifdef ADC_ENABLE_ADC // ADC interrupt? If ADIF = 1 Then Select state Case 0 // stop AN3 ADCON0.0 = 0 // disabled // read result TEMPP = ADRES If TEMPP < TouchThreshold Then If PCOUNT < 4 Then Inc(PCOUNT) Else XBUF(BUFI) = TEMPX YBUF(BUFI) = TEMPY BUFI = (BUFI + 1) And 3 EndIf Else PCOUNT = 0 EndIf ToggleLed () // config for next read Input(TS_X1) // X- floating Input(TS_X2) // X+ floating Output(TS_Y1) // Y- LOW TS_Y1 = 0 Output(TS_Y2) // Y+ HIGH TS_Y2 = 1 RBPU = 1 // Disable PULL-UPs // start read on AN1 ADCON0 = %00000100 // AN1,disabled ADCON2 = %10111010 // Right,20Tad,Fosc/32 ADCON0.0 = 1 // enabled #ifndef ADC_USE_CCP2 ADCON0.1 = 1 // GO #endif state = 1 Case 1 // stop AN1 ADCON0.0 = 0 // disabled // read result TEMPX = ADRES // config for next read Input(TS_Y1) // Y- floating Input(TS_Y2) // Y+ floating Output(TS_X1) // X- LOW TS_X1 = 0 Output(TS_X2) // X+ HIGH TS_X2 = 1 RBPU = 1 // Disable PULL-UPs // start read on AN3 ADCON0 = %00001100 // AN3,disabled ADCON2 = %10111010 // Right,20Tad,Fosc/32 ADCON0.0 = 1 // enabled #ifndef ADC_USE_CCP2 ADCON0.1 = 1 // GO #endif state = 2 Case 2 // stop AN3 ADCON0.0 = 0 // disabled // read result TEMPY = ADRES // config for next read Input(TS_X2) // X+ floating Input(TS_Y1) // Y- floating Input(TS_Y2) // Y+ ADC input Output(TS_X1) // X- LOW TS_X1 = 0 RBPU = 0 // Enable PULL-UPs // start read on AN3 ADCON0 = %00001100 // AN3,disabled ADCON2 = %10111010 // Right,20Tad,Fosc/32 ADCON0.0 = 1 // enabled #ifndef ADC_USE_CCP2 ADCON0.1 = 1 // GO #endif state = 0 Else state = 0 EndSelect // Clear ADC Interrupt Flag // - doco suggests this should be done after reading result ADIF = 0 EndIf #endif // ADC_ENABLE_ADC ...