Take KEY2 controlling LED3 on and off as an example:
1. Polling method
【0】Detect button k2. When button k2 is pressed once, LED2 flashes once.
【1】Check the schematic diagram, connect the pins and control logic
(1) Push button K2 is connected to the GPX1_1 pin
(2) Control logic
K2 is pressed ---- K2 is closed ---- GPX1_1 is low voltage
K2 is normal ---- K2 is open ---- GPX1_1 is high voltage
【2】Check the corresponding chip manual
【2-1】Cyclic detection of the input level of the GPX1_1 pin. When the voltage is low, the button is pressed.
(1) Configure the GPX1_1 pin function as input and set the internal pull-up and pull-down to disable.
GPX1.CON = GPX1.CON &(~(0xf<<4)) ;
GPX1.PUD = GPX1.PUD & ~(0x3 << 2);
(2) Loop detection:
while(1)
{
if(!(GPX1.DAT & (0x1<<1))) // Returns true, the button is pressed
{
msdelay(10);
if(!(GPX1.DAT & (0x1<<1))) //Secondary detection, debounce
{
GPX2.DAT |= 0x1 << 7; //Turn on LED2
mydelay_ms(500);
GPX2.DAT &= ~(0x1<<7); //Turn off LED2
mydelay_ms(500);
while(!(GPX1.DAT & (0x1<<1)));
}
}
}
This polling method always occupies the CPU and is not conducive to operation.
2. Interrupt Mode
When K2 is pressed, the level obtained by the GPX1_1 pin is regarded as an abnormal event. Enable exception handling, and respond to exception handling every time k2 is pressed. The SPI transfer process is shown as follows:
Note:
The Exynos4412 interrupt controller includes 160 interrupt control sources, which come from soft interrupts (SGI), private external interrupts (PPI), and public external interrupts (SPI).
Exynos4412 uses GIC interrupt controller, mainly because Contex-A9 is a multi-core processor. GIC (Generic Interrupt Controller) is used to select which CPU interface to use. It has two main functions:
1) Distributor: Set a switch to determine whether to receive an external interrupt source; select the CPU interface for the interrupt source;
2) CPU interface: Set a development to determine whether to accept the interrupt source request;
The specific implementation is as follows:
1. Peripheral level 1---Set up GPIO controller
1-- Disable the pull-up and pull-down of the GPX1_1 pin
GPX1PUD[3:2]= 0b00;
2 -- Set the GPX1_1 pin function to interrupt function WAKEUP_INT1[1] --- EXT_INT41[1]
GPX1CON[7:4] = 0xf
3 -- EXT_INT41CON configures the trigger level
Currently configured as falling edge trigger:
EXT_INT41CON[6:4] = 0x2
4 -- EXT_INT41_FLTCON0 configures interrupt pin filtering
It is enabled by default and does not require configuration.
5 -- EXT_INT41_MASK interrupt enable register
Enable INT41[1]
EXT_INT41_MASK[1] = 0b0
6 -- EXT_INT41_PEND interrupt status register
When the GPX1_1 pin receives an interrupt signal, an interrupt occurs, and the corresponding bit of the interrupt status register EXT_INT41_PEND is automatically set to 1.
Note: When the interrupt processing is completed, the corresponding status bit needs to be cleared. Set 1 to clear 0.
EXT_INT41_PEND[1] =0b1
2. Interrupt Controller
1-- Find the name of the peripheral interrupt and the corresponding name of the GIC interrupt controller
Check the chip manual (this example: Exynos_4412 -- Table 9.2)
WAKEUP_INT1[1] --- EXT_INT41[1] --- INT[9] --- SPI[25]/ID[57]
It corresponds to INT[9], and the interrupt ID is 57. This is very important and plays a big role in the subsequent register settings;
The following is the specific process of peripheral and interrupt controller processing:
2 -- GIC enabled
ICDDCR =1;
Enable the allocator.
3 -- Enable the corresponding interrupt to the distributor
ICDISER.ICDISER1 |= (0x1 << 25); //57/32 =1...25 Get the integer (which register) and the remainder (which bit)
ICDISER is used to enable the corresponding interrupt to the distributor. One bit controls one interrupt source. One ICDISER can control 32 interrupt sources. Here, the interrupt ID corresponding to INT[9] is 57, so it is set in ICDSER1. 57/32 = 1 remainder 25, so here the 25th position of ICDISER1 is set to 1.
4 -- Select CPU interface
Set SPI[25]/ID[57] to be handled by which CPU, currently set to IRQ interrupt of cpu0
ICDIPTR.ICDIPTR14 |= 0x01<<8; //SPI25 interrupts are sent to processor 0 //57/4 = 14..1 [15:8] of register 14
Each 8 bits of the ICDIPTR register controls an interrupt source
5 -- Globally enable cpu0 interrupt processing
CPU0.ICCICR |= 0x1;
Enable interrupt to CPU.
6 -- Priority mask register, set cpu0 to handle all interrupts.
CPU0.ICCPMR = 0xFF;
3. ARM core (cpu0)
After setting the first two steps, you can wait for the interrupt to occur. When the interrupt occurs, the ARM core processes as follows:
1-- Four major steps and three minor steps--- Hardware
(1) Copy CPSR to SPSR_ 2 -- Interrupt service routine --- start.S assembly .text .global _start _start: b reset ldr pc,_undefined_instruction ldr pc,_software_interrupt ldr pc,_prefetch_abort ldr pc,_data_abort ldr pc,_not_used ldr pc,_irq ldr pc,_fiq _undefined_instruction: .word _undefined_instruction _software_interrupt: .word _software_interrupt _prefetch_abort: .word _prefetch_abort _data_abort: .word _data_abort _not_used: .word _not_used _irq: .word irq_handler _fiq: .word _fiq reset: ldr r0,=0x40008000 mcr p15,0,r0,c12,c0,0 @ Vector Base Address Register init_stack: ldr r0,stacktop /*get stack top pointer*/ /********svc mode stack********/ mov sp,r0 sub r0,#128*4 /*512 byte for irq mode of stack*/ /****irq mode stack**/ msr cpsr,#0xd2 mov sp,r0 sub r0,#128*4 /*512 byte for irq mode of stack*/ /***fiq mode stack***/ msr cpsr,#0xd1 mov sp,r0 sub r0,#0 /***abort mode stack***/ msr cpsr,#0xd7 mov sp,r0 sub r0,#0 /***undefine mode stack***/ msr cpsr,#0xdb mov sp,r0 sub r0,#0 /*** sys mode and usr mode stack ***/ msr cpsr,#0x10 mov sp,r0 /*1024 byte for user mode of stack*/ b main .align 4 /**** swi_interrupt handler ****/ /**** irq_handler ****/ irq_handler: sub lr,lr,#4 stmfd sp!,{r0-r12,lr} .weak do_irq bl do_irq ldmfd sp!,{r0-r12,pc}^ stacktop: .word stack+4*512 .data stack: .space 4*512 3--Interrupt handler--- do_irq function C language (function prototype void name(void)) (1) Read the interrupt ID register (ICCIAR) being processed irq_num = (CPU0.ICCIAR & 0x1FF); (2) According to irq_num, branch to handle interrupt switch(irq_num) { . case 57: break; .... } (3-1) i. Peripheral level, EXT_INT41_PEND |= 0x1 << 1; Here is the C program: #include "exynos_4412.h" #include "led.h" void delay_ms(unsigned int num) { int i,j; for(i=num; i>0;i--) for(j=1000;j>0;j--) ; } void do_irq(void) { static int a = 1; int irq_num; irq_num = CPU0.ICCIAR&0x3ff; //Get the interrupt number switch(irq_num) { case 57: printf("in the irq_handlern"); if(a) led_on(1); else led_off(1); a = !a; EXT_INT41_PEND = EXT_INT41_PEND |((0x1 << 1)); // Clear GPIO interrupt flag ICDICPR.ICDICPR1 = ICDICPR.ICDICPR1 | (0x1 << 25); // Clear GIC interrupt flag break; } CPU0.ICCEOIR = CPU0.ICCEOIR&(~(0x3ff))|irq_num; //Clear CPU interrupt flag } /* * Bare metal code, different from the LINUX application layer, must add loop control */ int main (void) { GPX1.CON =GPX1.CON & (~(0xf << 4)) |(0xf << 4); //Configure the pin function as external interrupt GPX1.PUD = GPX1.PUD & (~(0x3 << 2)); //Turn off the pull-up and pull-down resistors EXT_INT41_CON = EXT_INT41_CON &(~(0xf << 4))|(0x2 << 4); //External interrupt trigger mode EXT_INT41_MASK = EXT_INT41_MASK & (~(0x1 << 1)); // Enable interrupt ICDDCR = 1; // Enable the distributor ICDISER.ICDISER1 = ICDISER.ICDISER1 | (0x1 << 25); // Enable the corresponding interrupt to the distributor ICDIPTR.ICDIPTR14 = ICDIPTR.ICDIPTR14 & (~(0xff << 8))|(0x1 << 8); //Select CPU interface CPU0.ICCPMR = 255; //Interrupt mask priority CPU0.ICCICR = 1; // Enable interrupt to CPU led_init(); while(1) { } return 0; }
(2) Set appropriate CPSR bits:
(2-1) - Change processor state to ARM state
(2-2) - Change processor mode to corresponding exception mode
(2-3) - Set interrupt disable bit to disable corresponding interrupt (if necessary)
(3) Save return address to LR_
(4) Set PC to corresponding exception vector
(3) Clear the interrupt status bit
(3-2) ii. GIC level, ICDICPR.ICDICPR1 |= 0x1 << 25;
(3-3) iii. CPU0 level CPU0.ICCEOIR = (CPU0.ICCEOIR & ~(0x1FF)) | irq_num;
Previous article:Exynos 4412 eMMC configuration and usage
Next article:Exynos4412 bare metal development - RTC real-time clock unit
Recommended ReadingLatest update time:2024-11-16 11:31
- Popular Resources
- Popular amplifiers
- Production of Linux file system without interface for embedded development board
- Samsung Quad-core 4412 Embedded Development Board Xunwei 4412 Development Board Introduction
- Introduces the CAN interrupt structure function of C167CR and the application of the standard CAN interrupt structure
- USB Complete The Developer\'s Guide 5ed (USB Development Complete 5th Edition)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- When BLE meets MEMS——Device Selection
- Oracle laid off employees again, rumored to be N+6 compensation, some people received 1 million compensation
- GPIO pin multiplexing in C6455
- [ESK32-360 Review] Potentiometer controls USB camera image brightness
- Discussion on the practical ability of silicone pads
- The pitfalls of HC32L110 series burning
- Segment LCD, how to light up the desired part
- Active-Semi holds "Day One" event and officially joins the Qorvo family
- Shenzhen Electronic Hardware Engineer
- "Blink" on the "New Version of Bluesight AB32VG1 RISC-V Development Board"