无网不进  
软硬件开发

这次是S3C2440上面的uart0的FIFO模式的实验,程序设置串口0的输入fifo中包含的数据个数在从小于16字节的状态变换为大于等于16字节的状态的瞬间触发一个脉冲中断,在这个中断中,把输入fifo 中的数据全部写入到输出fifo中,在输出fifo 从非空状态变换成空的状态的瞬间会触发一个脉冲中断,在中断中我让灯闪一下,实验的正确现象是从超级终端往2440的串口0发数据,每发16个字节的数据,串口就会把这16个字节全部打印出来,同时由于输出fifo变空,会触发灯闪一下,经过测试,实验现象和上面说的是一致的。要注意在往utxh0寄存器写数据的时候要先检查输出fifo是不是已经满了,如果已经满了就要等待,否则会造成输出fifo对头的数据提前出队,出队的数据就丢掉了,输入fifo中的数据个数要从UFSTAT寄存器里面的相应字段去读,uart的dma模式怎么用的还需要研究一下。

 

Makefile

 

[cpp] view plain copy
 
  1. uart_interrupt.bin : start.s function.c  
  2.     arm-linux-gcc -g -c -o start.o start.s  
  3.     arm-linux-gcc -g -c -o function.o function.c  
  4.     arm-linux-ld -Ttext 0x30000000 -g start.o function.o -o uart_fifo.elf  
  5.     arm-linux-objcopy -O binary -S uart_fifo.elf uart_fifo.bin  
  6.     arm-linux-objdump -D -m arm uart_fifo.elf > uart_fifo.dis  
  7. clean :   
  8.     rm -f *.o *.bin *.dis *.elf  


start.s

 

[cpp] view plain copy
 
  1. .text  
  2. .global _start  
  3. _start:  
  4.     b       reset  
  5.     b       .  
  6.     b       .  
  7.     b       .  
  8.     b       .  
  9.     b       .  
  10.     b       handle_irq  
  11.     b       .  
  12.   
  13. reset:  
  14.     @shut down the watchdog  
  15.     ldr     r0, =0x53000000  
  16.     ldr     r1, =0x00000000  
  17.     str     r1, [r0]  
  18.   
  19.     @init the stack address  
  20.     ldr     r1, =4096  
  21.     ldr     r0, =0x40000000  
  22.     add     sp, r1, r0  
  23.   
  24.     bl      init_led  
  25.     bl      init_clock  
  26.     bl      display_led1  
  27.     bl      init_sdram  
  28.     bl      display_led2  
  29.   
  30.     @reset the stack pointer  
  31.     ldr     sp, =0x34000000 @change stack to the end of sdram  
  32.     msr     cpsr_c, #0xd2  
  33.     ldr     sp, =0x33F00000 @change the stack pointer of irq mode  
  34.     msr     cpsr_c, #0xd3 @change cpu back to svc mode  
  35.   
  36.   
  37.     bl      copy_code2sdram @copy 8KB data from norflash to sdram  
  38.       
  39.     ldr     pc, =on_sdram  
  40. on_sdram:  
  41.     bl      init_uart0  
  42.     bl      init_interrupt  
  43.     msr     cpsr_c, #0x53 @clear the irq disable bit in cpsr  
  44.   
  45.   
  46.     bl      main  
  47. halt_loop:  
  48.     b       halt_loop  
  49.   
  50.   
  51. handle_irq:  
  52.     sub     lr, lr, #4 @set the address(int main function) to return when handle_irq ends  
  53.     stmdb   sp!, {r0-r12, lr}   @save the universal registers and lr_irq to the stack of irq mode  
  54.     bl      handle_irq_func     @branch to the irq handleing function achieved in function.c   
  55.     ldmia   sp!, {r0-r12, pc}^  @resume the universal registers and save lr to pc while copying spsr to cpsr  


function.c

 

[cpp] view plain copy
 
    1. //gpb registers  
    2. #define     GPBCON      (*((volatile unsigned long *)0x56000010))     
    3. #define     GPBDAT      (*((volatile unsigned long *)0x56000014))  
    4.   
    5. //mem controler registers  
    6. #define     BWSCON      (*((volatile unsigned long *)0x48000000))  
    7. #define     BANKCON0    (*((volatile unsigned long *)0x48000004))  
    8. #define     BANKCON1    (*((volatile unsigned long *)0x48000008))  
    9. #define     BANKCON2    (*((volatile unsigned long *)0x4800000C))  
    10. #define     BANKCON3    (*((volatile unsigned long *)0x48000010))  
    11. #define     BANKCON4    (*((volatile unsigned long *)0x48000014))  
    12. #define     BANKCON5    (*((volatile unsigned long *)0x48000018))  
    13. #define     BANKCON6    (*((volatile unsigned long *)0x4800001C))  
    14. #define     BANKCON7    (*((volatile unsigned long *)0x48000020))  
    15. #define     REFRESH     (*((volatile unsigned long *)0x48000024))  
    16. #define     BANKSIZE    (*((volatile unsigned long *)0x48000028))  
    17. #define     MRSRB6      (*((volatile unsigned long *)0x4800002C))  
    18. #define     MRSRB7      (*((volatile unsigned long *)0x48000030))  
    19.   
    20. //gpg registers  
    21. #define     GPGCON      (*((volatile unsigned long *)0x56000060))  
    22.   
    23. //gph registers  
    24. #define     GPHCON      (*((volatile unsigned long *)0x56000070))  
    25. #define     GPHUP       (*((volatile unsigned long *)0x56000078))  
    26.   
    27. //interrupt related registers  
    28. #define     EINTMASK    (*((volatile unsigned long *)0x560000A4))  
    29. #define     INTMSK      (*((volatile unsigned long *)0x4A000008))  
    30. #define     INTMOD      (*((volatile unsigned long *)0x4A000004))  
    31. #define     INTOFFSET   (*((volatile unsigned long *)0x4A000014))  
    32. #define     SRCPND      (*((volatile unsigned long *)0x4A000000))  
    33. #define     INTPND      (*((volatile unsigned long *)0x4A000010))  
    34. #define     EINTPEND    (*((volatile unsigned long *)0x560000A8))  
    35. #define     INTSUBMSK   (*((volatile unsigned long *)0x4A00001C))  
    36. #define     SUBSRCPND   (*((volatile unsigned long *)0x4A000018))  
    37.   
    38.   
    39. //PLL related registers  
    40. #define     LOCKTIME    (*((volatile unsigned long *)0x4C000000))  
    41. #define     MPLLCON     (*((volatile unsigned long *)0x4C000004))  
    42. #define     CLKDIVN     (*((volatile unsigned long *)0x4C000014))  
    43.   
    44. //uart0 related registers  
    45. #define     ULCON0      (*((volatile unsigned long *)0x50000000))  
    46. #define     UCON0       (*((volatile unsigned long *)0x50000004))  
    47. #define     UFCON0      (*((volatile unsigned long *)0x50000008))  
    48. #define     UMCON0      (*((volatile unsigned long *)0x5000000C))  
    49. #define     UBRDIV0     (*((volatile unsigned long *)0x50000028))  
    50. #define     UTRSTAT0    (*((volatile unsigned long *)0x50000010))  
    51. #define     URXH0       (*((volatile unsigned char *)0x50000024))  
    52. #define     UTXH0       (*((volatile unsigned char *)0x50000020))  
    53. #define     UFSTAT0     (*((volatile unsigned long *)0x50000018))  
    54.   
    55.   
    56. void blink(void);  
    57. void display_led(int);  
    58.   
    59. void init_sdram(){  
    60.     BWSCON      = 0x22011110;  
    61.     BANKCON0    = 0x00000700;  
    62.     BANKCON1    = 0x00000700;  
    63.     BANKCON2    = 0x00000700;  
    64.     BANKCON3    = 0x00000700;  
    65.     BANKCON4    = 0x00000700;  
    66.     BANKCON5    = 0x00000700;  
    67.     BANKCON6    = 0x00018005;  
    68.     BANKCON7    = 0x00018005;  
    69.   
    70.     //when hcls is 12MHz  
    71.     //REFRESH       = 0x008C07A3;  
    72.   
    73.     //when hckl is 100MHz  
    74.     REFRESH     = 0x008C04F4;   
    75.   
    76.     BANKSIZE    = 0x000000B1;  
    77.     MRSRB6      = 0x00000030;  
    78.     MRSRB7      = 0x00000030;  
    79. }  
    80.   
    81.   
    82. void init_interrupt(){  
    83.     //set the gpio pins of the six keys to interrupt mode   
    84.     GPGCON = (1<<(0*2+1) | 1<<(3*2+1) | 1<<(5*2+1) | 1<<(6*2+1) | 1<<(7*2+1) | 1<<(11*2+1));  
    85.   
    86.     //set EINTMASK register to enable external interrupt  
    87.     EINTMASK &= (~(1<<8 | 1<<11 | 1<<13 | 1<<14 | 1<<15 | 1<<19));  
    88.   
    89.     //set INTMSK register to enable eint8_23  
    90.     INTMSK &= (~(1<<5));  
    91.   
    92.     //enable uart0 interrupt  
    93.     INTMSK &= (~(1<<28));  
    94.     //enable rxd0 interrupt and txd0 interrupt  
    95.     INTSUBMSK &= (~(0b11));  
    96.   
    97.     //set INTMOD register to set int8_23 to irq mode  
    98.     INTMOD &= (~(1<<5));  
    99. }  
    100.   
    101.   
    102. void init_uart0(){  
    103.     GPHCON |= ( (1<<5) | (1<<7) );  
    104.     GPHCON &= ~( (1<<4) | (1<<6) );  
    105.     GPHUP |= ( (1<<2) | (1<<3) );  
    106.   
    107.     ULCON0 = 0x03; //8 data bits, 1 stop bits, no check  
    108.     UCON0 = 0X05; //polling mode or interrupt mode  
    109.     UCON0 |= (1<<6); //enable rx0 time out interrupt  
    110.     UFCON0 = 0b00100001; //enable fifo, set receive fifo trigger to be 16 bytes and set transport fifo trigger to zero   
    111.     UMCON0 = 0x00; //disable AFC  
    112.     UBRDIV0 = 0x1A; //bit rate is 115200(pclk is 50MHz)  
    113. }  
    114.   
    115. unsigned char getchar_uart0(){  
    116.     //while( !(UTRSTAT0&1) );  
    117.     return URXH0;  
    118. }  
    119.   
    120. void putchar_uart0_fifo(unsigned char ch){  
    121.     while( UFSTAT0&(1<<6) ); //wait while transport fifo is full   
    122.     UTXH0 = ch;  
    123. }  
    124.   
    125. void puts_uart0_fifo(char *str){  
    126.     int i;  
    127.     for(i=0; str[i]!='\0'; i++){  
    128.         putchar_uart0_fifo(str[i]);  
    129.     }  
    130. }  
    131.   
    132.   
    133. void handle_key(){  
    134.     int eint_v;  
    135.   
    136.     eint_v = EINTPEND;  
    137.   
    138.     if(eint_v & (1<<8)){  
    139.         display_led(1);  
    140.         EINTPEND = 1<<8;  
    141.         return;       
    142.     }  
    143.   
    144.     if(eint_v & (1<<11)){  
    145.         display_led(2);  
    146.         EINTPEND = 1<<11;  
    147.         return;       
    148.     }  
    149.   
    150.     if(eint_v & (1<<13)){  
    151.         display_led(3);  
    152.         EINTPEND = 1<<13;  
    153.         return;       
    154.     }  
    155.   
    156.     if(eint_v & (1<<14)){  
    157.         display_led(4);  
    158.         EINTPEND = 1<<14;  
    159.         return;       
    160.     }  
    161.   
    162.     if(eint_v & (1<<15)){  
    163.         display_led(5);  
    164.         EINTPEND = 1<<15;  
    165.         return;       
    166.     }  
    167.   
    168.     if(eint_v & (1<<19)){  
    169.         display_led(6);  
    170.         EINTPEND = 1<<19;  
    171.         return;       
    172.     }  
    173. }  
    174.   
    175. #define     RX0_FIFO_SIZE   64  
    176. #define     TX0_FIFO_SIZE   64  
    177. void handle_uart0_interrupt(){  
    178.     int i, fifo_count;  
    179.     unsigned char ch;  
    180.   
    181.     if(SUBSRCPND & (1<<1)){ //txd0 interrupt will happen when transport fifo is empty  
    182.         //do nothing  
    183.         if( (UFSTAT0&(0b111111<<8)) == 0 )  
    184.             blink();  
    185.     }  
    186.   
    187.   
    188.   
    189.     if(SUBSRCPND & (1<<0)){ //rxd0 interrupt  
    190.         if( UFSTAT0 & (1<<6) ){ //rx0 fifo is full  
    191.             for(i=0; i<RX0_FIFO_SIZE; i++){  
    192.                 ch = URXH0;  
    193.                 putchar_uart0_fifo(ch);  
    194.             }     
    195.         }  
    196.         else{ //rx0 fifo is not full  
    197.             //blink();  
    198.             fifo_count = ((UFSTAT0 & (0b111111<<0)) >> 0); //get the data length in fifo  
    199.             for(i=0; i<fifo_count; i++){  
    200.                 ch = URXH0;  
    201.                 putchar_uart0_fifo(ch);  
    202.             }     
    203.         }  
    204.   
    205.     }  
    206.   
    207.     SUBSRCPND = SUBSRCPND;  
    208. }  
    209.   
    210. void handle_irq_func(){  
    211.     int offset_v;  
    212.     offset_v = INTOFFSET;  
    213.     switch(offset_v){  
    214.     case 5: //external interrupt  
    215.         handle_key();  
    216.         break;  
    217.     case 28:  
    218.         handle_uart0_interrupt();  
    219.         break;  
    220.     default:  
    221.         break;  
    222.     }  
    223.   
    224.     //clear the interrupt  
    225.     SRCPND = 1<<offset_v;  
    226.     INTPND = 1<<offset_v;  
    227. }  
    228.   
    229. void delay(int n){  
    230.     int i, j;  
    231.     for(i=0; i<n; i++){  
    232.         for(j=0; j<1000; j++){}  
    233.     }  
    234. }  
    235.   
    236. void blink(){  
    237.     GPBDAT = 0xffffffff;  
    238.     GPBDAT = 0x00000000;  
    239.     delay(1);  
    240.     GPBDAT = 0xffffffff;  
    241.     delay(1);  
    242. }  
    243.   
    244. void display_led1(){  
    245.     GPBDAT = ~(1<<5);  
    246.     delay(1);  
    247. }  
    248.   
    249. void display_led2(){  
    250.     GPBDAT = ~(3<<5);  
    251.     delay(1);  
    252. }  
    253.   
    254. void display_led3(){  
    255.     GPBDAT = ~(7<<5);  
    256.     delay(1);  
    257. }  
    258.   
    259. void display_led4(){  
    260.     GPBDAT = ~(15<<5);  
    261.     delay(1);  
    262. }  
    263.   
    264. void display_led(int n){  
    265.     GPBDAT = ~(n<<5);  
    266. }  
    267.   
    268.   
    269. void copy_code2sdram(){  
    270.     int size, i;  
    271.     unsigned char *src, *des;  
    272.     size = 8*1024;  
    273.   
    274.     des = (unsigned char*)(0x30000000);  
    275.     src = (unsigned char *)(0x00000000);  
    276.     for(i=0; i<size; i++){  
    277.         *(des++) = *(src++);  
    278.     }  
    279. }  
    280.   
    281. void init_led(){  
    282.     GPBCON = 0x00015400;  
    283.     GPBDAT &= ~(0x0f<<5);  
    284. }  
    285.   
    286. //initialize the clock of soc  
    287. void init_clock(){  
    288.     LOCKTIME = 0xffffffff;    
    289.     CLKDIVN = 0X03; //fclk:hclk:pclk=1:2:4    
    290.     __asm__    
    291.     (    
    292.         "mrc    p15, 0, r1, c1, c0, 0\n"    
    293.         "orr    r1, r1, #0xc0000000\n"    
    294.         "mcr    p15, 0, r1, c1, c0, 0\n"        
    295.     );    
    296.     MPLLCON = (92<<12)|(1<<4)|(2<<0); //fclk=200M, hclk=100M, pclk=50M   
    297. }  
    298.   
    299. /* 
    300. int main(void){ 
    301.     int i; 
    302.  
    303.     GPBCON = 0x00015400; 
    304.     i = 0; 
    305.     while(1){ 
    306.         GPBDAT = ~(1<<(i+5)); 
    307.         delay(1); 
    308.         i = (i+1)%4; 
    309.     } 
    310.     return 0; 
    311. */  
    312.   
    313. int main(void){  
    314.     display_led3();  
    315.     while(1){  
    316.         //waiting for interrupt  
    317.         //puts_uart0_fifo("Hello world\r\n");  
    318.         //puts_uart0_fifo("this is a test of uart0\r\n");  
    319.     }  
    320.     return 0;  
    321. }  
posted on 2018-05-31 10:34  无网不进  阅读(344)  评论(0编辑  收藏  举报