Chinaunix首页 | 论坛 | 博客
  • 博客访问: 306339
  • 博文数量: 63
  • 博客积分: 1482
  • 博客等级: 上尉
  • 技术积分: 1185
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-12 19:06
个人简介

hello world!

文章分类

全部博文(63)

分类: LINUX

2011-03-15 11:32:05

一、S3C2440中断控制要点

    S3C2440A 中的中断控制器可以从60 个中断源接收中断请求。这些中断源由内部外设提供,例如DMA 控制器、UARTIIC 等。在这些中断源中,UARTnAC97 和外部中断EINTn 对于中断控制器来说是或逻辑。当接收来自内部外设和外部中断请求引脚的多个中断请求时,在仲裁过程后中断控制器请求ARM920T FIR IRQ 中断。

                                 图中断流程图

    如果在ARM920T CPU 中的程序状态寄存器的位置1CPU 不能接收来自中断控制器的FIR,如果程序状态寄存器的位被置1,则CPU 不能接收来自中断控制器的IRQ。所以,通过清程序状态寄存器中的位和位且清0INTMSK 寄存器中的相应位,中断控制器可以接收中断。

   
 

二、寄存器设置

SRCPND 0X4A000000 R/W Indicate the interrupt request status.

0 = The interrupt has not been requested.

1 = The interrupt source has asserted。

 
 
 
 
三、中断程序源代码
     start.S
  1. /*
  2. *************************************************************************
  3. *
  4. * lcl bootloader
  5. *
  6. *************************************************************************
  7. */
  8. .globl _start
  9. _start: b start_code
  10. HandleUndef:
  11. b HandleUndef @ 0x04: 指未定义指令终止模式的向量地址
  12. HandleSWI:
  13. b HandleSWI @ 0x08 指管理模式,通过SWI指令进入
  14. HandlePerfetchAbort:
  15. b HandlePerfetchAbort @ 0x0c: 指令预取终止导致的异常的向量地址
  16. HandleDataAbort:
  17. b HandleDataAbort @ 0x10: 数据访问终止导致的异常的向量地址
  18. HandleNotUsed:
  19. b HandleNotUsed @ 0x14: 保留
  20. b HandleIRQ @ 0x18: 中断模式的向量地址
  21. HandleFIQ:
  22. b HandleFIQ @ 0x1c: 快中断模式的向量地址
  23. start_code:
  24. bl clock_init
  25. bl cpu_init_crit
  26. msr cpsr_c,#0xd2 @进入中断模式
  27. ldr sp,=3072 @设置中断模式堆栈指针
  28. msr cpsr_c,#0xdf @进入系统模式
  29. msr cpsr_c,#0x5f @开IRQ中断
  30. /*
  31. *run in sdram
  32. */
  33. ldr sp, =4096
  34. ldr lr, =halt_loop @返回地址
  35. ldr pc, = Main
  36. halt_loop:
  37. b halt_loop
  38. HandleIRQ:
  39. sub lr,lr,#4
  40. stmdb sp!,{r0-r12,lr} @保存使用到的寄存器至中断堆栈区
  41. ldr lr,=int_return @设置ISR的返回地址
  42. ldr pc,=EINT_Handle @调用中断服务函数
  43. int_return:
  44. ldmia sp!,{r0-r12,pc}^ @中断返回,恢复寄存器值,^表示将spsr的值复制到cpsr
  45. clock_init:
  46. #define pWTCON 0x53000000
  47. #define CLKDIVN 0x4C000014 /* clock divisor register */
  48. #define CLK_CTL_BASE 0x4C000000 /* clock base address */
  49. #define MDIV_405 0x7f << 12 /* MDIV 0x7f*/
  50. #define PSDIV_405 0x21 /* PDIV SDIV 0x2 0x1 */
  51. /* turn off the watchdog */
  52. ldr r0, =pWTCON
  53. mov r1, #0x0
  54. str r1, [r0]
  55. /* FCLK:HCLK:PCLK = 1:4:8 */
  56. ldr r0, =CLKDIVN
  57. mov r1, #5 //1:4:8
  58. str r1, [r0]
  59. mrc p15, 0, r1, c1, c0, 0 //切换到实时总线HCLK
  60. orr r1, r1, #0xc0000000
  61. mcr p15, 0, r1, c1, c0, 0
  62. mov r1, #CLK_CTL_BASE
  63. mov r2, #MDIV_405
  64. add r2, r2, #PSDIV_405
  65. str r2, [r1, #0x04] /* MPLLCON address Mpll=405MHZ */
  66. mov pc, lr
  67. /*
  68. *MMU and SDRAM initialize
  69. */
  70. cpu_init_crit:
  71. /*
  72. * flush v4 I/D caches
  73. */
  74. mov r0, #0
  75. mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
  76. mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
  77. /*
  78. * disable MMU stuff and caches
  79. */
  80. mrc p15, 0, r0, c1, c0, 0
  81. bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
  82. bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
  83. orr r0, r0, #0x00000002 @ set bit 2 (A) Align
  84. orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
  85. mcr p15, 0, r0, c1, c0, 0
  86. /*
  87. * before relocating, we have to setup RAM timing
  88. * because memory timing is board-dependend, you will
  89. * find a lowlevel_init.S in your board directory.
  90. */
  91. mov ip, lr
  92. bl memsetup /* memory control configuration */
  93. mov lr, ip
  94. mov pc, lr
  95. memsetup:
  96. /* memory control configuration */
  97. /* make r0 relative the current location so that it */
  98. /* reads SMRDATA out of FLASH rather than memory ! */
  99. #define MEM_CTL_BASE 0x48000000
  100. mov r1,#MEM_CTL_BASE
  101. adr r2,mem_cfg_val
  102. add r3,r1,#52
  103. 1:
  104. ldr r4, [r2], #4
  105. str r4, [r1], #4
  106. cmp r1, r3
  107. bne 1b
  108. mov pc,lr
  109. .align 4
  110. /* the literal pools origin */
  111. mem_cfg_val:
  112. .long 0x22011110
  113. .long 0x00000700
  114. .long 0x00000700
  115. .long 0x00000700
  116. .long 0x00000700
  117. .long 0x00000700
  118. .long 0x00000700 @BANK5
  119. .long 0x00018005
  120. .long 0x00018005
  121. .long 0x00ac03f4 @REFRESH // 12MHZ 0x00ac07a3
  122. .long 0x000000B1
  123. .long 0x00000030
  124. .long 0x00000030
    def.h
  1. #ifndef __DEF_H__
  2. #define __DEF_H__

  3. #define U32 unsigned int
  4. #define U16 unsigned short
  5. #define S32 int
  6. #define S16 short int
  7. #define U8 unsigned char
  8. #define    S8 char

  9. #define __REGb(x)    (*(volatile unsigned char *)(x))
  10. #define __REGw(x)    (*(volatile unsigned short *)(x))
  11. #define __REGi(x)    (*(volatile unsigned int *)(x))

  12. #endif /*__DEF_H__*/
    s3c2440_addr.h
  1. #ifndef _s3c2440_addr_h_
  2. #define _s3c2440_addr_h_

  3. #include "def.h"

  4. /***********uart address*********************/

  5. #define UART_CTL_BASE        0x50000000
  6. #define UART0_CTL_BASE        UART_CTL_BASE
  7. #define UART1_CTL_BASE        UART_CTL_BASE + 0x4000
  8. #define UART2_CTL_BASE        UART_CTL_BASE + 0x8000


  9. #define ULCON0            __REGi(UART0_CTL_BASE + 0x00)    /* R/W, UART line control register */
  10. #define UCON0            __REGi(UART0_CTL_BASE + 0x04)    /* R/W, UART control register */
  11. #define UFCON0            __REGi(UART0_CTL_BASE + 0x08)    /* R/W, UART FIFO control register */
  12. #define UMCON0            __REGi(UART0_CTL_BASE + 0x0C)    /* R/W, UART modem control register */
  13. #define UTRSTAT0        __REGi(UART0_CTL_BASE + 0x10)    /* R , UART Tx/Rx status register */
  14. #define UERSTAT0        __REGi(UART0_CTL_BASE + 0x14)    /* R , UART Rx error status register */
  15. #define UFSTAT0            __REGi(UART0_CTL_BASE + 0x18)    /* R , UART FIFO status register */
  16. #define UMSTAT0            __REGi(UART0_CTL_BASE + 0x1C)    /* R , UART Modem status register */
  17. #define UTXH0            __REGb(UART0_CTL_BASE + 0x20)    /* W 8bit , UART transmit(little-end) buffer */
  18. #define URXH0            __REGb(UART0_CTL_BASE + 0x24)    /* R 8bit , UART receive(little-end) buffer */
  19. #define UBRDIV0            __REGi(UART0_CTL_BASE + 0x28)    /* R/W, Baud rate divisor register */

  20. /* ... */
  21. #define UTRSTAT_TX_EMPTY    (1 << 2)
  22. #define UTRSTAT_RX_READY    (1 << 0)
  23. #define UART_ERR_MASK        0xF

  24. #define UART_BAUD_RATE        115200
  25. #define UART_PCLK_405_148 50625000
  26. #define UART_PCLK UART_PCLK_405_148
  27. #define UART_BRD ((UART_PCLK / (UART_BAUD_RATE * 16)) - 1)
  28.   

  29. /***********GPB GPG GPH GPIO address*********************/

  30. #define GPBCON (*(volatile unsigned long *) 0x56000010)
  31. #define GPBDAT (*(volatile unsigned long *) 0x56000014)
  32. #define GPBUP (*(volatile unsigned long *) 0x56000018)

  33. #define GPGCON (*(volatile unsigned long *) 0x56000060)
  34. #define GPGDAT (*(volatile unsigned long *) 0x56000064)
  35. #define GPGUP (*(volatile unsigned long *) 0x56000068)

  36. #define GPHCON         __REGi(0x56000070)             //R/W      Configures the pins of port H                             0x0

  37. #define GPHDAT          __REGi(0x56000074)             //R/W      The data register for port H                             Undef.

  38. #define GPHUP     __REGi(0x56000078)             //R/W      pull-up disable register for port H


  39. /* .. */    
  40. #define GPX_up              0x00000000 // up

  41. #define GPX_mask(pin) (~(3<<((pin)*2)))
  42. #define BIT_mask(pin) (~(1<<(pin)))

  43.     
  44.     
  45. #define GPH_tx0         (2<<(2*2))                     //10 = TXD[0]

  46. #define GPH_rx0         (2<<(3*2))                     //10 = RXD[0]


  47. #define GPB5_out          (1<<(5*2))
  48. #define GPB6_out          (1<<(6*2))
  49. #define GPB7_out          (1<<(7*2))
  50. #define GPB8_out          (1<<(8*2))

  51. #define GPG0_in          (0<<(0*2))
  52. #define GPG3_in          (0<<(3*2))
  53. #define GPG5_in          (0<<(5*2))
  54. #define GPG6_in          (0<<(6*2))

  55. #define GPG0_eint8      (2<<(0*2))
  56. #define GPG3_eint11      (2<<(3*2))
  57. #define GPG5_eint13      (2<<(5*2))
  58. #define GPG6_eint14      (2<<(6*2))

  59. /*****************timer register*****************/

  60. #define TCFG0 (*(volatile unsigned long *) 0x51000000)
  61. #define TCFG1 (*(volatile unsigned long *) 0x51000004)
  62. #define TCON (*(volatile unsigned long *) 0x51000008)
  63. #define TCNTB0 (*(volatile unsigned long *) 0x5100000C)
  64. #define TCMPB0 (*(volatile unsigned long *) 0x51000010)
  65. #define TCNTO0 (*(volatile unsigned long *) 0x51000014)

  66. /* .. */
  67. #define GPB0_pwm         (2<<(0*2))

  68. /*****************interrupt register*****************/
  69. #define INT_CTL_BASE        0x4A000000

  70. #define SRCPND            __REGi(INT_CTL_BASE + 0x00)
  71. #define INTMOD            __REGi(INT_CTL_BASE + 0x04)
  72. #define INTMSK            __REGi(INT_CTL_BASE + 0x08)
  73. #define PRIORITY        __REGi(INT_CTL_BASE + 0x0c)
  74. #define INTPND            __REGi(INT_CTL_BASE + 0x10)
  75. #define INTOFFSET        __REGi(INT_CTL_BASE + 0x14)
  76. #define SUBSRCPND        __REGi(INT_CTL_BASE + 0x18)
  77. #define INTSUBMSK        __REGi(INT_CTL_BASE + 0x1c)

  78. #define EINTMASK __REGi(0x560000A4) /*External interrupt mask register*/
  79. #define EINTPEND __REGi(0x560000A8) /*External interrupt pending register*/

  80. /* ... */
  81. #define INT_ADCTC        (1 << 31)    /* ADC EOC interrupt */
  82. #define INT_RTC            (1 << 30)    /* RTC alarm interrupt */
  83. #define INT_SPI1        (1 << 29)    /* UART1 transmit interrupt */
  84. #define INT_UART0        (1 << 28)    /* UART0 transmit interrupt */
  85. #define INT_IIC            (1 << 27)    /* IIC interrupt */
  86. #define INT_USBH        (1 << 26)    /* USB host interrupt */
  87. #define INT_USBD        (1 << 25)    /* USB device interrupt */
  88. #define INT_RESERVED24    (1 << 24)
  89. #define INT_UART1        (1 << 23)    /* UART1 receive interrupt */
  90. #define INT_SPI0        (1 << 22)    /* SPI interrupt */
  91. #define INT_MMC            (1 << 21)    /* MMC interrupt */
  92. #define INT_DMA3        (1 << 20)    /* DMA channel 3 interrupt */
  93. #define INT_DMA2        (1 << 19)    /* DMA channel 2 interrupt */
  94. #define INT_DMA1        (1 << 18)    /* DMA channel 1 interrupt */
  95. #define INT_DMA0        (1 << 17)    /* DMA channel 0 interrupt */
  96. #define INT_LCD            (1 << 16)    /* reserved for future use */
  97. #define INT_UART2        (1 << 15)    /* UART 2 interrupt */
  98. #define INT_TIMER4        (1 << 14)    /* Timer 4 interrupt */
  99. #define INT_TIMER3        (1 << 13)    /* Timer 3 interrupt */
  100. #define INT_TIMER2        (1 << 12)    /* Timer 2 interrupt */
  101. #define INT_TIMER1        (1 << 11)    /* Timer 1 interrupt */
  102. #define INT_TIMER0        (1 << 10)    /* Timer 0 interrupt */
  103. #define INT_WDT            (1 << 9)    /* Watch-Dog timer interrupt */
  104. #define INT_TICK        (1 << 8)    /* RTC time tick interrupt */
  105. #define INT_BAT_FLT        (1 << 7)
  106. #define INT_RESERVED6        (1 << 6)    /* Reserved for future use */
  107. #define INT_EINT8_23        (1 << 5)    /* External interrupt 8 ~ 23 */
  108. #define INT_EINT4_7        (1 << 4)    /* External interrupt 4 ~ 7 */
  109. #define INT_EINT3        (1 << 3)    /* External interrupt 3 */
  110. #define INT_EINT2        (1 << 2)    /* External interrupt 2 */
  111. #define INT_EINT1        (1 << 1)    /* External interrupt 1 */
  112. #define INT_EINT0        (1 << 0)    /* External interrupt 0 */

  113. #define INT_ADC            (1 << 10)
  114. #define INT_TC            (1 << 9)
  115. #define INT_ERR2        (1 << 8)
  116. #define INT_TXD2        (1 << 7)
  117. #define INT_RXD2        (1 << 6)
  118. #define INT_ERR1        (1 << 5)
  119. #define INT_TXD1        (1 << 4)
  120. #define INT_RXD1        (1 << 3)
  121. #define INT_ERR0        (1 << 2)
  122. #define INT_TXD0        (1 << 1)
  123. #define INT_RXD0        (1 << 0)

  124. #endif
    usrt0_init.h
  1. #ifndef __UART0_INIT_H__
  2. #define __UART0_INIT_H__

  3. void uart0_init();
  4. void Uart_SendString(char *pt);

  5. #endif
uart0_init.c
  1. /*
  2.   * uart0 lib
  3.   */
  4. #include "s3c2440_addr.h"

  5. void uart0_init()
  6. {
  7.     GPHCON &= (GPX_mask(2) & GPX_mask(3));
  8.     GPHCON |= GPH_tx0 | GPH_rx0;
  9.     GPHUP |= 0x0c;

  10.     ULCON0 = (0<< 3) | (0<< 2) | (3<< 0); // 8N1 ;normal mode , no parity , 1stop bit,8bit

  11.    UCON0 = (0<<10) | (1<< 9) | (1<< 6) | (1<< 2) | (1<< 0); // Select PCLK for the UART baud rate,polling mode, [9][6]:1 1

  12.    UFCON0 = 0x00;                          // disable FIFO

  13.    UMCON0 = 0x00;                          // disable AFC


  14.     UBRDIV0 = UART_BRD;                      // baud rate divisior 115200



  15. }

  16. static inline void putc(char data)
  17. {
  18.     while (!(UTRSTAT0 & 0x4)) ;                //Wait until THR is empty.

  19.     UTXH0 = data;
  20. }

  21. static inline unsigned char getc(void)
  22. {
  23.     while (!(UTRSTAT0 & (1))) ;                //Wait until THx is empty.

  24.     return URXH0;
  25. }

  26. void Uart_SendString(char *pt)
  27. {
  28.     while (*pt)
  29.         putc(*pt++);
  30. }
    mem.lds
  1. /*
  2.  *lcl bootloader mem.lds
  3.  */

  4. OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
  5. OUTPUT_ARCH(arm)
  6. ENTRY(_start)

  7. SECTIONS {
  8.   . = 0x00000000;

  9.   . = ALIGN(4);
  10.   .init : AT(0) {start.o}

  11.   . = 0x00000800;
  12.   .text : AT(2048) { *(.text) }
  13.     
  14.   .rodata ALIGN(4) : AT((LOADADDR(.text)+SIZEOF(.text)+3)&~(0x03)) { *(.rodata*) }

  15.   .data ALIGN(4) : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+3)&~(0x03)) { *(.data) }
  16.   
  17.   . = ALIGN(4);
  18.   __bss_start = .;
  19.   .bss :{ *(.bss) *(COMMON)}
  20.   __bss_end = .;
  21. }
    Makefile
  1. objs := start.o main.o uart0_init.o interrupt.o

  2. sdram.bin : $(objs)
  3.     arm-linux-ld -Tmem.lds    -o sdram_elf $^
  4.     arm-linux-objcopy -O binary -S sdram_elf $@
  5.     arm-linux-objdump -D -m arm sdram_elf > sdram.dis
  6.     arm-linux-objdump -dx sdram_elf > mem_bin.map
  7.     rm -f sdram.dis sdram_elf *.o

  8. %.o:%.c
  9.     arm-linux-gcc -Wall -c -O2 -o $@ $<

  10. %.o:%.S
  11.     arm-linux-gcc -Wall -c -O2 -o $@ $<

  12. clean:
  13.     rm -f sdram.bin mem_bin.map
    main.c
  1. /*
  2. GPBCON 0x56000010 Port B control
  3. GPBDAT 0x56000014 Port B data
  4. GPBUP 0x56000018 Pull-up control B

  5. LED1 GPB5 LED2 GPB6 LED3 GPB7 LED4 GPB8

  6. */

  7. #include "uart0_init.h"
  8. #include "s3c2440_addr.h"
  9. #include "interrupt.h"

  10. void leds_init()
  11. {
  12.     /*GPBCON &= (GPX_mask(5) & GPX_mask(6) & GPX_mask(7) & GPX_mask(8));
  13.     GPBCON |= (GPB5_out | GPB6_out | GPB7_out | GPB8_out);
  14.     GPBUP = GPX_up;
  15.     GPBDAT |=( 0xf << 5 );*/
  16.     GPBCON = (GPB5_out | GPB6_out | GPB7_out | GPB8_out);
  17.     GPBUP     = GPX_up;
  18. }
  19. void buttons_eint_init()
  20. {
  21.     GPGCON &= (GPX_mask(0) & GPX_mask(3) & GPX_mask(5) & GPX_mask(6));
  22.     GPGCON |= (GPG0_eint8 | GPG3_eint11 | GPG5_eint13 | GPG6_eint14);
  23. }

  24. int Main()
  25. {
  26.     unsigned long dwDat;
  27.     leds_init();
  28.     buttons_eint_init();
  29.     uart0_init();
  30.     irq_init();
  31.         
  32.     GPBDAT |=( 0xf << 5 );
  33.     
  34.     Uart_SendString("\r wait interrupt. \r\n");    

  35.     while (1)
  36.     {
  37.     GPBDAT |=( 0xf << 5 );
  38.     }

  39.     return 0;
  40. }
 
以下为能直接运行的二进制文件,下载到Nand Flash 的 Black0 直接以Nand Flash运行。
 
 
 
阅读(1521) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~