In the last log we added support for interrupts on the PSoC. To summarize:
- There are (5) MCP23017 parts which connect to the PSoC
- MCP23017 parts communicate with the PSoC using I2C
- (1) Expansion MC23017 on the main board
- Port A and Port B have pull-ups enabled
- Port A and Port B inputs set to inverting
- Pulling input pin to ground causes a "1" to be read for the pin
- Connected to a JOYPAD on Port A
- Expansion MCP23017 ports are initialized as inputs
- Ports can be configured by Z80 writes (PIO control register format)
- (4) MCP23017 parts on the Front Panel
- Half of the pins on each MCP23017 are configured as inputs from pushbuttons and half as outputs for LEDs
- Ports can be read from the Z80
- The MCP23017 has two interrupt pins; one for A Port and one for B Port
- The (2) interrupt pins on each of the MCP23017 parts are wired together
- MCP23017 parts are set to Open Drain outputs on the Interrupt lines
- All [five] MCP23017 ports are Wire-OR tied together into one line - I2CINT*
- MCP23017 parts are set to interrupt on change of the input pins
- Any change (H>L or L>H) causes the interrupt lines to be asserted on the port's interrupt pin
- Every button press causes two interrupts one when the button is pressed, the other when the button is released
- Any change (H>L or L>H) causes the interrupt lines to be asserted on the port's interrupt pin
- The PSoC has to poll each MCP23017 to determine which MCP23017 part caused the interrupt
- The I2CINT* line is connected to pin 68 (P12[3]) on the PSoC
- An inverter inside the PSoC changes the active low signal into an active high signal
- The I2CINT* pin on the PSoC is connected to an interrupt function in the PSoC
- InterruptType is set to LEVEL
- PSOC Creator generates the API for the interrupt function which corresponds to I2CINT*
- API functions that can be called from "anywhere" include:
- I2CINT_ISR_Start( ) - Start up the function and enable interrupts
- I2CINT_ISR_Disable( ) - Disable interrupts from the I2CINT* pin
- I2CINT_ISR_Enable( ) - Enable interrupts from the I2CINT* pin
- API functions that can be called from "anywhere" include:
- Had to manually create a function to handle the Interrupt
- I2CIntISR( ) - Read the Interrupt capture registers into variables
- Reads the six INTCAP registers (two in the Expansion MCP23017 and the four halves from the switches of the Front Panel MCP23017 parts)
- I2CIntISR( ) - Read the Interrupt capture registers into variables
- The Z80 reset was tied to the MCP23017 reset line
- The MCP23017 couldn't t be initialized while it is held in reset
- The PSoC monitor couldn't be used to test the interrupt function
- Reworked the reset line to access interrupts from the PSoC Monitor
- Cut etch
- Add pull-up resistor since MCP23017 part doesn't have internal pull-up
After Reworking RESET* to the Expansion MCP23017
After doing the rework to the card, it now processes interrupts consistently. The ARM Core no longer gets heap errors, etc. However, the bounce of the switches is now a problem. If the code is set with a breakpoint at the end of the I2CINT_ISR routine it shows all key presses and releases are being received. If the ARM is running full speed it looks like some presses are being missed.
Possible Ways to Debounce and Have Interrupts
One way might be to disable interrupts when the interrupt is received and then use a timer to only enable interrupts again after some number of mSecs have gone by. That has the potential to be relatively simple. Would be the first time I've explicitly used timers, though.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.