Tiny4412 external interrupt

Publisher:风暴使者Latest update time:2021-12-22 Source: eefocusKeywords:Tiny4412 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1: External interrupt  

When we studied key drivers before, we detected whether the key was pressed by round-robin (that is, what we call an infinite loop). Although this can detect the key press, it wastes too much system resources. Regardless of whether our key interrupt occurs, the CPU must keep detecting; in this way, the operating system cannot do other things, so this is definitely not possible, so we can solve it through external interrupts;


To handle an interrupt, we need to understand the mode, and to understand the mode, we need to understand MMU; after learning these, we can return to deal with the problems left when we drove the key;


Through the previous push-to-drive, we have learned the position of the push-to-drive on the board, the circuit diagram of the button, and the function of its pins. Now let's take a look at the steps to implement this program:


We know that the registers that control the buttons are:

 

The external interrupts correspond to:

0xf = EXT_INT43[2]

In EXT_INT43[2] we select edge trigger mode:

Through the key on the core board pin diagram we can know that the external interrupt source is 26 and the interrupt number is 64

Registers that we need to configure:

(1) EXT_INT43PEND (2) EXT_INT43MASK (3) EXT_INT43CON

It should be noted that: interrupt status: EXT_INT43_PEND[2], especially to clear the interrupt, set the value to 1.


Implementing an external interrupt generally requires five steps:

  (1) CPU allows interrupts

  (2) Enable GIC

  (3) Configure external interrupt register (xeint)

  (4) Configure GPIO (General Purpose Input Output, referred to as GPIO. Each GPIO port can be configured as input or output through software)

  (5) External interrupt source


The following is the specific code for implementation:

 1 #ifndef __BUNFLY_H

 2 #define __BUNFLY_H

 3 

 4 #define ICCICR_CPU0 (*(volatile unsigned long *)0x10480000)

 5 #define ICCPMR_CPU0 (*(volatile unsigned long *)0x10480004)

 6 #define ICDDCR (*(volatile unsigned long *)0x10490000)

 7 #define ICDIPR0_CPU0 (*(volatile unsigned long *)0x10490400)

 8 #define ICDIPTR0_CPU0 (*(volatile unsigned long *)0x10490800)

 9 #define ICDISER0_CPU0 (*(volatile unsigned long *)0x10490100)

10 #define ICDSGIR (*(volatile unsigned long *)0x10490f00)

11 #define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010)

12 #define ICCIAR_CPU0 (*(volatile unsigned long *)0x1048000c)

13 #define ICDIPR2_CPU0 (*(volatile unsigned long *)0x10490408)

14 #define ICDIPTR2_CPU0 (*(volatile unsigned long *)0x10490808)

15 #define ICDIPR3_CPU0 (*(volatile unsigned long *)0x1049040c)

16 #define ICDIPTR3_CPU0 (*(volatile unsigned long *)0x1049080c)

17 #define ICDIPR16_CPU0 (*(volatile unsigned long *)0x10490440)

18 #define ICDIPTR16_CPU0 (*(volatile unsigned long *)0x10490840)

19 #define ICDIPR18_CPU0 (*(volatile unsigned long *)0x10490448)

20 #define ICDIPTR18_CPU0 (*(volatile unsigned long *)0x10490848)

21 #define ICDISER2_CPU0 (*(volatile unsigned long *)0x10490108)

twenty two 

23 #define WTCON (*(volatile unsigned long *)0x10060000)

24 #define WTDAT (*(volatile unsigned long *)0x10060004)

25 #define WTCNT (*(volatile unsigned long *)0x10060008)

26 #define WTCLRINT (*(volatile unsigned long *)0x1006000C)

27 

28 #define EXT_INT43_CON (*(volatile unsigned long *)0x11000e0c)

29 #define EXT_INT43_MASK (*(volatile unsigned long *)0x11000f0c)

30 #define EXT_INT43_PEND (*(volatile unsigned long *)0x11000f4c)

31 #define GPX3CON (*(volatile unsigned long *)0x11000c60)

32 

33 #define GPM4CON (*(volatile unsigned long *)0x110002e0)

34 #define GPM4DAT (*(volatile unsigned long *)0x110002e4)

35 

36 #endif //__BUNFLY_H


  1 #include "bunfly.h"

  2 

  3 int (*printf)(char *, ...) = 0xc3e114d8;

  4 void enable_mmu();

  5 void init_table(unsigned long *addr);

  6 void memcpy(unsigned char *dest, unsigned char *src, int len);

  7 extern unsigned long vector_start;

  8 void do_irq();

  9 

 10 int main()

 11 {

 12 memcpy(0x70000000, vector_start, 0x10000);

 13 enable_mmu();

 14     

 15 *(unsigned long *)0x47000000 = do_irq;

 16     

 17 //step 1: cpu permit interrupt

 18 __asm__ __volatile__ (

 19 "mrs r0, cpsrn"

 20 "bic r0, r0, #0x80n"

 21 "msr cpsr, r0n"

 22 ::: "r0"

 twenty three );

 twenty four     

 25 //step 2: GIC (cgi) enable

 26 ICCICR_CPU0 = 1; // Main switch

 27 ICCPMR_CPU0 = 0xff; //Total priority (threshold)

 28 ICDDCR = 1; //Interrupt switch

 29 

 30 ICDIPR16_CPU0 = (0 << 0); //This interrupt priority

 31 ICDIPTR16_CPU0 = (1 << 0); //target cpu

 32 ICDISER2_CPU0 = (1 << 0); // Enable this interrupt

 33     

 34 //step 3: Xeint

 35 EXT_INT43_CON = (4 << 8); //Triggers Both edge (set to edge trigger)

 36 EXT_INT43_MASK = 0; // Enable interrupt

 37     

 38 //step 4: set gpio

 39 GPX3CON = (0xf << 8); //0xF = EXT_INT43[2] (gpio configured as external interrupt)

 40     

 41 //step 5: interrupt source

 42 

 43 printf("welcome back");

 44 }

 45 

 46 void do_irq()

 47 {

 48 unsigned long data = ICCIAR_CPU0;

 49 int irq = data & 0x3ff; //Get the interrupt number

 50 int cpu = (data >> 10) & 0x7; //Get the target cpu 

 51 ICCEOIR_CPU0 = irq | (cpu << 10); // Clear interrupt

 52 EXT_INT43_PEND |= (1 << 2); // Clear interrupt

 53 printf("key 1 down, cpu is %d, irq is %dn", cpu, irq);    

 54 }

 55 

 56 void enable_mmu()

 57 {

 58 unsigned long addr = 0x50000000;

 59 init_table(addr);

 60 unsigned long mmu = 0;

 61 mmu = 1 | (1 << 1) | (1 << 3) | (1 << 8);

 62     

 63 __asm__ __volatile__ (

 64 "mov r0, #3n"

 65 "MCR p15, 0, r0, c3, c0, 0n"

 66 "MCR p15, 0, %0, c2, c0, 0n"

 67 "MCR p15, 0, %1, c1, c0, 0n"

 68 :

 69 : "r" (addr), "r" (mmu)

 70 :

 71 );

 72 }

 73 

 74 void init_table(unsigned long *addr)

 75 {

 76 unsigned long va = 0;

 77 unsigned long phys = 0;

 78     

 79 for(va = 0x40000000; va < 0x80000000; va+=0x100000)

 80 {

 81 phys = va;

 82 addr[va >> 20] = phys | 2;

 83 }

 84 

 85 for(va = 0x10000000; va < 0x14000000; va+=0x100000)

 86 {

 87 phys = va;

 88 addr[va >> 20] = phys | 2;

 89 }

 90 

 91 for(va = 0x0; va < 0x10000000; va+=0x100000)

 92 {

 93 phys = va + 0x70000000;

 94 addr[va >> 20] = phys | 2;

 95 }

 96 }

 97 

 98 __asm__ (

 99 "vector:n"

100 "b reset"

101 "b undefinedn"

102 " b swin"

103 "b pre_abtn"

104 "b data_abtn"

105 ".word 0x0n"

106 "b irqn"

107 "b fiqn"

108 

109 "reset:n"

110 "undefined:n"

111 "mov sp, #0x47000000n"

112 "stmdb sp!, {r0-r12, lr}n"

113 

114 "ldr r3, =0x47000004n"

115 "ldr r2, [r3]n"

116 "blx r2n"

117     

118 "mov sp, #0x47000000n"

119 "ldmdb sp, {r0-r12, pc}^n"

120 "swi:n"

121 "mov sp, #0x47000000n"

122 "stmdb sp!, {r0-r12, lr}n"

123 

124 "mov sp, #0x47000000n"

125 "ldmdb sp, {r0-r12, pc}^n"

126 "pre_abt:n"

127 "data_abt:n"

128 "mov sp, #0x47000000n"

129 "sub lr, lr, #4n"

130 "stmdb sp!, {r0-r12, lr}n"

131 

132 "ldr r3, =0x47000008n"

133 "ldr r2, [r3]n"

134 "blx r2n"

135 

136 "mov sp, #0x47000000n"

137 "ldmdb sp, {r0-r12, pc}^n"

138 "irq:n"

139 "mov sp, #0x47000000n"

140 "sub lr, lr, #4n"

141 "stmdb sp!, {r0-r12, lr}n"

142 

143 "mov r3, #0x47000000n"

144 "ldr r2, [r3]n"

145 "blx r2n"

146     

147 "mov sp, #0x47000000n"

148 "ldmdb sp, {r0-r12, pc}^n"

149 "fiq:n"

150 

151 ".global vector_startn"

152 "vector_start:n"

153 ".word vectorn"

154 );

155 

156 void memcpy(unsigned char *dest, unsigned char *src, int len)

157 {

158 int i = 0;

159 for(i = 0; i < len; i++)

160 dest[i] = src[i];

161 }


Next, we control the watchdog through the external interrupt (KEY1), and then control the LED light through the watchdog. When key1 is pressed, the LED light starts flashing, and press it again to stop flashing:


The code is posted below:


 1 #ifndef __BUNFLY_H

 2 #define __BUNFLY_H

 3 

 4 #define ICCICR_CPU0 (*(volatile unsigned long *)0x10480000)

 5 #define ICCPMR_CPU0 (*(volatile unsigned long *)0x10480004)

 6 #define ICDDCR (*(volatile unsigned long *)0x10490000)

 7 #define ICDIPR0_CPU0 (*(volatile unsigned long *)0x10490400)

 8 #define ICDIPTR0_CPU0 (*(volatile unsigned long *)0x10490800)

 9 #define ICDISER0_CPU0 (*(volatile unsigned long *)0x10490100)

10 #define ICDSGIR (*(volatile unsigned long *)0x10490f00)

11 #define ICCEOIR_CPU0 (*(volatile unsigned long *)0x10480010)

12 #define ICCIAR_CPU0 (*(volatile unsigned long *)0x1048000c)

13 #define ICDIPR2_CPU0 (*(volatile unsigned long *)0x10490408)

14 #define ICDIPTR2_CPU0 (*(volatile unsigned long *)0x10490808)

15 #define ICDIPR3_CPU0 (*(volatile unsigned long *)0x1049040c)

16 #define ICDIPTR3_CPU0 (*(volatile unsigned long *)0x1049080c)

17 #define ICDIPR16_CPU0 (*(volatile unsigned long *)0x10490440)

18 #define ICDIPTR16_CPU0 (*(volatile unsigned long *)0x10490840)

19 #define ICDIPR18_CPU0 (*(volatile unsigned long *)0x10490448)

20 #define ICDIPTR18_CPU0 (*(volatile unsigned long *)0x10490848)

21 #define ICDISER2_CPU0 (*(volatile unsigned long *)0x10490108)

twenty two 

23 #define WTCON (*(volatile unsigned long *)0x10060000)

24 #define WTDAT (*(volatile unsigned long *)0x10060004)

25 #define WTCNT (*(volatile unsigned long *)0x10060008)

26 #define WTCLRINT (*(volatile unsigned long *)0x1006000C)

27 

28 #define EXT_INT43_CON (*(volatile unsigned long *)0x11000e0c)

29 #define EXT_INT43_MASK (*(volatile unsigned long *)0x11000f0c)

30 #define EXT_INT43_PEND (*(volatile unsigned long *)0x11000f4c)

31 #define GPX3CON (*(volatile unsigned long *)0x11000c60)

32 

33 #define GPM4CON (*(volatile unsigned long *)0x110002e0)

34 #define GPM4DAT (*(volatile unsigned long *)0x110002e4)

35 

36 #endif //__BUNFLY_H


  1 #include "bunfly.h"

  2 

  3 void (*udelay)(int) = 0xc3e25f90;

  4 int (*printf)(char *, ...) = 0xc3e114d8;

  5 void enable_mmu();

  6 void init_table(unsigned long *addr);

  7 void memcpy(unsigned char *dest, unsigned char *src, int len);

  8 extern unsigned long vector_start;

  9 void do_irq();

 10 void led_on();

 11 void led_off();

 12 void wdt_on();

 13 void wdt_off();

 14 

 15 int main()

 16 {    

 17 memcpy(0x70000000, vector_start, 0x1000);    

 18 enable_mmu();

 19 

 20 *(unsigned long *)0x47000000 = do_irq;

 twenty one 

 22 //step 1: cpu permit interrupt

 23 __asm__ __volatile__(

 24 "mrs r0, cpsrn"

 25 "bic r0,r0, #0x80n"

 26 "msr cpsr, r0n"

 27 :::"r0"

 28 );

 29 

 30 //step 2: GIC (cgi) enable

 31 ICCICR_CPU0 = 1; // Main switch

 32 ICCPMR_CPU0 =0xff; //Total priority

[1] [2]
Keywords:Tiny4412 Reference address:Tiny4412 external interrupt

Previous article:S3C6410 board transplanted Android2.2
Next article:Tiny4412 interrupt watchdog

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号