ARM Applications


 
* Update history

- 2012.11.21 : Ãʱâ Release



 
5. S3C2440 °³¹ßº¸µå ½Ç½À
   5.1 S3C2440 Startup ÄÚµå ºÐ¼®
   5.2 GPIO Output( LED On/Off )
   5.3 GPIO Input( KEY Input) - Polling
   5.4 GPIO Input( KEY Input) - Interrupt
   5.5 TIMER
   5.6 PWM Buzzer
   5.7 UART


 
5Àå¿¡¼­´Â ¿ì¸®°¡ ½Ç½À¿¡ »ç¿ëÇÒ Mini2440 °³¹ßº¸µå¸¦ °¡Áö°í Áö±Ý±îÁö ÀÌ·ÐÀ¸·Î¸¸ °øºÎÇß´ø ¾î¼Àºí¸®¾î¿Í C¾ð¾î¸¦ ÀÌ¿ëÇؼ­ ÁÖº¯ ÀåÄ¡µéÀ» Á¦¾îÇÏ´Â ½Ç½ÀÀ» Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ½ÇÁ¦ ŸÄϺ¸µå¿¡ ³»°¡ ÀÛ¼ºÇÑ ÇÁ·Î±×·¥À» ´Ù¿î·ÎµåÇÏ¿© µ¿ÀÛÀ» È®ÀÎÇÏ´Â ÀÏÀº Ç×»ó °¡½¿ÀÌ ¼³·¹ÀÔ´Ï´Ù.

5. S3C2440 °³¹ßº¸µå ½Ç½À

5.1 S3C2440 Startup ÄÚµå ºÐ¼®

ARM°³¹ßº¸µåÀÇ ºÎÆ®ÄÚµå(Startup)¿¡´Â Áö±Ý±îÁö ÀÌ·ÐÀ¸·Î ¹è¿ü´ø ³»¿ëµéÀÌ °ÅÀÇ ¸ðµÎ Æ÷ÇÔÀÌ µÇ¾î ÀÖ½À´Ï´Ù. ºÎÆ® Äڵ常 Àß ºÐ¼®Çصµ CPUÀÇ 50% ÀÌ»óÀº ¾Ë°í ÀÖ´Ù°í Çصµ °ú¾ðÀÌ ¾Æ´Õ´Ï´Ù. ºÎÆ®ÄÚµå ±â´ÉÀ» °£·«ÇÏ°Ô ¿ä¾àÇØ º¸¸é ¾Æ·¡¿Í °°½À´Ï´Ù.

– Clock & Power Initialization
– Setup each exception handler
– Memory (SDRAM) Initialization
– Peripheral Initialization
– Stack Initialization for each Processor Mode
– Interrupt Handler Setup
– Segment Initialization
– Jump to User Application

ÀÌÁ¦ºÎÅÍ ºÎÆÃÀÌ µÇ´Â ¼ø¼­´ë·Î ½ÇÁ¦ Äڵ带 ºÐ¼®ÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.

(1) Exception Vector Table

__program_start
       b ResetHandler
       b HandlerUndef ;handler for Undefined mode
       b HandlerSWI ;handler for SWI interrupt
       b HandlerPabort ;handler for PAbort
       b HandlerDabort ;handler for DAbort
       b . ;reserved
       b HandlerIRQ ;handler for IRQ interrupt
       b HandlerFIQ ;handler for FIQ interrupt

CPU¿¡ Àü¿øÀÌ Àΰ¡µÇ¸é óÀ½À¸·Î ½ÃÀ۵Ǵ Vector Table(0x0000 0000) ÀÔ´Ï´Ù.


(2) Watchdog Disable

Watchdog °¡ ¹«¾ùÀϱî¿ä? Á÷¿ªÀ» Çϸé "ÁöÅ°´Â°³" ÀÌ·± ¶æÀ̳׿ä. Watchdog´Â º¸Åë S/W ÀûÀ¸·Î ¼³Á¤ÇÑ ½Ã°£µ¿¾È Kick(ÁýÁöÅ°´Â °³¸¦ Çѹø¾¿ Â÷ÁÖ¾î¾ß ÀáÀ» ÀÚÁö ¾Ê°ÚÁÒ ... ^) À» ÇØÁÖÁö ¾ÊÀ¸¸é CPU¸¦ Reset ½ÃÅ°´Â ±â´ÉÀ¸·Î ÁÖ·Î »ç¿ëÇÕ´Ï´Ù. ¿Ö ÀÌ·± ±â´ÉÀÌ ÇÊ¿äÇÑ °É±î¿ä ? ¿ì¸®°¡ ÀÚÁÖ »ç¿ëÇÏ´Â ½º¸¶Æ®ÆùÀ» ¿¹·Î µé¾î º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ½º¸¶Æ®Æù »ç¿ëÁß¿¡ ¾î¶² AppÀ» ½ÇÇà½ÃÄ״µ¥ ±× ÀÌÈÄ·Î ½º¸¶Æ®ÆùÀÌ ±× App¶§¹®¿¡ ÅÍÄ¡µµ µÇÁö¾Ê°í, Àü¿ø ¹öÆ°µµ ÀÔ·ÂÀÌ µÇÁö ¾Ê°Ô ¸ÔÅëÀÌ µÇ¾ú´Ù°í °¡Á¤À» ÇÏ¸é º£Å͸®¸¦ ºÐ¸®½ÃŲ ÈÄ ´Ù½Ã ¿¬°áÇÏ´Â ¹æ¹ýÀÌ¿Ü¿¡´Â ¹æ¹ýÀÌ ¾ø½À´Ï´Ù. À̶§ ¸¸¾à Watchdog°¡ È°¼ºÈ­ µÇ¾î ÀÖ´Ù¸é ½º¸¶Æ®ÆùÀÌ ¸ÔÅëÀÌ µÇ´Â ¼ø°£ S/W ÀûÀ¸·Î ¼³Á¤ÇÑ ½Ã°£µ¿¾È KickÀÌ ¾øÀ¸¸é ½º¸¶Æ®ÆùÀÌ Reset(Àç ºÎÆÃ)ÀÌ µÇ¾î ´Ù½Ã »ç¿ëÇÒ ¼ö ÀÖ´Â »óÅ°¡ µÉ°ÍÀÔ´Ï´Ù. º£Å͸®¸¦ ºÐ¸®Çϴ°żҴٴ ³´°ÚÁÒ..
±×¸®°í ºÎÆ®Äڵ忡¼­ Watchdog Disable Çϴ°ÍÀº ºÎÆÃÀÌ ¿Ï·áµÇ±âµµ Àü¿¡ Watchdog¿¡ ÀÇÇؼ­ CPU°¡ ResetÀÌ µÇ´Â°ÍÀ» ¹æÁöÇϱâ À§Çؼ­ ÇÏ´Â°Í ÀÔ´Ï´Ù.




0x5300 0000 ¹øÁöÀÇ SFR ·¹Áö½ºÅ͸¦ Á¦¾îÇϸé WTCONÀ» ¼³Á¤ÇÒ ¼ö ÀÖ½À´Ï´Ù. ½ÇÁ¦·Î´Â 5¹ø ºñÆ®¸¸ "0 = Disable" Çصµ µË´Ï´Ù.

ResetHandler
       ldr r0,=WTCON ;watch dog disable
       ldr r1,=0x0
       str r1,[r0]


(3) Interrupt Disable

ºÎÆÃÁß¿¡ ¿¹ÃøÇÏÁö ¸øÇÏ´Â ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏÁö ¾Êµµ·Ï Disable Çϴ°ÍÀÌ ¾ÈÀü ÇÕ´Ï´Ù.

- Core Level Disable: CPSR ·¹Áö½ºÅÍÀÇ I, F Çʵ带 "1" ·Î MaskÇÕ´Ï´Ù.
  CPSR.I (1), CPSR.F(1) : ºÎÆýÿ¡ "1" ·Î ¸¶½ºÅ·µÇ¾î ÀÖ½À´Ï´Ù.

- S3C2440 CPU Level ÀÇ Interrupt Controller ¸¦ Disable ÇÕ´Ï´Ù.
  Interrupt Mask Register
  Interrupt SubMask Register

¾Æ·¡ ±×¸²Àº S3C2440 CPUÀÇ ÀÎÅÍ·´Æ® ÄÁÆ®·Ñ·¯ ºí·°µµ ÀÔ´Ï´Ù. " S3C2440 CPU Level ÀÇ Interrupt Controller ¸¦ Disable" ÇÑ´Ù´Â °ÍÀº ¾Æ·¡ ºí·°µµ¿¡¼­ ¹Ù·Î "SUBMASK", "MASK" ¸¦ Disable("1" ·Î Mask) ÇÑ´Ù´Â °ÍÀÔ´Ï´Ù.





       ldr r0,=INTMSK
       ldr r1,=0xffffffff ;all interrupt disable

       str r1,[r0] ldr r0,=INTSUBMSK
       ldr r1,=0x3ff ;all sub interrupt disable
       str r1,[r0]


(4) PLL ¼³Á¤

¿ì¸®°¡ »ç¿ëÇÏ´Â S3C2440 Mini °³¹ßº¸µå´Â ¿ÜºÎ Crystal·Î 12MHz¸¦ »ç¿ë ÇÕ´Ï´Ù.
Input Frequency °¡ 12MHz À϶§, FCLK:HCLK:PCLK = 400MHz : 100MHz : 40MHz, Áï 1:4:8 ºñÀ²·Î ºÐÁÖ°¡ µÇµµ·Ï ¼³Á¤ ÇÕ´Ï´Ù.

 

(4.1) Clock Divider Control Register(CLKDIVIN) ¼³Á¤



CLKDIV_VAL°ªÀÌ "b0101" À¸·Î ¼¼ÆÃÀÌ µÇ¾î À־ FCLK:HCLK:PCLK = 1:4:8 ºñÀ²·Î ºÐÁÖ°¡ µÇµµ·Ï ¼³Á¤ÀÌ µË´Ï´Ù.
ÃÖÁ¾ÀûÀ¸·Î´Â 12MHzÀÇ ÀÔ·ÂÁÖÆļö¸¦ ¹Þ¾Æ¼­ µ¿ÀÛ ÁÖÆļö°¡ 400MHz°¡ µÇµµ·Ï ¼³Á¤ ÇÕ´Ï´Ù.

(4.2) UPLL Control Register(USB CLK) ¼³Á¤



Upll = (m * Fin) / (p * 2s)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV

Fin = FCLKÀÔ·ÂÀ¸·Î µé¾î¿À´Â Crystal ÁÖÆļö 12MHz
UPLL = ((56+8)*12) / ((2+2)*2*2) = 48MHz



UPLLÀº USBÄÁÆ®·Ñ·¯¿¡¼­ »ç¿ëÇÒ CLK À¸·Î °á±¹Àº 12MHz Crystal ÀÔ·ÂÀ» ¹Þ¾Æ¼­ 48MHz¸¦ ¸¸µé¾î¼­ »ç¿ëÇÏ°í ÀÖ½À´Ï´Ù.

(4.3) MPLL Control Register(Main CLK) ¼³Á¤

Mpll = (2 * m * Fin) / (p * 2s)
m = (MDIV + 8), p = (PDIV + 2), s = SDIV
MPLL = (2*(92+8)*12) / ((1+2)*2*1) = 400MHz

MPLLÀº °á±¹Àº 12MHz Crystal ÀÔ·ÂÀ» ¹Þ¾Æ¼­ FCLK = 400MHz, HCLK = 100MHz, PCLK = 50MHz ¸¦ ¸¸µé¾î¼­ »ç¿ëÇÏ°í ÀÖ½À´Ï´Ù. HCLK°ú PCLKÀÇ °è»êÀº
CLKDIV ·¹Áö½ºÅÍ ¼³Á¤À» FCLK:HCLK:PCLK = 1:4:8 ºñÀ²·Î ºÐÁÖºñ¸¦ ¼³Á¤ Ç߱⠶§¹®¿¡ ÀÚµ¿À¸·Î °è»êÀÌ µË´Ï´Ù.

- ÂüÁ¶·Î PLL °è»ê ¹æ½ÄÀº S3C2440 Datasheet ¸¦ ÂüÁ¶ÇϽñ⠹ٶø´Ï´Ù.


       ldr r0,=CLKDIVN ; 0x4C000014
       ldr r1,=CLKDIV_VAL ; CLKDIV_VAL=5 ---> 1:4:8
       str r1,[r0]

       ;Configure UPLL
       ldr r0,=UPLLCON ; 0x4C000008
       ldr r1,=((U_MDIV<<12)+(U_PDIV<<4)+U_SDIV) ; U_MDIV=56, U_PDIV=2, U_SDIV=2
       str r1,[r0]

       ;Configure MPLL
       ldr r0,=MPLLCON
       ldr r1,=((M_MDIV<<12)+(M_PDIV<<4)+M_SDIV)
       str r1,[r0]



(5) Internal Bus Mode


      bl MMU_SetAsyncBusMode


- Synchronous : Core Clock System Clock(HCLK) ¿¡ µ¿±âÈ­ µÇ¾î »ç¿ë
- Asynchronous : System Clock(HCLK)°ú °ü°è¾øÀÌ Free Running Clock(FCLK) À» ÀÌ¿ë

¿ì¸®´Â FCLKÀ» ÀÌ¿ëÇÒ °ÍÀ̱⠶§¹®¿¡ MMU_SetAsyncBusMode ÇÔ¼ö¸¦ È£Ãâ ÇÏ¿´½À´Ï´Ù.

(6) Memory System ÃʱâÈ­

½Ã½ºÅÛ¿¡ ¿¬°áµÇ FLASH, SDRAM, I/O Device µî°ú °°Àº ÀåÄ¡µéÀ» Á¦¾îÇϱâ À§Çؼ­ Memory Controller¸¦ ÃʱâÈ­ ÇØ¾ß ÇÕ´Ï´Ù.

– Access Timing
– Data Bus Width
– Wait Cycle
– Refresh Rate
– Bank Memory Size

¼Ò½º ÄÚµåµéÀÌ ²Ï ¾Ë¾Æ¸Ô±â Èûµç ÄÚµåµéÀ̳׿ä. º¹ÀâÇØ º¸ÀÌÁö¸¸ ÇÏ´Â ÀÏÀº BWSCONÁÖ¼ÒÀÇ SFR ¿¡ SMRDATA ÀÇ 4Byte(32-bit) µ¥ÀÌÅ͵éÀ» ·çÇÁ¸¦ µ¹¸é¼­ Write ÇÏ´Â °ÍÀÔ´Ï´Ù.
- SMRDATA : ¸Þ¸ð¸® ÄÁÆ®·Ñ·¯ SFR¿¡ ±â·ÏÇÒ ³»¿ëµéÀ» 4Byte ±æÀÌ·Î Çؼ­ Å×À̺í ÇüÅ·Πµ¥ÀÌÅ͸¦ ¼øÂ÷ÀûÀ¸·Î °¡Áö°í ÀÖ½À´Ï´Ù.
- BWSCON : S3C2440 ¸Þ¸ð¸® ÄÁÆ®·Ñ·¯ÀÇ SFR ÁÖ¼Ò ÀÔ´Ï´Ù.

¼Ò½º ÆÄÀÏÀÇ memcfg.inc ¿¡ ´ÙÀ½°ú °°ÀÌ Á¤ÀÇ µÇ¾î ÀÖ½À´Ï´Ù.
;BWSCON
DW8 EQU (0x0)
DW16 EQU (0x1)
DW32 EQU (0x2)
WAIT EQU (0x1<<2)
UBLB EQU (0x1<<3)

B1_BWSCON EQU (DW32)
B2_BWSCON EQU (DW16)
B3_BWSCON EQU (DW16+WAIT+UBLB)
B4_BWSCON EQU (DW16) ; N.C.
B5_BWSCON EQU (DW16) ; N.C.
B6_BWSCON EQU (DW32) ; MINI2440 SDRAM(K4S281632C)-2M*16bit*4Bank*2, SDRAM(K4S561632C) 32MBx2, 32-bit
B7_BWSCON EQU (DW32) ; N.C.

SMRDATAÀÇ ¸Çù¹ø° µ¥ÀÌÅ͵éÀÌ ¹«¾ùÀ» ÀǹÌÇϴ°ÍÀϱî¿ä ?
      (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
--> (0+(0x2<<4)+(0x1<<8)+(0xD<<12)+(0x1<<16)+(0x1<<20)+(0x2<<24)+(0x2<<28))

»óÀ§ ºñÆ®ºÎÅÍ »ìÆ캸µµ·Ï ÇÏ°Ú½À´Ï´Ù.

- (0x2<<28) = DW7[29:28] = Bank7¿¡´Â ¾î¶² Memory µð¹ÙÀ̽ºµµ ¿¬°áµÇ¾î ÀÖÁö ¾Ê½À´Ï´Ù. »ç½ÇÀº ¹«ÀǹÌÇÑ ÄÚµå ÀÔ´Ï´Ù.



- (0x2<<24) = DW6[25:24] = Bank6Àº SDRAMÀÌ ¿¬°áµÇ¾î ÀÖ´Â ¸Þ¸ð¸® ¹ðÅ© ÀÔ´Ï´Ù. µ¥ÀÌÅÍ ¶óÀÎÀº 32bit(2b10) ÀÔ´Ï´Ù.



- (0x1<<20) = DW5[21:20] = N.C(Not connected)



- (0x1<<16) = DW4[17:16] = N.C(Not connected)



- (0xD<<12) = ST3[15], WS3[14], DW3[13:12] = 16-bit DM9000 Ehternet ÄÁÆ®·Ñ·¯ ¼³Á¤ ÀÔ´Ï´Ù.



- (0x1<<8) = DW2[9:8] = N.C(Not connected)



- (0x2<<4) = DW1[5:4] = N.C(Not connected)



- DW0[2:1] = Read only ¿µ¿ªÀ¸·Î OM[1:0] ÇÉ¿¡ ÀÇÇؼ­ °áÁ¤ µË´Ï´Ù . ¿ì¸®°¡ »ç¿ëÇÏ´Â °³¹ßº¸µå´Â 16bit Data widthÀÇ NOR Flash ÀÔ´Ï´Ù.



³ª¸ÓÁö µ¥ÀÌÅÍ ¼³Á¤°ªµéµµ Datasheet¸¦ ÂüÁ¶Çؼ­ ºÐ¼®ÇØ º¸½Ã±â ¹Ù¶ø´Ï´Ù.


       ;Set memory control registers
       ldr r0,=SMRDATA
       ldr r1,=BWSCON ; 0x48000000
       add r2, r0, #52 ;End address of SMRDATA
L5
       ldr r3, [r0], #4
       str r3, [r1], #4
       cmp r2, r0
       bne L5
      
       .
       .
       .


       LTORG
       SMRDATA DATA
       DCD (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
       DCD ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
       DCD ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
       DCD ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
       DCD ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC)) ;GCS3
       DCD ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC)) ;GCS4
       DCD ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC)) ;GCS5
       DCD ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN)) ;GCS6
       DCD ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN)) ;GCS7
       DCD ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
       DCD 0x32 ;SCLK power saving mode, BANKSIZE 128M/128M DCD 0x30 ;MRSR6 CL=3clk
       DCD 0x30 ;MRSR7 CL=3clk
       DATA


(7) Stack Pointer ÃʱâÈ­

°¢ ÇÁ·Î¼¼¼­ ¸ðµåº°(7°³ µ¿ÀÛ¸ðµå)·Î Processor Mode¸¦ ÀüȯÇϸ鼭 StackÀ» ÃʱâÈ­ ÇØ¾ß ÇÕ´Ï´Ù. ÀÌÀü °­ÁÂÀÎ ARM ArchitectureÀÇ ARM Register ºÎºÐÀ» ´Ù½Ã º¸½Ã¸é R13(SP) ´Â °¢ µ¿ÀÛ ¸ðµåº°·Î ¹ðÅ©µÇ µÇ¾î ÀÖ´Â ·¹Áö½ºÅÍÀÓÀ» È®ÀÎ ÇÒ ¼ö ÀÖ½À´Ï´Ù. ¿©±â¼­ ÁÖÀÇÇØ¾ß ÇÒ Á¡Àº User Mode StackÀº Á¦ÀÏ ¸¶Áö¸·¿¡ ÃʱâÈ­ ÇØ¾ß ÇÕ´Ï´Ù. ¿Ö ±Û·²±î¿ä ? User Mode ´Â ºñ Ư±Ç ¸ðµåÀ̹ǷΠÇѹø User Mode·Î ÁøÀÔÀ» Çϸé SWI ¸í·ÉµîÀ» »ç¿ëÇÏÁö ¾ÊÀ¸¸é ´Ù½Ã Ư±Ç ¸ðµå·Î ÁøÀÔÀ» ÇÒ ¼ö ¾ø¾î¼­ ´Ù¸¥ Processor ModeÀÇ Stack Pointer¸¦ ÃʱâÈ­ ÇÒ ¼ö°¡ ¾ø½À´Ï´Ù. ÀÌ·± ÀÌÀ¯·Î Çؼ­ User Mode ÀÇ Stack Pointer¸¦ Á¦ÀÏ ¸¶Áö¸·¿¡ ÃʱâÈ­ Çϵµ·Ï ÇØ¾ß ÇÕ´Ï´Ù.


      ;function initializing stacks
InitStacks
      ;Don't use DRAM,such as stmfd,ldmfd......
      ;SVCstack is initialized before
      ;Under toolkit ver 2.5, 'msr cpsr,r1' can be used instead of 'msr cpsr_cxsf,r1'
      mrs r0,cpsr
      bic r0,r0,#MODEMASK
      orr r1,r0,#UNDEFMODE|NOINT
      msr cpsr_cxsf,r1     ;UndefMode
      ldr sp,=UndefStack

      orr r1,r0,#ABORTMODE|NOINT
      msr cpsr_cxsf,r1     ;AbortMode
      ldr sp,=AbortStack

      orr r1,r0,#IRQMODE|NOINT
      msr cpsr_cxsf,r1     ;IRQMode
      ldr sp,=IRQStack

      orr r1,r0,#FIQMODE|NOINT
      msr cpsr_cxsf,r1     ;FIQMode
      ldr sp,=FIQStack ;// ¾Æ·¡(System Mode Stack) ºÎºÐ Ãß°¡ ÇÔ.

      bic r0,r0,#MODEMASK|NOINT
      orr r1,r0,#SYSMODE
      msr cpsr_cxsf,r1 ;SYSMode
      ldr sp,=SYSStack

      bic r0,r0,#MODEMASK|NOINT
      orr r1,r0,#SVCMODE
      msr cpsr_cxsf,r1 ;SVCMode
      ldr sp,=SVCStack

      ;USER mode has not be initialized. We use always SVC mode.

      mov pc,lr ;The LR register won't be valid if the current mode is not SVC mode.


(8) Segment Initialization

ROM Binary°¡ ¸¸µé¾î Áö°í ³ª¼­ ÇÁ·Î±×·¥ÀÌ ½ÇÇàµÇ±â À§Çؼ­´Â ¹Ýµå½Ã RAM ÀÌ ÀÖ¾î¾ß ÇÕ´Ï´Ù. Segment Initialization Àº RAM¿¡¼­ ÇÁ·Î±×·¥ÀÌ ¿Ã¹Ù¸¥ µ¥ÀÌÅ͸¦ °¡Áö°í ½ÇÇà µÉ¼ö ÀÖµµ·Ï RAM ¿µ¿ª¿¡ Àü¿ªº¯¼öÀÇ ÃʱⰪµéÀ» ÀúÀåÇÏ´Â ÀÏÀ» ÇÕ´Ï´Ù. Á»´õ ÀÚ¼¼ÇÑ »çÇ×Àº ÀÌÀü °­ÁÂÀÎ ARM Architecture 4.4 Linker ºÎºÐÀ» ÂüÁ¶ÇϽñ⠹ٶø´Ï´Ù.




À§ÀÇ ±×¸²¿¡¼­ ¿ÞÂÊÀÌ ROM Binary ÀÌ°í ¿À¸¥ÂÊÀÌ RAM ¿µ¿ª ÀÔ´Ï´Ù.

- .data : C¾ð¾î µî¿¡¼­ ¼±¾ðÇÑ Àü¿ªº¯¼öµéÀÇ ÃʱⰪÀÌ ÀúÀåµÇ¾î ÀÖ´Â ¿µ¿ª ÀÔ´Ï´Ù.
- .bss : 0 À¸·Î ÃʱâÈ­ µÇ´Â ¿µ¿ª ÀÔ´Ï´Ù. ÃʱⰪÀ» ÁöÁ¤ÇÏÁö ¾ÊÀº Àü¿ªº¯¼öµîÀÌ ¿©±â¿¡ ÇØ´ç ÇÕ´Ï´Ù.
- .textrw : ÄÄÆÄÀÏ·¯¿¡ÀÇÇØ »ý¼ºµÈ RAM¿¡¼­ ½ÇÇàµÇ´Â ÇÔ¼öµé ÀÔ´Ï´Ù.

#pragma segment = ".bss"
#pragma segment = ".data"
#pragma segment = ".data_init"
#pragma segment = ".rodata"
#pragma segment = ".textrw"
#pragma segment = ".textrw_init"
#pragma segment = "CSTACK"

void InitSegment()
{
     unsigned int k, n;
     unsigned char *pdst, *psrc;

     //
     // initialize zero-initialized segment
     //
     n = (unsigned int)__section_end(".bss") - (unsigned int)__section_begin(".bss");
     pdst = (unsigned char *)__section_begin(".bss");

     for(k=0; k<n; k++)
     {
          *(pdst + k) = 0;
     }

     //
     // initialize non-zero-initialized segment
     //
     n = (unsigned int)__section_end(".data_init") - (unsigned int)__section_begin(".data_init");
     pdst = (unsigned char *)__section_begin(".data");
     psrc = (unsigned char *)__section_begin(".data_init");

     for(k=0; k<n; k++)
     {
          *(pdst + k) = *(psrc + k);
     }

     //
     // initialize segment for ram-function
     //
     n = (unsigned int)__section_end(".textrw_init") - (unsignedint)__section_begin(".textrw_init");
     pdst = (unsigned char *)__section_begin(".textrw");
     psrc = (unsigned char *)__section_begin(".textrw_init");

     for(k=0; k<n; k++)
     {
          *(pdst + k) = *(psrc + k);
     }

     return;
}


(9) main ÇÔ¼ö·Î À̵¿

EXTERN main
ldr pc, =main

µåµð¾î ¸ðµç StackÃʱâÈ­¿Í Segment ÃʱâÈ­ °úÁ¤À» ³¡³»°í C ÇÔ¼ö¸¦ È£ÃâÇÒ ¼ö ÀÖ°Ô µÇ¾ú½À´Ï´Ù. ÀÌÁ¦ ºÎÅÍ´Â C Äڵ带 ÀÌ¿ëÇؼ­ °¢ µð¹ÙÀ̽ºµéÀ» Å×½ºÆ® ÇÒ¼ö ÀÖ°Ô µÇ¾ú³×¿ä.

5.2 GPIO Output( LED On/Off )

LED¸¦ ÄÁÆ®·Ñ Çϱâ À§Çؼ­´Â Æ÷Æ®¸¦ OutputÀ¸·Î ¼³Á¤ÇÑ ÈÄ¿¡ GPIO(General Purpose Input Output) Æ÷Æ®¿¡ Low or High ¸¦ Ãâ·ÂÇÏ¸é µË´Ï´Ù. ¾Æ·¡ ȸ·Îµµ´Â ¿ì¸®°¡ ½Ç½À¿¡ »ç¿ëÇÏ°í ÀÖ´Â Mini2440ÀÇ LED ȸ·Îµµ ÀÔ´Ï´Ù. 4°³ÀÇ LED°¡ Àִµ¥ °¢ LED´Â GPB5 ~ 8 ¿¡ ¿¬°áÀÌ µÇ¾î ÀÖ½À´Ï´Ù. ±×·¸´Ù¸é LED1À» Äѱâ À§Çؼ­ GPB5 Æ÷Æ®¿¡ Low(0) ·Î ÇØ¾ß ÇÒ±î¿ä ? ¾Æ´Ï¸é High(1) ·Î ÇØ¾ß ÇÒ±î¿ä ? Á¤´äÀº LEDÀÇ ÇÑÂÊ ³¡ÀÌ VDD33V ¿¡ ¿¬°áÀÌ µÇ¾î Àֱ⠶§¹®¿¡ Low·Î ¼³Á¤ ÇØ¾ß Àü·ùÀÇ È帧ÀÌ ¹ß»ýÇÏ¿© LED°¡ ÄÑÁö°Ô µË´Ï´Ù.

* ½ÇÇ迹Á¦
LED1, LED2 ´Â OnÀ» ÇÏ°í LED3, LED4´Â Off ½ÃÄÑ º¾´Ï´Ù.

(1) GPBCON ·¹Áö½ºÅÍ¿¡ GPB5 ~ GPB8 À» OutputÀ¸·Î ¼³Á¤ ÇÕ´Ï´Ù.




// GPB5 Output
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) & ~(0x3 << 10);
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) | (0x1 << 10);

// GPB6 Output
rGPBCON = rGPBCON & ~(0x3 << 12);
rGPBCON = rGPBCON | (0x1 << 12);

// GPB7 Output
rGPBCON = rGPBCON & ~(0x3 << 14);
rGPBCON = rGPBCON | (0x1 << 14);

// GPB8 Output
rGPBCON = rGPBCON & ~(0x3 << 16);
rGPBCON = rGPBCON | (0x1 << 16);

(3) GPBDAT ·¹Áö½ºÅÍÀÇ GPB5, GPB6 À» Low ·Î, GPB7, GPB8 À» High·Î ¼¼Æà ÇÕ´Ï´Ù.

// LED1 On
rGPBDAT = rGPBDAT & ~(0x1 << 5);
// LED2 On
rGPBDAT = rGPBDAT & ~(0x1 << 6);
//rGPBDAT = rGPBDAT | (0x1 << 6);


// LED3 Off
rGPBDAT = rGPBDAT | (0x1 << 7);
// LED4 Off
rGPBDAT = rGPBDAT | (0x1 << 8);


diag.c - led_test()


// GPB5 Output
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) & ~(0x3 << 10);
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) | (0x1 << 10);

// GPB6 Output
rGPBCON = rGPBCON & ~(0x3 << 12);
rGPBCON = rGPBCON | (0x1 << 12);

// GPB7 Output
rGPBCON = rGPBCON & ~(0x3 << 14);
rGPBCON = rGPBCON | (0x1 << 14);

// GPB8 Output
rGPBCON = rGPBCON & ~(0x3 << 16);
rGPBCON = rGPBCON | (0x1 << 16);

// LED1 On
rGPBDAT = rGPBDAT & ~(0x1 << 5);
// LED2 On
rGPBDAT = rGPBDAT & ~(0x1 << 6);

// LED3 Off
rGPBDAT = rGPBDAT | (0x1 << 7);
// LED4 Off
rGPBDAT = rGPBDAT | (0x1 << 8);



* ¼Ò½ºÄÚµå ºÐ¼®
(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) & ~(0x3 << 10);
GPBCON ·¹Áö½ºÅÍÀÇ ÁÖ¼Ò°¡ 0x50000010 ÀÔ´Ï´Ù. 0x3(b11) À» ¿ÞÂÊÀ¸·Î 10¹ø ½¬ÇÁÆ®¸¦ Çϸé b110000000000 ÀÌ°í ÀÌ°ÍÀ» "~" (Bit clear) ½ÃÅ°¸é GPB5[11:10] ºÎºÐÀÌ "00" À¸·Î Clear µË´Ï´Ù.

(*(volatile unsigned *)0x56000010) = (*(volatile unsigned *)0x56000010) | (0x1 << 10);
0x1(b01) À» ¿ÞÂÊÀ¸·Î 10¹ø ½¬ÇÁÆ®¸¦ Çϸé b010000000000 ÀÌ°í ÀÌ°ÍÀ» "|" (OR) ½ÃÅ°¸é GPB5[11:10] ºÎºÐÀÌ "01" À¸·Î OutputÀ¸·Î ¼³Á¤ µË´Ï´Ù.

¼Ò½º ÄÚµåÁß¿¡ volatile À̶ó´Â °ÍÀ» »ç¿ëÇÏ°í ÀÖ½À´Ï´Ù. ÀÌ°ÍÀº ÄÄÆÄÀÏ·¯ ÃÖÀûÈ­¿¡¼­ Á¦¿ÜµÇ´Â È¿°ú°¡ ÀÖ½À´Ï´Ù.

ÄÄÆÄÀÏ·¯ ÃÖÀûÈ­ Àü

ÄÄÆÄÀÏ·¯ ÃÖÀûÈ­ ÈÄ
int a = 0; // Àü¿ª º¯¼ö
int b = 0; // Àü¿ª º¯¼ö
int i; // ·ÎÄà º¯¼ö

for(i=0;i<100;i++)
     b = b + a * 100;
int a = 0; // Àü¿ª º¯¼ö
int b = 0; // Àü¿ª º¯¼ö
int i; // ·ÎÄà º¯¼ö

for(i=0;i<100;i++)
     b = b + 0; // a * 100;

À§ÀÇ Äڵ忡¼­ ¿À¸£ÂÊ ÄÚµåó·³ °³¹ßÀÚ°¡ ÀǵµÇÏÁö ¾Ê°Ô ÄÄÆÄÀÏ·¯¿¡ ÀÇÇØ ÃÖÀûÈ­°¡ µÇ¾î "a*100" ºÎºÐÀ» ÃÖÀûÈ­ ÇÏ¿© b º¯¼ö¿¡ Ç×»ó 0À¸·Î ÀúÀåÀÌ µÇµµ·Ï ÇÒ ¼öµµ ÀÖ½À´Ï´Ù. ¹°·Ð ÀϹÝÀûÀÎ »óȲ¿¡¼­´Â ¾Æ¹« ¹®Á¦°¡ µÇÁö ¾ÊÁö¸¸ for ·çÇÁ ¼öÇàÁß¿¡ ¿ÜºÎ ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏ¿© ÀÎÅÍ·´Æ® ¼­ºñ½º ·çƾ¿¡¼­ a ÀÇ °ªÀ» 0ÀÌ ¾Æ´Ñ ´Ù¸¥ °ªÀ¸·Î º¯ÇÏ°Ô ÇÑ ÈÄ ´Ù½Ã for ·çÇÁ¸¦ ¼öÇà ÇÏ¸é °³¹ßÀÚ´Â b¿¡ 0ÀÌ ¾Æ´Ñ ´Ù¸¥°ªÀÌ ÀúÀåµÇ±â¸¦ ±â´ëÇÏ°í ÀÖ°ÚÁö¸¸ ÃÖÀûÈ­µÈ Äڵ忡¼­´Â b ¿¡ Ç×»ó 0 ÀÌ ÀúÀåÀÌ µÇ¾î ÀÖÀ»°ÍÀÔ´Ï´Ù. ÀÌ°ÍÀº °³¹ßÀÚ°¡ ÀǵµÇÑ °á°ú°¡ ¾Æ´Õ´Ï´Ù. ÀÌ·± Çö»óÀ» ¹æÁöÇϱâ À§Çؼ­´Â º¯¼ö a ¸¦ volatile ·Î ¼±¾ðÀ» ÇÏ¸é µË´Ï´Ù. ƯÈ÷³ª SFR ·¹Áö½ºÅ͵ °ªÀ» ¼¼ÆÃÇÏ´Â ÀÛ¾÷À» ÇÑ´Ù¸é Ç×»ó volatile ·Î ¼±¾ðÀ» Çؼ­ »ç¿ëÇÏ´Â Çϴ°ÍÀÌ ÁÁ½À´Ï´Ù.

5.3 GPIO Input( KEY Input) - Polling

LED¸¦ Ä×À»¶§¿Í ¹Ý´ë·Î À̹ø¿¡´Â GPIOÆ÷Æ®¸¦ ÀÌ¿ëÇؼ­ ÀÔ·ÂÀ» ¹Þ¾Æ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. Æ÷Æ®¿¡¼­ ÀÔ·ÂÀ» ¹Þ±â À§Çؼ­´Â Æ÷Æ®¸¦ Input À¸·Î ¼³Á¤ÇÑ ÈÄ¿¡ GPIO(General Purpose Input Output) Æ÷Æ®¸¦ ÀÐÀ¸¸é µË´Ï´Ù. 6°³ÀÇ KEY°¡ Àִµ¥ ¿ì¸®´Â INT11, INT13 ¿¡ ¿¬°áµÇ¾î ÀÖ´Â K2, K3 ¿¡ ´ëÇؼ­ Æú¸µ¹æ½ÄÀ¸·Î ÀÔ·ÂÀ» °¨ÁöÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. Âü°í·Î Æú¸µ ¹æ½ÄÀ̶õ Äڵ忡¼­ ¹«ÇÑ ·çÇÁ¸¦ µ¹¸é¼­ ƯÁ¤ ÇàÀ§¸¦ Çϴ°ÍÀ» ¸»ÇÕ´Ï´Ù. À̹ø °æ¿ì¿¡´Â Key°¡ ´­·ÁÁ³´ÂÁö¸¦ °¨½ÃÇÏ´Â °ÍÀÌ°ÚÁö¿ä. Æú¸µ°ú ´Ù¸¥ ¹æ½ÄÀ¸·Î´Â ÀÎÅÍ·´Æ® ¹æ½ÄÀÌ ÀÖ½À´Ï´Ù. ´ÙÀ½Àý¿¡¼­ °øºÎÇÏ°ÔµÉ ³»¿ëÀÔ´Ï´Ù.


* ½ÇÇ迹Á¦
K2, K3 ¸¦ Àо KEY°¡ ´­·ÁÁ® ÀÖÀ¸¸é LED2, LED3 ¸¦ OnÀ¸·Î ÇÏ°í ´­·ÁÁ® ÀÖÁö ¾ÊÀ¸¸é Off ·Î ¼³Á¤ÇØ º¾½Ã´Ù.

(1) GPGCON ·¹Áö½ºÅÍ¿¡ GPG3, GPG5 ¸¦ InputÀ¸·Î ¼³Á¤ ÇÕ´Ï´Ù.




// KEY3, GPG5 Input
rGPGCON = rGPGCON & ~(0x3 << 10);
// KEY2, GPG3 Input
rGPGCON = rGPGCON & ~(0x3 << 6);

(2) GPGDAT ·¹Áö½ºÅÍÀÇ GPG3, GPG5 ¸¦ Àо "0" À̸é KEY°¡ ´­¸° »óÅÂÀÌ°í, "1" À̸é KEY ´­·ÁÁöÁö ¾ÊÀº »óÅ ÀÔ´Ï´Ù.

diag.c - key_test()

// KEY3, GPG5 Input
rGPGCON = rGPGCON & ~(0x3 << 10);

// KEY2, GPG3 Input
rGPGCON = rGPGCON & ~(0x3 << 6);


while(1)
{
     if( (rGPGDAT & (0x1 << 3)) == 0 ) // KEY2 pressed
          // LED2 On
          rGPBDAT = rGPBDAT & ~(0x1 << 6);
     else
          // LED2 Off
          rGPBDAT = rGPBDAT | (0x1 << 6);

     if( (rGPGDAT & (0x1 << 5)) == 0 ) // KEY3 pressed
          // LED3 On
          rGPBDAT = rGPBDAT & ~(0x1 << 7);
     else
          // LED3 Off
          rGPBDAT = rGPBDAT | (0x1 << 7);

     Delay(80);
};

 


5.4 GPIO Input( KEY Input) - Interrupt

À̹ø¿¡´Â ÀÎÅÍ·´Æ® ¹æ½ÄÀ¸·Î K2, K3 ÀÔ·ÂÀ» °¨ÁöÇØ º¸µµ·Ï ÇÏ°Ú½À´Ï´Ù. ÀÎÅÍ·´Æ® ¹æ½ÄÀº Æú¸µ¹æ½Äº¸´Ù È¿À²ÀûÀ̱â´Â ÇÏÁö¸¸ Á»´õ º¹ÀâÇÕ´Ï´Ù. ¿©±â¼­ È¿À²ÀûÀ̶ó°í Çϴ°ÍÀº CPU»ç¿ëÀ» È¿°úÀûÀ¸·Î ÇѴٴ°ÍÀÌÁö Æú¸µ¹æ½Äº¸´Ù ºü¸£´Ù´Â ¸»Àº ¾Æ´Õ´Ï´Ù. ÀÎÅÍ·´Æ®¹æ½ÄÀº ÀÎÅÍ·´Æ®¿äûÀÌ ¿ÔÀ»¶§ ÀÎÅÍ·´Æ® ¼­ºñ½º ·çƾÀ¸·Î ºÐ±âÇÒ¶§±îÁö Áö¿¬½Ã°£ÀÌ ÀÖ¾î Æú¸µ ¹æ½Äº¸´Ù ´À¸±¼ö ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ Æú¸µ¹æ½Äó·³ °è¼Ó ·çÇÁ¸¦ µ¹¸é¼­ ´ë±âÇÏÁö ¾Ê¾Æµµ µÇ±â ¶§¹®¿¡ CPUÈ°¿ë¸é¿¡¼­´Â È¿À²ÀûÀÔ´Ï´Ù.

* ½ÇÇ迹Á¦
K2, K3 ¸¦ Àо KEY°¡ ´­·ÁÁ® ÀÖÀ¸¸é LED2, LED3 ¸¦ OnÀ¸·Î ÇÏ°í ´­·ÁÁ® ÀÖÁö ¾ÊÀ¸¸é Off ·Î ¼³Á¤ÇØ º¾½Ã´Ù.

(1) GPGCON ·¹Áö½ºÅÍ¿¡ GPG3, GPG5 ¸¦ EINT(0x2) À¸·Î ¼³Á¤ ÇÕ´Ï´Ù.



// KEY3, GPG5 EINT13
rGPGCON = rGPGCON & ~(0x3 << 10);
rGPGCON = rGPGCON | (0x2 << 10);

// KEY2, GPG3 EINT11
rGPGCON = rGPGCON & ~(0x3 << 6);
rGPGCON = rGPGCON | (0x2 << 6);

(2) EXTINT1 ·¹Áö½ºÅÍ¿¡ EINT11, EINT13À» Falling Edge·Î ¼³Á¤ ÇÕ´Ï´Ù.




// set eint13 falling edge trigger
rEXTINT1 &= ~(0x7 << 20);
rEXTINT1 |= (0x2 << 20);

// set eint11 falling edge trigger
rEXTINT1 &= ~(0x7 << 12);
rEXTINT1 |= (0x2 << 12);

(3) EINTPEND ·¹Áö½ºÅÍÀÇ Pending bit ¸¦ Clear ÇÕ´Ï´Ù.





// clear eint 11,13
rEINTPEND |= (1 << 11)|(1 << 13);

"It is cleard by writing 1" À̶ó´Â ¹®±¸°¡ º¸À̴µ¥¿ä. ¹«½¼ ÀÇ¹Ì Àϱî¿ä ? ÀϹÝÀûÀ¸·Î ¿ì¸®°¡ SFR ·¹Æ¼½ºÅ͸¦ ¼³Á¤ ÇÒ¶§¿¡ ¾Æ·¡¿Í °°ÀÌ ¸ÕÀú Bit¸¦ Clear ½ÃÅ°°í Set ÇÏ´Â 2´Ü°è °úÁ¤À» °ÅÄ¡°Ô µË´Ï´Ù.

rEXTINT1 &= ~(0x7 << 20);
rEXTINT1 |= (0x2 << 20);

ÇÏÁö¸¸ ÀÎÅÍ·´Æ® ¼­ºñ½º ·çƾ ¾È¿¡¼­´Â ÀÌ°Í Á¶Â÷µµ ºñÈ¿À²ÀûÀϼö ÀÖ°í Atmoic Operation ÀÌ ¾Æ´Ï±â ¶§¹®¿¡ Pending Clear¸¦ ÇÏ´Â °úÁ¤¿¡¼­ »õ·Î¿î ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÒ °æ¿ì¿¡ »õ·Î¿î ÀÎÅÍ·´Æ®°¡ Áö¿¬µÉ¼öµµ ÀÖ½À´Ï´Ù.

rEINTPEND |= (1 << 11)|(1 << 13);

ÀÌ·¯ÇÑ ÀÌÀ¯·Î À§¿Í °°ÀÌ "1" À» ½á³Ö¾î¼­ ¹Ù·Î PendingÀ» Clear ÇÒ¼ö ÀÖµµ·ÏÇÑ °ÍÀÔ´Ï´Ù.

(4) EINTMASK ·¹Áö½ºÅÍ¿¡¼­ Interrupt¸¦ Enable ÇÕ´Ï´Ù.



// enable eint 11,13
rEINTMASK &= ~((1 << 11)|(1 << 13));

(5) SRCPND ·¹Áö½ºÅÍÀÇ Pending bit ¸¦ Clear ÇÕ´Ï´Ù.



rSRCPND = (0x1<<5); // Clear pending bit

(6) INTPND ·¹Áö½ºÅÍÀÇ Pending bit ¸¦ Clear ÇÕ´Ï´Ù.




rINTPND = (0x1<<5); // Clear pending bit

(7) EINT ÀÎÅÍ·´Æ® ¼­ºñ½º ·çƾÀÇ ÇÔ¼ö Æ÷ÀÎÅ͸¦ ¼³Á¤ ÇÕ´Ï´Ù.

pISR_EINT8_23 = (U32)isr_eint_8_23;

(8) INTMSK ¿¡¼­ EINT8_23 ÀÇ ÀÎÅÍ·´Æ®¸¦ Enable ÇÕ´Ï´Ù.




rINTMSK &= ~((0x1<<5));

(9) Startup ÄÚµåÀÇ IRQ Exception ¿¡¼­ ÀÎÅÍ·´Æ® ¹øÈ£¸¦ È®ÀÎÇÏ°í ÀÎÅÍ·´Æ® ¼­ºñ½º ·çƾÀ¸·Î ºÐ±â ÇÕ´Ï´Ù.
Startup ÄÚµå ¼³¸íÇÒ¶§ À̺κÐÀº ¼³¸íÀ» ÇÏÁö ¾Ê°í ±×³É ³Ñ¾î°¬½À´Ï´Ù. ¾î¶² ¸¶¹ýÀÇ ÄÚµå·Î ÀÎÇؼ­ ¼ö¸¹Àº ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼ö°¡ 1°³ÀÇ ·çƾÀ¸·Î ÇØ°áÀÌ µÉ±î¿ä ? À̹ø¿¡ »ó¼¼ÇÏ°Ô ¼³¸í Çϵµ·Ï ÇÏ°Ú½À´Ï´Ù.


IsrIRQ
     sub sp,sp,#4 ;reserved for PC --> 1
     stmfd sp!,{r8-r9} ; --> 2

     ldr r9,=INTOFFSET ; --> 3
     ldr r9,[r9] ; --> 4
     ldr r8,=HandleEINT0 ; --> 5
     add r8,r8,r9,lsl #2 ; --> 6
     ldr r8,[r8] ; --> 7
     str r8,[sp,#8] ; --> 8
     ldmfd sp!,{r8-r9,pc} ; --> 9




--> 1 : ½ºÅÃÆ÷ÀÎÅ͸¦ 1 °¨¼ÒÇÏ¿© ºó °ø°£À» ¸¸µì´Ï´Ù. ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼öÀÇ ÁÖ¼Ò°ªÀÌ ÀúÀåµÉ °ø°£ ÀÔ´Ï´Ù.
--> 2 : r8, r9 ¸¦ »ç¿ëÇÏ°í º¹¿øÇØ¾ß ÇϹǷΠstack¿¡ ÀúÀå ÇÕ´Ï´Ù. stmfd´Â ¸ÕÀú ¾îµå·¹½º¸¦ °¨¼ÒÇÏ°í ÀúÀåÇϹǷΠ1 ¿¡¼­ ¸¸µé¾îÁø ºó°£°øÀº ±×´ë·Î ³²¾Æ ÀÖ½À´Ï´Ù.
--> 3, 4 : INTOFFSET À» r9 ·¹ ·Îµå ÇÕ´Ï´Ù.
--> 5 : HandleEINT0 ¸¦ r8 ¿¡ ·Îµå ÇÕ´Ï´Ù. HandleEINT0´Â Startup ÄÚµåÀÇ ¾Æ·¡ ºÎºÐ¿¡ Á¤ÀǵǾî ÀÖ½À´Ï´Ù.
--> 6,7 : HandleEINT0 + INTOFFSET*4 ÀÇ ¼ö½ÄÀÌ µË´Ï´Ù. INTOFFSET ·¹Áö½ºÅÍ¿¡´Â ¹ß»ýÇÑ ÀÎÅÍ·´Æ® ¼Ò½ºÀÇ Offset °ªÀÌ µé¾îÀÖ´Â ·¹Áö½ºÅÍ ÀÔ´Ï´Ù.
¿ì¸®´Â EINT8_23 À» ÀÌ¿ëÇÒ °ÍÀ̱⠶§¹®¿¡ INTOFFSET ·¹Áö½ºÅÍ¿¡´Â 5°¡ ÀúÀåµÇ¾î ÀÖÀ»°ÍÀÔ´Ï´Ù. ±×·¯¹Ç·Î HandleEINT0 + 5*4 Áï HandleEINT8_23ÀÇ ÁÖ¼Ò°¡ µË´Ï´Ù.
¼Ò½ºÄڵ忡¼­ key_test_eint() ÇÔ¼ö¿¡¼­ pISR_EINT8_23 = (U32)isr_eint_8_23; ÀÇ Äڵ带 »ðÀÔÇϸé EINT8_23 ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇϸé isr_eint_8_23 ÇÔ¼ö·Î ºÐ±â¸¦ ÇÏ°Ô µË´Ï´Ù.



--> 8 : str r8,[sp,#8] ¿¡ ÀÇÇؼ­ ¸Ç óÀ½¿¡ StackÀÇ ºó°£°øÀ» ¸¸µé¾î µÎ¾ú´ø °÷À¸·Î ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼öÀÇ Æ÷ÀÎÅÍÁÖ¼Ò°ªÀ» ÀúÀå ÇÕ´Ï´Ù.
--> 9 : r8, r9 ¸¦ Stack ¿¡¼­ º¹¿øÇÏ°í pc ¿¡ ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼öÀÇ ÁÖ¼Ò°¡ ÀúÀåÀÌ µÇ¾î ½ÇÁ¦·Î ÀÎÅÍ·´Æ® Çڵ鷯 ÇÔ¼ö°¡ ½ÇÇàÀÌ µË´Ï´Ù.

(10) ÀÎÅÍ·´Æ® ¼­ºñ½º ·çƾ¿¡¼­ GPGDAT ·¹Áö½ºÅÍÀÇ GPG3, GPG5 ¸¦ Àо "0" À̸é KEY°¡ ´­¸° »óÅÂÀÌ°í, "1" À̸é KEY ´­·ÁÁöÁö ¾ÊÀº »óÅ ÀÔ´Ï´Ù.

Áö±Ý±îÁö ¼³¸íÇÑ ÀÎÅÍ·´Æ® °ü·Ã ¼³Á¤µéÀ» S3C2440 ÀÎÅÍ·´Æ® ÄÁÆ®·Ñ·¯ ºí·°µµ¿Í ºñ±³Çؼ­ º¸½Ã±â ¹Ù¶ø´Ï´Ù.



Interrupt MODEµµ IRQ/FIQ ¼³Á¤À» ÇØ¾ß ÇÏÁö¸¸ S3C2440ÀÇ ±âº» ÀÎÅÍ·´Æ® ¼³Á¤ °ªÀÌ IRQ À̱⠶§¹®¿¡ »ý·« ÇÏ¿´½À´Ï´Ù.
¿ÜºÎ ÀÎÅÍ·´Æ® 1°³¸¦ ¼­ºñ½º ¹Þ±â À§Çؼ­ Á¤¸» ¸¹Àº °úÁ¤ÀÌ ÇÊ¿ä Çϳ׿ä. ARM Applications ÀÌÈÄ¿¡ ÇÏ°ÔµÉ Cortex-M3 Architecture ºÎºÐ¿¡¼­µµ ÀÎÅÍ·´Æ® ¼­ºñ½º¿¡ ´ëÇؼ­ ¼³¸íÀ» ÇÒÅÙµ¥, ±×¶§ Cortex-M3 °¡ ¾ó¸¶³ª °£°áÇÏ°í È¿À²ÀûÀÎÁö ºñ±³ÇØ º¸½Ã±â ¹Ù¶ø´Ï´Ù.

diag.c - key_test_eint()


__irq __arm void isr_eint_8_23(void)
{
     if(rINTPND==BIT_EINT8_23)
     {
          ClearPending(BIT_EINT8_23);
          if(rEINTPEND&(1<<11))
          {
               rEINTPEND |= 1 << 11;
               rGPBDAT = rGPBDAT ^ (0x1 << 6); // toggle
           }

          if(rEINTPEND&(1<<13))
          {
                rEINTPEND |= 1 << 13;
               rGPBDAT = rGPBDAT ^ (0x1 << 7); // toggle
          }
     }
}

void key_test_eint(void)
{

// KEY3, GPG5 EINT13
rGPGCON = rGPGCON & ~(0x3 << 10);
rGPGCON = rGPGCON | (0x2 << 10);

// KEY2, GPG3 EINT11
rGPGCON = rGPGCON & ~(0x3 << 6);
rGPGCON = rGPGCON | (0x2 << 6);

// set eint13 falling edge trigger
rEXTINT1 &= ~(0x7 << 20);
rEXTINT1 |= (0x2 << 20);

// set eint11 falling edge trigger
rEXTINT1 &= ~(0x7 << 12);
rEXTINT1 |= (0x2 << 12);

// clear eint 11,13 --> clear by writing "1" test
rEINTPEND |= (1 << 11)|(1 << 13);

// enable eint 11,13
rEINTMASK &= ~((1 << 11)|(1 << 13));

rSRCPND = (0x1<<5); // Clear pending bit --> clear by writing "1" test
rINTPND = (0x1<<5); // Clear pending bit --> clear by writing "1" test

pISR_EINT8_23 = (U32)isr_eint_8_23;

// Enable EINT8_23 Interrupt
rINTMSK &= ~((0x1<<5));

}



5.5 Timer

ÀÓº£µðµå ½Ã½ºÅÛ¿¡¼­ Timer´Â °¡Àå Áß¿äÇÏ°í ÇʼöÀûÀÎ ¿ä¼ÒÁßÀÇ Çϳª·Î OS¿¡¼­ Task ½ºÄÉÁÙ¸µÀ» À§Çؼ­ »ç¿ëµÇ±âµµ ÇÕ´Ï´Ù. ÀüÀÚ¾×ÀÚ, Â÷·®¿ë ºí·¢¹Ú½º µîÀÇ ÀÀ¿ë ¾îÇø®ÄÉÀ̼ǿ¡¼­µµ ƯÁ¤ ½Ã°£ ÀÌÈÄ¿¡ ÀÎÅÍ·´Æ®¸¦ ¹ß»ý½ÃÄÑ Á¤ÇØÁø ÀÏÀ» ¼öÇàÇÏ´Â °æ¿ìµî ÀÀ¿ëºÐ¾ß´Â ¹«¼öÈ÷ ¸¹½À´Ï´Ù.
½Ã°£ À̾߱Ⱑ ³ª¿Í¼­ À̾߱â Çϴµ¥ CPUÀÇ Å¬·° ¼Óµµ°¡ 1Hz ¶ó´Â °ÍÀº ¹«¾ùÀ» ÀǹÌÇÏ´Â °ÍÀϱî¿ä ? ÀÌ°ÍÀº 1ÃÊ¿¡ 1¹øÀÇ Tick ÀÌ ¹ß»ýÇÑ´Ù´Â °ÍÀÔ´Ï´Ù. ¾ÆÁÖ Á¤È®ÇÑ °ÍÀº ¾Æ´ÏÁö¸¸ ij½Ã°¡ ÀÖ´Â ½Ã½ºÅÛ¿¡¼­ ij½Ã Hit(ij½Ã¿¡¼­ µ¥ÀÌÅÍ È¤Àº ¸í·É¾î¸¦ °¡Áö°í ¿Ã °æ¿ì)ÀÏ °æ¿ì¿¡ 1ÃÊ¿¡ 1°³ÀÇ ¸í·É¾î¸¦ ¼öÇàÇÑ´Ù´Â °Í°ú °°½À´Ï´Ù. S3C2440ÀÌ 400MHz ·Î µ¿ÀÛ ÇÑ´Ù¸é 1ÃÊ¿¡ 4¾ï¹øÀÇ TickÀÌ ¹ß»ýÇÏ´Â °ÍÀÔ´Ï´Ù. Á¤¸» ¾î¸¶¾î¸¶ ÇÏÁö¿ä. »ó»óÇØ º¸¼¼¿ä. ¿äÁò ÃֽŠ½º¸¶Æ®ÆùµéÀº 2GHz CPUÀ̸鼭 ±×°Íµµ µà¾ó ÄÚ¾î ÀÔ´Ï´Ù. ¾Æ·¡´Â ½Ã°£°ú ÁÖÆļö »çÀÌÀÇ °ü°è ÀÔ´Ï´Ù. Timer ¼³Á¤Çϴµ¥ ÀÌÁ¤µµ´Â ¾Ë°í ÀÖ¾î¾ß ÇÕ´Ï´Ù. Àß ±â¾ï ÇϽñ⠹ٶø´Ï´Ù.

- 1sec = 1,000ms = 1,000,000us = 1,000,000,000ns
- 1Hz = 1KHz = 1MHz = 1GHz

* ½ÇÇ迹Á¦
S3C2440 CPUÀÇ ³»ÀåµÈ Timer4¸¦ ÀÌ¿ëÇؼ­ 1ÃÊ¿¡ Çѹø¾¿ Timer ÀÎÅÍ·´Æ®¸¦ ¹ß»ý½ÃÄÑ LDE2¸¦ Blink(On/Off) ÇÏ´Â ½ÇÇèÀ» Çغ¸µµ·Ï ÇÏ°Ú½À´Ï´Ù.

(1) TCFG0 ·¹Áö½ºÅÍÀÇ Timer4 Prescaler¸¦ 15 ·Î ¼³Á¤ ÇÕ´Ï´Ù.



// Timer4 Prescaler = 15
rTCFG0 = 0x0;
rTCFG0 = (15 << 8);

(2) TCFG1 ·¹Áö½ºÅÍÀÇ Timer4 Divider¸¦ 1/2 ·Î ¼³Á¤ ÇÕ´Ï´Ù.



// Timer4 Divider = 2
rTCFG1 = 0x0;
rTCFG1 = (0x0 << 16);

À§¿Í °°ÀÌ ¼³Á¤Çϸé Datasheet ¿¡ ÀÖ´Â ¾Æ·¡ °ø½Ä¿¡ ÀÇÇؼ­

Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
Timer input clock Frequency = 50000000/(15+1)/2 = 1562500

À§ÀÇ °è»ê½ÄÀÇ Àǹ̴ Timer4ÀÇ Å¬·°ÀÌ 1ÃÊ¿¡ 1562500 ¹ø ¹ß»ý ÇÑ´Ù´Â ÀÇ¹Ì ÀÔ´Ï´Ù. ±×·¯¹Ç·Î Timer4 buffer count(TCNTB4) ¸¦ 15625 ·Î ¼³Á¤ÇØ ÁÖ¸é 10ms ¸¶´Ù Auto Reload(Timer Overflow) °¡ µÇ¾î ÀÎÅÍ·´Æ®°¡ ¹ß»ýÇÏ°Ô µË´Ï´Ù. ¹°·Ð °£´ÜÇÏ°Ô TCNTB4¸¦ 1562500·Î ¼³Á¤ÇØ ÁÖ¸é 1ÃÊ¿¡ Çѹø ¹ß»ýÇÏ´Â ÀÎÅÍ·´Æ®¸¦ ¸¸µé¼ö ÀÖ°ÚÁö¸¸, ¾ÈŸ±õ°Ôµµ S3C2440ÀÇ Å¸À̸Ӵ 16ºñÆ® ŸÀÌ¸Ó À̹ǷΠÃÖ´ë °ªÀ¸·Î 0xFFFF(65535) ÀÌ»óÀ» »ç¿ëÇÒ¼ö°¡ ¾ø½À´Ï´Ù.

(3) TCNTB4 ·¹Áö½ºÅÍ¿¡ Timer4 buffer count ¸¦ 15625·Î ¼³Á¤ ÇÕ´Ï´Ù.



// buffer count
rTCNTB4 = 15625; // interrupt resolution 10msec

(4) TCON ·¹Áö½ºÅÍ¿¡ Update TCNTB4¿Í Auto Reload¸¦ ¼³Á¤ ÇÕ´Ï´Ù.



rTCON = rTCON & ~(0xffffff) | 0x1<<21 ; // Manual update : Update TCNTB4, TIMER Stop
rTCON = rTCON | (1 << 22); // Auto reload

(5) TCON ·¹Áö½ºÅ͸¦ ¼³Á¤ÇÏ¿© Timer¸¦ Start ½Ãŵ´Ï´Ù.

// Start Timer 4
rTCON |= (1<<20);

(6) TCON ¿¡¼­ Manual Update¸¦ ÇØÁ¦ÇÏ°í INTMSK ¿¡¼­ ÀÎÅÍ·´Æ® ¸¶½ºÅ©¸¦ Clear ½Ãŵ´Ï´Ù.

// clean manual update
rTCON &= ~(1<<21);

// Enable interrupt
rINTMSK &= ~(0x1<<14);

ÀÌ·¸°Ô Çϸé Timer4 ÀÎÅÍ·´Æ®°¡ 10msec ¸¶´Ù Çѹø¾¿ ¹ß»ýÇÏ°Ô µË´Ï´Ù.



diag.c - timer4_test()

__irq __arm void isr_timer4(void)
{
rSRCPND = BIT_TIMER4; //Clear pending bit
rINTPND = BIT_TIMER4;

// Timer°¡ 10msec ¸¶´Ù ¹ß»ýÇϹǷΠ1ÃÊ¿¡ Çѹø¾¿ toggle ½ÃÅ°±â À§Çؼ­
if( ++one_seconds_var == 100 )
{
     rGPBDAT = rGPBDAT ^ (0x1 << 6); // toggle LED2
     one_seconds_var = 0;
}


void timer4_test(void)
{

/*
Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
{prescaler value} = 0~255
{divider value} = 2, 4, 8, 16

period = (prescaler value + 1) * (divider value) * buffer count / PCLK = 10 ms
e.g.; PCLK = 50 Mhz
10 ms = (15 + 1) * 2 * 15625 / (50000 * 1000)
15626 = 10 ms * (50000 * 1000) / 2 / (15 + 1)
*/


// Timer4 Prescaler = 15
rTCFG0 = 0x0;
rTCFG0 = (15 << 8);

// Timer4 Divider = 2
rTCFG1 = 0x0;
rTCFG1 = (0x0 << 16);

// Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
// 50000000/(15+1)/2 = 1562500 --> 1ÃÊ¿¡ ¹ß»ýÇÏ´Â Timer Tick

// buffer count
rTCNTB4 = 15625; // interrupt resolution 10msec

rTCON = rTCON & ~(0xffffff) | 0x1<<21 ; // Manual update : Update TCNTB4, TIMER Stop
rTCON = rTCON | (1 << 22); // Auto reload

pISR_TIMER4 = (int)isr_timer4;

// Start Timer 4
rTCON |= (1<<20);

// clean manual update
rTCON &= ~(1<<21);

// Enable interrupt
rINTMSK &= ~(0x1<<14);

}



¿©±â¼­ Àá±ñ ÀϹÝÇÔ¼ö¿Í "__irq __arm" °¡ ÀÖ´Â ÇÔ¼öÀÇ Â÷ÀÌÁ¡Àº ¹«¾ùÀϱî¿ä ?

* ÀÏ¹Ý ÇÔ¼öÀÇ Return ºÎºÐ



* ISR ÇÔ¼öÀÇ Return ºÎºÐ



ISR ÇÔ¼ö´Â ARM Architecture ¿¡¼­ ¹è¿îµ¥·Î ReturnÀ» SUBS PC,LR,#4 ·Î ÇÏ°í ÀÖ½À´Ï´Ù. Àß ±â¾ïÀÌ ³ªÁö ¾ÊÀ¸½Ã¸é ARM Architecture ÀÚ·á¿¡¼­ Pipeline°ú Interrupt ºÎºÐÀ» ´Ù½Ã º¸½Ã±â ¹Ù¶ø´Ï´Ù.

5.6 PWM Buzzer

Buzzer, LED µîÀÇ ¹à±â Á¶Á¤µî¿¡ ÀÀ¿ëÀ» ÇÒ ¼ö ÀÖ½À´Ï´Ù.

* ½ÇÇ迹Á¦
BuzzerÀ» ¿ï¸®µµ·Ï ÇÏ°í ¿ÜºÎ ÀÎÅÍ·´Æ® ¹æ½ÄÀ¸·Î Key K2¸¦ ´©¸£¸é ÁÖÆļö¸¦ 10Hz ¿Ã¸®°í K3¸¦ ´©¸£¸é 10Hz ÁÖÆļö°¡ ³»·Á°¡µµ·Ï Çغ¾½Ã´Ù.



(1) GPBCON ·¹Áö½ºÅÍ¿¡¼­ GPB0¸¦ TOUT0(Timer0 Output) À¸·Î ¼³Á¤ ÇÕ´Ï´Ù.




rGPBCON &= ~0x3; // set GPB0 as tout0, pwm output
rGPBCON |= 0x2;

(2) TCFG0 ·¹Áö½ºÅÍÀÇ Timer0 Prescaler¸¦ 15 ·Î ¼³Á¤ ÇÕ´Ï´Ù.



rTCFG0 &= ~0xff;
rTCFG0 |= 15; // prescaler = 15+1


(3) Timer0ÀÇ Divider ¸¦ 1/8 ·Î ¼³Á¤ ÇÕ´Ï´Ù.




rTCFG1 &= ~0xf;
rTCFG1 |= 2; // mux = 1/8

(4) Timer0 ÀÇ Count buffer register, compare buffer register ¸¦ ¼³Á¤ ÇÕ´Ï´Ù.



rTCNTB0 = (Pclk>>7)/buzzer_freq;
rTCMPB0 = rTCNTB0>>1; // rTCNTB0/2

¿©±â±îÁö ¼³Á¤À» ÇÏ¸é ¾Æ·¡¿Í °°ÀÌ 1KHzÀÇ ÁÖÆļö°¡ ¸¸µé¾î Áü.

Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
Timer input clock Frequency = 50000000/(15+1)/8 = 390625 --> 1ÃÊ¿¡ ¹ß»ýÇÏ´Â Timer Tick

50000000Hz(PCLK) >> 7 = 390625 --> °á±¹Àº 1ÃÊ¿¡ 1¹ø 1Hz °ª, buzzer_freq(1000) À¸·Î ³ª´©¾î ÁÖ¸é TCNTBnÀº 1KHz °¡ µË´Ï´Ù.
Ãß°¡·Î TCMPBn Àº TCNTBn/2 ·Î Çϸé ÃÖÁ¾ÀûÀ¸·Î 1KHzÀÎ Timer0(TOUT0) À¸·Î 1KHzÀÎ PWM ÆÄÇüÀÌ Ãâ·Â µË´Ï´Ù.



(5) Timer0 ¸¦ Start ½Ãŵ´Ï´Ù.



rTCON &= ~0x1f;
rTCON |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
rTCON &= ~2; //clear manual update bit

diag.c - pwm_buzzer_test()

__irq __arm void isr_eint_8_23(void)
{

if(rINTPND==BIT_EINT8_23)
{
     ClearPending(BIT_EINT8_23);

     if(rEINTPEND&(1<<11)) // KEY2
     {
          rEINTPEND |= 1 << 11;
          rGPBDAT = rGPBDAT ^ (0x1 << 6); // LED2 toggle

          buzzer_freq += 100;
          pwm_buzzer_test();
     }

     if(rEINTPEND&(1<<13)) // KEY3
     {
          rEINTPEND |= 1 << 13;
          rGPBDAT = rGPBDAT ^ (0x1 << 7); // LED3 toggle

          buzzer_freq -= 100;
          pwm_buzzer_test();
     }
}
}

void pwm_buzzer_test(void)
{
rGPBCON &= ~0x3; // set GPB0 as tout0, pwm output
rGPBCON |= 0x2;

rTCFG0 &= ~0xff;
rTCFG0 |= 15; // prescaler = 15+1

rTCFG1 &= ~0xf;
rTCFG1 |= 2; // mux = 1/8

// Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
// 50000000/(15+1)/8 = 390625 --> 1ÃÊ¿¡ ¹ß»ýÇÏ´Â Timer Tick

// PCLK = 50000000Hz >> 7 = 390625 --> °á±¹Àº 1ÃÊ¿¡ 1¹ø 1Hz °ªÀÌ´Ù.
// buzzer_freq(1000) À¸·Î ³ª´©¾î ÁÖ¸é 1KHz°¡ µÈ´Ù.
rTCNTB0 = (PCLK>>7)/buzzer_freq;

rTCMPB0 = rTCNTB0>>1; // rTCNTB0/2

rTCON &= ~0x1f;
rTCON |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
rTCON &= ~2; //clear manual update bit
}






5.7 UART

ÀÓº£µðµå ÇÁ·Î±×·¥¿¡¼­ Timer¿Í ÇÔ²² UARTµµ ÇʼöÀûÀÎ ÀÎÅÍÆäÀ̽º ÀÔ´Ï´Ù. °³¹ßÃʱ⿡ µð¹ö±×¸ð´ÏÅÍ¿ëÀ¸·Î È°¿ëÀ» Çϱ⵵ ÇÏ°í °³¹ßÀÌ ¿Ï·áµÈ ÀÌÈÄ¿¡´Â Á¦Ç°ÀÇ Setting, Firmware ¾÷±×·¹ÀÌµå µî¿¡µµ È°¿ëÀ» ÇÕ´Ï´Ù.



* ½ÇÇ迹Á¦
UART0¸¦ PC¿Í 115200bps Baudrate·Î Åë½Å(RX, TX)À» ÇÏ´Â Echo server·Î ¸¸µé¾î º¾½Ã´Ù.

(1) GPH2¸¦ TXD·Î GPH3À» RXD·Î ¼³Á¤ÇÏ°í, GPHÀÇ PullupÀ» Disable ÇÕ´Ï´Ù.




rGPHCON &= ~( (0x3 << 6) | (0x3 << 4) );
rGPHCON |= ( (0x2 << 6) | (0x2 << 4) );
rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]

(2) UART0ÀÇ FIFO Buffer¸¦ Disable ÇÕ´Ï´Ù.



rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable

(3) UART0ÀÇ Auto Flow ControlÀ» Disable ÇÕ´Ï´Ù.



rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable

(4) UART Line Control Regier ¼³Á¤(Normal Mode, No Parity, One Stop Bit, Word Length = 8)




rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits


(5) UART Control Regier ¼³Á¤






rUCON0 = (0x0 << 10) | (0x1 << 6) | (0x0 << 5) | (0x0 << 4) | (0x1 << 2) | (0x1 << 0);

(6) UART Baudrate Divisor Register ¼³Á¤



rUBRDIV0 = ( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 value = 26

UBRDIV = (int)( UART clock / ( buad rate x 16) ) –1
( UART clock : PCLK, FCLK/n or UEXTCLK )

¿ì¸®´Â UART ClockÀ¸·Î PCLK 50MHz(50000000)À» »ç¿ëÇÏ°í ÀÖÀ¸¹Ç·Î °è»ê½ÄÀº ´ÙÀ½°ú °°½À´Ï´Ù.

UBRDIV = ( PCLK / (115200*16) ) - 1 = 26

diag.c - uart0_test()

void uart0_send_byte(int data)
{

while(!(rUTRSTAT0 & 0x2)); //Wait until THR is empty.
Delay(10);
WrUTXH0(data);

}

void uart0_test(unsigned int baud)
{

rGPHCON &= ~( (0x3 << 6) | (0x3 << 4) );
rGPHCON |= ( (0x2 << 6) | (0x2 << 4) );


rGPHUP = 0x7ff; // The pull up function is disabled GPH[10:0]


rUFCON0 = 0x0; //UART channel 0 FIFO control register, FIFO disable
rUMCON0 = 0x0; //UART chaneel 0 MODEM control register, AFC disable

//UART0
rULCON0 = 0x3; //Line control register : Normal,No parity,1 stop,8 bits

rUCON0 = (0x0 << 10) | (0x1 << 6) | (0x0 << 5) | (0x0 << 4) | (0x1 << 2) | (0x1 << 0);

rUBRDIV0 = ( (int)(Pclk/16./baud+0.5) -1 ); //Baud rate divisior register 0 value = 26

while(!(rUTRSTAT0 & 0x4)); //Wait until tx shifter is empty.

uart0_send_byte('E');
uart0_send_byte('c');
uart0_send_byte('h');
uart0_send_byte('o');
uart0_send_byte('\r');
uart0_send_byte('\n');

while(1)
{
     Delay(10);
     while(!(rUTRSTAT0 & 0x1)); //Receive data ready

     uart0_send_byte((*(volatile unsigned char *)0x50000024));
}

}





À§ÀÇ ÄÚµå´Â Å͹̳Îâ¿¡ "Echo" ¸¦ Display ÇÏ°í Å͹̳ο¡¼­ ÀÔ·ÂÇÑ ¹®ÀÚ¸¦ ¹Ù·Î Echo ÇÏ¿© ´Ù½Ã Å͹̳Πâ¿¡ Ç¥½ÃÇÏ°Ô µË´Ï´Ù.