Skip to content
Snippets Groups Projects
Commit 7ab05050 authored by cnlohr's avatar cnlohr
Browse files

Example how to use the pin-change interrupt to monitor a cap touch sensor with...

Example how to use the pin-change interrupt to monitor a cap touch sensor with about 6 bits of accuracy.
parent 7083e77c
No related branches found
No related tags found
No related merge requests found
all : flash
TARGET:=touch_exti
include ../../ch32v003fun/ch32v003fun.mk
flash : cv_flash
clean : cv_clean
#ifndef _FUNCONFIG_H
#define _FUNCONFIG_H
// Though this should be on by default we can extra force it on.
#define FUNCONF_USE_DEBUGPRINTF 1
#define FUNCONF_DEBUGPRINTF_TIMEOUT (1<<31) // Wait for a very very long time.
// high res systick.
#define FUNCONF_SYSTICK_USE_HCLK 1
#define CH32V003 1
#endif
/* Demo showing how to use eternal interrupts to detect touch. This allows for
both low resolution touch (about 6-7 bits for a 6mm x 10mm pad) by using
internal pull up resistors, as well as high resolution touch (8+ bits per
pad) with a 560k pull up resistor.
The current configuration uses:
PORT C, pin 4 - regular touch pad, no extra components.
PORT C, pin 5 - high res pad, with pull-up to 3.3v with 560k resistor.
PORT D, pin 5 - regular touch pad, no extra components.
Note: You may want to consider including a 1k series resistor for better
ESD performance.
*/
#include "ch32v003fun.h"
#include <stdio.h>
uint32_t count;
uint32_t endtime;
void EXTI7_0_IRQHandler( void ) __attribute__((interrupt));
void EXTI7_0_IRQHandler( void )
{
endtime = SysTick->CNT;
EXTI->INTFR = 0xffffffff;
}
#define GPIOPortByBase( i ) ((GPIO_TypeDef *)(GPIOA_BASE + 0x0400 * (i)))
// The "port" is:
// 0 for Port A
// 1 for Port B
// 2 for Port C
// 3 for Port D
int MeasureTouch( int portno, int pin, int pu_mode )
{
uint32_t starttime;
GPIO_TypeDef * port = GPIOPortByBase( portno );
uint32_t pinx4 = pin<<2;
// Mask out just our specific port. This way we don't interfere with other
// stuff that may be on this port.
uint32_t base = port->CFGLR & (~(0xf<<pinx4));
// Mode for CFGLR when asserted.
uint32_t setmode = base | (GPIO_CFGLR_OUT_2Mhz_PP)<<(pinx4);
// Mode for CFGLR when it drifts.
uint32_t releasemode = base | (pu_mode)<<(pinx4);
// Assert pin
port->CFGLR = setmode;
port->BSHR = 1<<(pin+16);
// Setup pin-change-interrupt. This will trigger when the voltage on the
// pin rises above the schmitt trigger threshold.
AFIO->EXTICR = portno<<(pin*2);
EXTI->INTENR = 0xffffffff; // Enable EXT3
EXTI->RTENR = 0xffffffff; // Rising edge trigger
// Tricky, we want the release to happen at an un-aligned address.
// This actually doubles our touch sensor resolution.
asm volatile( ".balign 4; c.nop" );
port->CFGLR = releasemode;
starttime = SysTick->CNT;
endtime = starttime - 1;
port->BSHR = 1<<(pin);
// Allow up to 256 cycles for the pin to change.
#define DELAY8 \
asm volatile( "c.nop;c.nop;c.nop;c.nop;c.nop;c.nop;c.nop;c.nop;" );
DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8
DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8
DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8
DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8 DELAY8
// Disable EXTI
EXTI->INTENR = 0;
// Optional assert pin when done to prevent it from noodling around.
//port->CFGLR = setmode;
//port->BSHR = 1<<(pin+16);
return endtime - starttime;
}
int main()
{
SystemInit();
// Enable GPIOs and pin-change interrupt.
RCC->APB2PCENR |= RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO;
// enable pin-change-interrupt.
NVIC_EnableIRQ( EXTI7_0_IRQn );
while(1)
{
printf( "%4d %4d %4d\n",
MeasureTouch( 2, 4, GPIO_CFGLR_IN_PUPD ), // Port C4
MeasureTouch( 3, 5, GPIO_CFGLR_IN_PUPD ), // Port D5
MeasureTouch( 2, 5, GPIO_CFGLR_IN_FLOAT ) ); // Port C5, with external pull-up.
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment