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
...