Embeddedsystem(6)_2.PDF

Similar documents
untitled

(Asynchronous Mode) ( 1, 5~8, 1~2) & (Parity) 1 ; * S erial Port (BIOS INT 14H) - 1 -

Microsoft Word doc

Chapter #01 Subject

6주차.key

K&R2 Reference Manual 번역본

KEY 디바이스 드라이버

1

CANTUS Evaluation Board Ap. Note

Embeddedsystem(8).PDF

슬라이드 1

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

교육지원 IT시스템 선진화

PowerPoint 프레젠테이션

PowerPoint 프레젠테이션

SRC PLUS 제어기 MANUAL

À©µµ³×Æ®¿÷ÇÁ·Î±×·¡¹Ö4Àå_ÃÖÁ¾

chap7.key


PowerPoint 프레젠테이션

untitled

T100MD+

untitled


PowerPoint 프레젠테이션

Microsoft PowerPoint - lab14.pptx

Microsoft Word - MPC850 SPI Driver.doc

MicrocontrollerAcademy_Lab_ST_040709

10.

hd1300_k_v1r2_Final_.PDF

[8051] 강의자료.PDF

untitled

untitled

PowerPoint 프레젠테이션

프로그램을 학교 등지에서 조금이라도 배운 사람들을 위한 프로그래밍 노트 입니다. 저 역시 그 사람들 중 하나 입니다. 중고등학교 시절 학교 도서관, 새로 생긴 시립 도서관 등을 다니며 책을 보 고 정리하며 어느정도 독학으르 공부하긴 했지만, 자주 안하다 보면 금방 잊어

<BDBAB8B6C6AE2D C5EBBDC52E >

PowerPoint 프레젠테이션

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A636C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

Chapter_06

歯9장.PDF

Microsoft Word doc

슬라이드 1

10주차.key

13주-14주proc.PDF

/chroot/lib/ /chroot/etc/

AN_0005B_UART

PowerPoint 프레젠테이션

Chap06(Interprocess Communication).PDF

03장.스택.key

C++-¿Ïº®Çؼ³10Àå

Microsoft PowerPoint - e9.pptx

Sena Technologies, Inc. HelloDevice Super 1.1.0


PowerPoint 프레젠테이션

Microsoft PowerPoint - 09-Pipe

Microsoft PowerPoint - polling.pptx

2. GCC Assembler와 AVR Assembler의차이 A. GCC Assembler 를사용하는경우 i. Assembly Language Program은.S Extension 을갖는다. ii. C Language Program은.c Extension 을갖는다.

untitled

본 강의에 들어가기 전

<4D F736F F F696E74202D20BBB7BBB7C7D15F FBEDFB0A3B1B3C0B05FC1A638C0CFC2F72E BC8A3C8AF20B8F0B5E55D>

MAX+plus II Getting Started - 무작정따라하기

Chap04(Signals and Sessions).PDF

BMP 파일 처리

강의10

06Àå

Microsoft Word - KPMC-400,401 SW 사용 설명서

슬라이드 1

한글사용설명서

Microsoft Word doc

hlogin2

Microsoft PowerPoint - IOControl [호환 모드]

bn2019_2

<443A5C4C C4B48555C B3E25C32C7D0B1E25CBCB3B0E8C7C1B7CEC1A7C6AE425CBED0C3E0C7C1B7CEB1D7B7A55C D616E2E637070>

untitled

제1장 Unix란 무엇인가?

untitled

<4D F736F F F696E74202D20B8B6C0CCC5A9B7CEC7C1B7CEBCBCBCAD202839C1D6C2F7207E203135C1D6C2F >

(SW3704) Gingerbread Source Build & Working Guide

1217 WebTrafMon II

도 1 명세서 도면의 간단한 설명 도 1은 본 발명의 바람직한 실시예에 따른 데이터 송수신 장치의 회로도이다. 도 2는 도 1에 도시된 등화기의 일 실시예를 보여주는 회로도이다. 도 3은 도 1에 도시된 프리엠퍼시스 회로의 일 실시예를 보여주는 회로도이다. 도 4는 본

목차 1. 제품 소개 특징 개요 Function table 기능 소개 Copy Compare Copy & Compare Erase

Remote UI Guide

제1장 Unix란 무엇인가?

SMB_ICMP_UDP(huichang).PDF

Microsoft PowerPoint - 3ÀÏ°_º¯¼ö¿Í »ó¼ö.ppt

CPX-E-SYS_BES_C_ _ k1

PowerPoint 프레젠테이션

제12장 파일 입출력

Microsoft Word - FS_ZigBee_Manual_V1.3.docx

PowerChute Personal Edition v3.1.0 에이전트 사용 설명서

Microsoft PowerPoint - chap13-입출력라이브러리.pptx

untitled


2009년 상반기 사업계획


Chapter 4. LISTS

[ 융합과학 ] 과학고 R&E 결과보고서 뇌파를이용한곤충제어 연구기간 : ~ 연구책임자 : 최홍수 ( 대구경북과학기술원 ) 지도교사 : 박경희 ( 부산일과학고 ) 참여학생 : 김남호 ( 부산일과학고 ) 안진웅 ( 부산일과학고 )

고급 프로그래밍 설계

LCD Display

Transcription:

SA1110 Peripheral Control Module UART Blocking I/O S5N8946 UART Device Driver SA1110 UART Device Driver UART Device Driver Program Test (Host / SA1110)

ARM System Bus DMA Controller ARM Peripheral Bus LCD Controller Serial Port 0 UDC Serial Port 1 GPCLK/UART Serial Port 2 ICP Serial Port 3 UART Serial Port 4 MCP / SSP L_PCLK L_BIAS UDC+ UDC- TXD1 RXD1 TXD2 RXD2 TXD3 RXD3 TXD4 SCLK

SA1110 Peripheral Control Module Peripheral Serial Protocol Register Width / DMA port Size Base Address Interrupt Number LCD Controller 32 0h B010 0000 12 Serial port 0 : USB 8 0h 8000 0000 13 UART 8 0h 8001 0000 Serial port 1 : 15 GPCLK 8 0h 8002 0000 UART 8 0h 8003 0000 Serial port 2 : ICP 16 HSSP 8 0h 8004 0000 Serial port 3 : UART 8 0h 8005 0000 17 MPC 16 0h 8006 0000 18 Serial port 4 : SSP 16 0h 8007 0000 19 Peripheral pin controller (PPC) 32 0h 9006 0000

UART 0x 8001 0000 UTCR0 / UART Control Register 0 0 0x 8001 0004 UTCR1 / UART Control Register 1 1 0x 8001 0008 UTCR2 / UART Control Register 2 2 0x 8001 000C UTCR3 / UART Control Register 3 3 0x 8001 0010 UTDR / UART Data Register 0x 8001 001C UTSR0 / UART State Register 0 0 0x 8001 0020 UTSR1 UART State Register 1 1

UTCR (UART Control Register 0) UART 7 6 5 4 3 2 1 0 RESERVED TCE RCE SCE DSS SBS OES PE 0??????? PE (Parity Enable) (0: X / 1: ) OES (Odd / Even parity Select) (0: / 1: ) SBS : Stop Bit Select (0:1 / 1:2 ) DSS : Data Size Select (0:7 / 1:8 ) SCE : Sample Clock Enable (0: / 1: (GPIO20)) RCE : Receive Clock Edge Select (0: / 1: ) TCE : Transmit Clock Edge Select (0: / 1: )

UART UTCR 1, 2 UTCR 1 7 6 5 4 3 2 1 0 RESERVED BRD 11 BRD 10 BRD 9 BRD 8 UTCR 2 0 0 0 0???? 7 6 5 4 3 2 1 0 BRD 7 BRD 6 BRD 5 BRD 4 BRD 3 BRD 2 BRD 1 BRD 0 0??????? *. BaudRate = (3.6864 X 10^6) / (16 X (BRD + 1)) BRD = (3.6864 X 10^6) / (16 X (BaudRate ) - 1 * 9600baud BRD = (3.6864 X 10^6) / (16 X (9600 ) 1 = 23

UTCR (UART Control Register 3) UART 7 6 5 4 3 2 1 0 RESERVED LBM TIE RIE BRK TXE RXE 0 0?????? RXE : Receiver Enable ( 0: / 1: ) TXE : Transmitter Enable ( 0: / 1: ) BRK : Break ( 0: / 1: LOW ) RIE : Receive FIFO Interrupt Enable ( 0: X / 1: ) TIE : Transmit FIFO Interrupt Enable ( 0: X / 1: ) LBM : Loopback Mode ( 0: / 1: )

UTDR (UART Data Register) UART 10 9 8 7 6 5 4 3 2 1 0 ROR FRE PRE DATA??????????? * ROR, FRE, PRE 1 ROR (Receive Over Run Error) : High FRE (Framing Error) : High PRE (Parity Error) : High

UTSR0(UART State Register) UART 7 6 5 4 3 2 1 0 RESERVED EIF REB RBB RID RFS TFS 0 0?????? TFS (Transmit FIFO Service Request Flag) : FIFO Write High RFS (Receiver FIFO Service Request Flag) : FIFO High RID (Receiver Idle Status) : FIFO High RBB (Receiver Begin of Break Status) : Break High REB (Receiver End of Break Status) : Break High EIF (Error in FIFO Flag) : 4 High

UTSR1(UART State Register) UART 7 6 5 4 3 2 1 0 RESERVED ROR FRE PRE TNF RNE TBY 0 0?????? TBY (Transmitter Busy Flag) : High RNE (Receive FIFO Not Empty Flag) : FIFO High TNF (Transmit FIFO Not Full Flag) : FIFO High PRE (Parity Error) : High FRE (Framing Error) : High ROR (Receive Over Run Error) : High

Blocking I/O Blocking, Nonblocking - Blocking - read,, - write,, -Nonblocking -Read / write read / write EAGIN -Nonblock -open( /dev/serial, O_RDWR O_NONBOCK);

Blocking I/O sleep_on / wake_up #include <linux/sched.h> void interruptible_sleep_on(struct wait_queue **q) void sleep_on(struct wait_queue **q) void wake_up_interruptible(struct wait_queue **q) void wake_up(struct wait_queue **q) Waiting queue - sleep struct wait_queue* - sleep_on wake_up

struct wait_queue *wq = NULL; Blocking I/O read_write_t sleepy_read(struct inode *inode, struct file *filp, char *buf, count_t count) if ( filp -> f_flags & O_NONBLOCK) printk(kern_debug procesor %i is nonblocking mode n, current -> pid_; return EAGAIN; else printk(kern_debug process %i (%s) going to sleep n,urrent_pid, courrent -> comm); interruptible_sleep_on(&wq); return 0; read_write_t sleepy_write(struct inode *inode, struct file *filp, const char *buf, count_t cout) printk(kern_debug process %i (%s) (&commn); wake_up_interrupt (&wq); return count;

UART Device Driver sleep_on() inq rp wp wake_up() process read() write() Input ring buffer Output ring buffer rx_isr xmit tx_isr UART wp rp sleep_on() wake_up() outq

S5N8946 Device driver #define UART_BASE(BASE_ADDR+0xd000) struct uart_regs u_32 ulcon; /* line control register */ u_32 ucon; /* control register */ u_32 ustat; /* status register */ u_32 utxbuf; /* transmit buffer register */ u_32 urxvuf; /* receive buffer register */ u_32 ubrdiv; /* baud rate divisor register */ u_32 brdcnt; /* baud rate count register */ u_32 brdclk; /* baud rate clock monitor */ ;

S5N8946 Device driver /* UART line control register */ #define UART_WL(x) ((x) & 0x3) /* 00:5bit, 01:6bit, 10:7bit, 11:8bit */ #define UART_STB (1<<2) /* stop bit, 0:one, 1:two */ #define UART_PMD(x) ((x)<<3 & 0x38) /* parity,0xx:no, 100:odd, 101:even */ #define UART_SC (1<<6) /* serial clock, 0:internal 1:external */ #define UART_IR (1<<7) /* infra-red mode */ /* UART control register */ #define UART_RxM(x) ((x) & 0x3) /*receive mode, 00:disable, 01: interrupt, 10:GDMA ch0, 11:GDMA ch1*/ #define UART_RXSI (1<<2) /* receive status interrupt enable */ #define UART_TxM(x) ((x)<<3 & 0x18) /* transmit mode, same as UART_RxM(x) */ #define UART_DSR (1<<5) /* data set ready */ #define UART_SBK (1<<6) /* send break */ #define UART_LPM (1<<7) /* look-back mode */

S5N8946 Device driver /* UART status register */ #define UART_OV (1) /* overrun error */ #define UART_PE (1<<1) /* parity error */ #define UART_FE (1<<2) /* frame error */ #define UART_BKD (1<<3) /* break interrupt */ #define UART_DTR (1<<4) /* data terminal ready */ #define UART_RDR (1<<5) /* receive data ready */ #define UART_TBE (1<<6) /* Tx buffer register empty */ #define UART_TC (1<<7) /* transmit complete */

S5N8946 Device driver SERIAL_MAJOR = 150; struct file_operations sserial_fops = read: sserial_read, write:sserial_write, open: sserial_open, release : sserial_release; int sserial_init(void) int result; result=register_chrdev(serial_major, "serial",&sserial_fops); if(result<0) printk( sserial:can't get major %d n", SERIAL_MAJOR ); return result; return 0;

S5N8946 Data structure Data structure for device #define MAX_SIZE 48 typedef struct sserial_dev_t struct wait_queue *inq, *outq; char inbuf[max_size]; char outbuf[max_size]; int inrp, inwp; int outrp, outwp; int buf_empty; sserial_dev_t; sserial_dev_t sserial_dev;

S5N8946 Open function sserial_open Device data structure Device Register interrupt service routines int sserial_open(struct inode *inode, struct file *filp) sserial_dev_t *dev; dev = &sserial_dev; memset(dev, 0, sizeof(serial_dev_t)); dev->buf_empty = 1; filp->private_data = dev; s5n8946_sserial_init(); request_irq(5, sserial_rx_isr, 0, sserial_dev_rx", NULL); request_irq(4, sserial_tx_isr, 0, sserial_dev_tx", NULL); return 0;

S5N8946 Release function sserial_release Flush data in write buffer Unregister interrupt void sserial_release ( struct inode *inode, struct file *filp) sserial_dev_t *dev; dev = filp->private_data; while(dev->outwp!= dev->outrp) interruptible_sleep_on(&(dev->outq)); free_irq(5, NULL); free_irq(4, NULL);

S5N8946 Read function int sserial_read(struct inode *inode, struct file *filp, char *buf, int count) sserial_dev_t *dev; char *b2; int i; dev = filp->private_data; b2 = kmalloc(count, GFP_ATOMIC); for(i=0; i<count;) if(dev->inwp!=dev->inrp) b2[i] = dev->inbuf[dev->inrp]; dev->inrp = (dev->inrp+1)%max_size; i++; else interruptible_sleep_on(&(dev->inq)); memcpy_tofs(buf, b2, count); kfree(b2); return count;

S5N8946 Write function(1) int sserial_write(struct inode *inode, struct file *filp, const char *buf, int count) volatile struct uart_regs *uart = (volatile struct uart_regs*)uart_base; sserial_dev_t *dev; char *b2; int i; register unsigned long flags; if(count == 0) return 0; dev = filp->private_data; b2 = kmalloc(count, GFP_ATOMIC); memcpy_fromfs(b2, buf, count);

S5N8946 Write function(2) for(i=0; i<count;) if(((dev->outwp+1)%max_size) == dev->outrp) sserial_tx_go(dev); interruptible_sleep_on(&(dev->outq)); else dev->outbuf[dev->outwp]=b2[i]; dev->outwp=(dev->outwp+1) %MAX_SIZE; i++; kfree(b2); sserial_tx_go(dev); return count;

S5N8946 sserial_tx_go function void sserial_tx_go(sserial_dev_t *dev) volatile struct uart_regs *uart = (volatile struct uart_regs *)UART_BASE; register unsigned long flags; if(dev->buf_empty) save_flags(flags); cli(); dev->buf_empty = 0; if(uart->ustat & UART_TBE) uart->utxbuf = dev->outbuf[dev->outrp]; dev->outrp = (dev->outrp + 1) % MAX_SIZE; restore_flags(flags);

S5N8946 sserial_rx_isr function void sserial_rx_isr(int irq, void *data, structpt_regs *reg) volatile struct uart_regs *uart = (volatile struct uart_regs )UART_BASE; sserial_dev_t *dev; dev = &sserial_dev; if(uart->ustat & UART_RDR) if( ((dev->inwp+1)%max_size) == dev->inrp) else dev->inbuf[dev->inwp] = uart->urxbuf; dev->inwp = (dev->inwp +1) % MAX_SIZE; wake_up_interruptible(&(dev->inq));

S5N8946 sserial_tx_isr function void sserial_tx_isr(int irq, void *data, struct pt_regs *reg) volatile struct uart_regs *uart = (volatile struct uart_regs *)UART_BASE; sserial_dev_t *dev; register unsigned long flags; dev = &sserial_dev; if(dev->outwp == dev->outrp) save_flags(flags); cli(); dev->buf_empty = 1; restore_flags(flags); else if(uart->ustat & UART_TBE) uart->utxbuf = dev->outbuf[dev->outrp]; dev->outrp = (dev->outrp + 1) % MAX_SIZE; wake_up_interruptible(&(dev->outq));

Source file Kernel % cp sserial.c ~/linux/drivers/char/ Kernel vi ~/linux/drivers/char/mem.c int char_dev_init(void) #ifdef CONFIG_SSERIAL sserial_init(); #endif vi ~/linux/drivers/char/makefile ifeq ($(CONFIG_SSERIAL),y) L_OBJS += sserial.o endif vi ~/linux/drivers/char/config.inv bool Sserial device support CONFIG_SSERIAL

Module Module init_module(void) sserial_init(); cleanup_module(void) sserial_release ();

SA1110 Source (include/asm/arch/sa-1100.h) #define _UTCR0(Nb) REG(0x80010000 + ((Nb) -1)*0x00020000) /* UART Control Reg. 0 [1..3] */ #define _UTCR1(Nb) REG(0x80010004 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 1 [1..3] */ #define _UTCR2(Nb) REG(0x80010008 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 2 [1..3] */ #define _UTCR3(Nb) REG(0x8001000C + ((Nb) - 1)*0x00020000) /* UART Control Reg. 3 [1..3] */ #define _UTCR4(Nb) REG(0x80010010 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 4 [2] */ #define _UTDR(Nb) REG(0x80010014 + ((Nb) - 1)*0x00020000) /* UART Data Reg. [1..3] */ #define _UTSR0(Nb) REG(0x8001001C + ((Nb) - 1)*0x00020000) /* UART Status Reg. 0 [1..3] */ #define _UTSR1(Nb) REG(0x80010020 + ((Nb) - 1)*0x00020000) /* UART Status Reg. 1 [1..3] */ #define Ser1UTCR0 _UTCR0 (1) /* Ser. port 1 UART Control Reg. 0 */ #define Ser1UTCR1 _UTCR1 (1) /* Ser. port 1 UART Control Reg. 1 */ #define Ser1UTCR2 _UTCR2 (1) /* Ser. port 1 UART Control Reg. 2 */ #define Ser1UTCR3 _UTCR3 (1) /* Ser. port 1 UART Control Reg. 3 */ #define Ser1UTDR _UTDR (1) /* Ser. port 1 UART Data Reg. */ #define Ser1UTSR0 _UTSR0 (1) /* Ser. port 1 UART Status Reg. 0 */ #define Ser1UTSR1 _UTSR1 (1) /* Ser. port 1 UART Status Reg. 1 */ #define Ser2UTCR0 _UTCR0 (2) /* Ser. port 2 UART Control Reg. 0 */ #define Ser2UTCR1 _UTCR1 (2) /* Ser. port 2 UART Control Reg. 1 */ #define Ser2UTCR2 _UTCR2 (2) /* Ser. port 2 UART Control Reg. 2 */ #define Ser2UTCR3 _UTCR3 (2) /* Ser. port 2 UART Control Reg. 3 */ #define Ser2UTCR4 _UTCR4 (2) /* Ser. port 2 UART Control Reg. 4 */ #define Ser2UTDR _UTDR (2) /* Ser. port 2 UART Data Reg. */ #define Ser2UTSR0 _UTSR0 (2) /* Ser. port 2 UART Status Reg. 0 */ #define Ser2UTSR1 _UTSR1 (2) /* Ser. port 2 UART Status Reg. 1 */......

SA1110 Data Structure struct uart_port u_int iobase; /* in/out[bwl] */ void *membase; /* read/write[bwl] */ u_int irq; u_int uartclk; u_char fifosize; /* tx fifo size */ u_char x_char; u_char regshift ; /* reg offset shift */ u_char iotype; /* io access style */ u_char hub6; u_char unused[7]; u_int read_status_mask; u_int ignore_status_mask; u_int flags; u_int type; /* port type */ struct uart_ops *ops; struct uart_icount icount; u_int line; u_long mapbase; /* for ioremap */ ; struct uart_info spinlock_t lock; struct uart_port *port; struct uart_ops *ops; struct uart_state *state; struct tty_struct *tty; struct circ_buf xmit ; u_int flags; u_int event; u_int timeout; u_int mctrl; u_int driver_priv; int blocked_open; pid_t session; pid_t pgrp; struct tasklet_struct tlet; wait_queue_head_t open_wait; wait_queue_head_t close_wait; wait_queue_head_t delta_msr_wait ; struct uart_info *next_info; ;

SA1110 Data Structure struct uart_ops u_int (*tx_empty)(struct uart_port *); void (*set_mctrl)(struct uart_port *, u_int mctrl); u_int (*get_mctrl)(struct uart_port *); void (*stop_tx)(struct uart_port *, u_int from_tty); void (*start_tx)(struct uart_port *, u_int nonempty, u_int from_tty); void (*stop_rx)(struct uart_port *); void (*enable_ms)(struct uart_port *); void (*break_ctl)(struct uart_port *, int ctl); int (*startup)(struct uart_port *, struct uart_info *); void (*shutdown)(struct uart_port *, struct uart_info *); void (*change_speed)(struct uart_port *, u_int cflag, u_int iflag, u_int quot); ; void (*pm)(struct uart_port *, u_int state, u_int oldstate); int (*set_wake)(struct uart_port *, u_int state); const char *(*type)(struct uart_port *); void (*release_port)(struct uart_port *); int (*request_port)(struct uart_port *); void (*config_port)(struct uart_port *, int); int (*verify_port)(struct uart_port *, struct serial_struct *); int (*ioctl)(struct uart_port *, u_int, u_long); struct uart_driver struct module *owner; int normal_major; const char *normal_name; struct tty_driver *normal_driver; int callout_major; const char *callout_name; struct tty_driver *callout_driver; struct tty_struct **table; struct termios **termios; struct termios **termios_locked; int minor; int nr; struct uart_state *state; /* driver should pass NULL */ struct uart_port *port; /* array of port information */ struct console *cons; ; struct termios tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ tcflag_t c_cflag; /* control mode flags */ tcflag_t c_lflag; /* local mode flags */ cc_t c_line; /* line discipline */ cc_t c_cc[nccs]; /* control characters */ speed_t c_ispeed; /* input speed */ speed_t c_ospeed; /* output speed */ ;

serial_sa1100.c Driver Initialization static struct uart_driver sa1100_reg = ; owner: normal_major: normal_name: callout_name:"cusa", normal_driver: callout_major: callout_driver: table: termios: termios_locked: minor: nr: port: THIS_MODULE, sa1100_table, sa1100_termios, MINOR_START, NR_PORTS, sa1100_ports, SERIAL_SA1100_MAJOR, "test", &normal, CALLOUT_SA1100_MAJOR, &callout, sa1100_termios_locked, static int init sa1100_serial_init(void) sa1100_init_ports(); return uart_register_driver(&sa1100_reg); static struct uart_ops sa1100_pops = tx_empty: sa1100_tx_empty, set_mctrl: sa1100_set_mctrl, get_mctrl: sa1100_get_mctrl, stop_tx: sa1100_stop_tx, start_tx: sa1100_start_tx, stop_rx: sa1100_stop_rx, enable_ms: sa1100_enable_ms, break_ctl: sa1100_break_ctl, startup: sa1100_startup, shutdown: sa1100_shutdown, change_speed: sa1100_change_speed, type: sa1100_type, release_port: sa1100_release_port, request_port: sa1100_request_port, config_port: sa1100_config_port, verify_port: sa1100_verify_port, ;

serial_sa1100.c Driver Initialization static void sa1100_init_ports(void) static int first = 1; int i; if (!first) return; first = 0; for (i = 0; i < NR_PORTS; i++) sa1100_ports[i].uartclk = 3686400; sa1100_ports[i].ops sa1100_ports[i].fifosize = 8; = &sa1100_pops; sa1100_register_uart(0,1); // Ser1SDCR0 = SDCR0_UART; //1 UART Ser2UTCR4 = 0; //2 Ser2HSCR0 = 0; void init sa1100_register_uart(int idx, int port) if (idx >= NR_PORTS) printk(kern_err FUNCTION ": bad index number %d n", idx); return; sa1100_ports[idx].membase = (void *)&Ser1UTCR0; //UART 1 sa1100_ports[idx].mapbase = _Ser1UTCR0; sa1100_ports[idx].irq = IRQ_Ser1UART; sa1100_ports[idx].iotype = SERIAL_IO_MEM; sa1100_ports[idx].flags = ASYNC_BOOT_AUTOCONF; void init sa1100_register_uart_fns(struct sa1100_port_fns *fns) if (fns->enable_ms) sa1100_pops.enable_ms = fns->enable_ms; if (fns->get_mctrl) sa1100_pops.get_mctrl = fns->get_mctrl; if (fns->set_mctrl) sa1100_pops.set_mctrl = fns->set_mctrl; sa1100_open = fns->open; sa1100_close = fns->close; sa1100_pops.pm = fns->pm; sa1100_pops.set_wake = fns->set_wake;

serial_sa1100.c Port Verification function static int sa1100_verify_port(struct uart_port *port, struct serial_struct *ser) int ret = 0; if (ser->type!= PORT_UNKNOWN && ser->type!= PORT_SA1100) ret = -EINVAL; if (port->irq!= ser->irq) ret = -EINVAL; if (ser->io_type!= SERIAL_IO_MEM) ret = -EINVAL; if (port->uartclk / 16!= ser->baud_base) ret = -EINVAL; if ((void *)port->mapbase!= ser->iomem_base) ret = -EINVAL; if (port->iobase!= ser->port) ret = -EINVAL; if (ser->hub6!= 0) ret = -EINVAL; return ret;

serial_sa1100.c startup function static int sa1100_startup(struct uart_port*port, struct uart_info *info) int retval; retval = request_irq(port->irq, sa1100_int, 0, "serial_test", info); // irq=15, name:serial_test if (retval) return retval; if (sa1100_open) retval = sa1100_open(port, info); if (retval) free_irq(port->irq, info); return retval; /* * Finally, clear and enable interrupts */ UART_PUT_UTSR0(port, -1); UART_PUT_UTCR3(port, UTCR3_RXE UTCR3_TXE UTCR3_RIE); return 0;

serial_sa1100.c Interrupt Service Routine static void sa1100_int(int irq, void *dev_id, struct pt_regs *regs) struct uart_info *info = dev_id; struct uart_port*port = info->port; unsigned int status, pass_counter = 0; status = UART_GET_UTSR0(port); status &= (SM_TO_UTSR0(port->read_status_mask) ~UTSR0_TFS); do if (status & (UTSR0_RFS UTSR0_RID)) /* Clear the receiver idle bit, if set */ if (status & UTSR0_RID) UART_PUT_UTSR0(port, UTSR0_RID); sa1100_rx_chars(info, regs); /* Clear the relevent break bits */ if (status & (UTSR0_RBB UTSR0_REB)) UART_PUT_UTSR0(port, status & (UTSR0_RBB UTSR0_REB)); if (status & UTSR0_RBB) port->icount.brk++; if (status & UTSR0_TFS) sa1100_tx_chars(info); if (pass_counter++ > SA1100_ISR_PASS_LIMIT) break; status = UART_GET_UTSR0(port); status &= (SM_TO_UTSR0(port->read_status_mask) ~UTSR0_TFS); while (status & (UTSR0_TFS UTSR0_RFS UTSR0_RID));

serial_sa1100.c sa1100_start_tx, sa1100_stop_tx function static void sa1100_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty) if (nonempty) unsigned long flags; u32 utcr3; local_irq_save(flags); utcr3 = UART_GET_UTCR3(port); port->read_status_mask = UTSR0_TO_SM(UTSR0_TFS); UART_PUT_UTCR3(port, utcr3 UTCR3_TIE); local_irq_restore(flags); static void sa1100_stop_tx(struct uart_port*port, u_int from_tty) u32 utcr3 = UART_GET_UTCR3(port); UART_PUT_UTCR3(port, utcr3 & ~UTCR3_TIE); port->read_status_mask &= ~UTSR0_TO_SM(UTSR0_TFS);

serial_sa1100.c sa1100_tx_chars function static void sa1100_tx_chars(struct uart_info *info) struct uart_port*port = info->port; if (port->x_char) UART_PUT_CHAR(port, port->x_char); port->icount.tx++; port->x_char = 0; return; if (info->xmit.head == info->xmit.tail info->tty->stopped info->tty->hw_stopped) sa1100_stop_tx(info->port, 0); return; /* * Tried using FIFO (not checking TNF) for fifo fill: * still had the '4 bytes repeated' problem. */ while (UART_GET_UTSR1(port) & UTSR1_TNF) UART_PUT_CHAR(port, info->xmit.buf[info->xmit.tail]); info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; if (info->xmit.head == info->xmit.tail) break; if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) < WAKEUP_CHARS) uart_event(info, EVT_WRITE_WAKEUP); if (info->xmit.head == info->xmit.tail) sa1100_stop_tx(info->port, 0);

serial_sa1100.c sa1100_rx_chars function(1) sa1100_rx_chars(struct uart_info *info, struct pt_regs *regs) struct tty_struct *tty = info->tty; unsigned int status, ch, flg, ignored = 0; struct uart_port*port = info->port; status = UTSR1_TO_SM(UART_GET_UTSR1(port)) UTSR0_TO_SM(UART_GET_UTSR0(port)); while (status & UTSR1_TO_SM(UTSR1_RNE)) ch = UART_GET_CHAR(port); if (tty->flip.count >= TTY_FLIPBUF_SIZE) goto ignore_char; port->icount.rx++; flg = TTY_NORMAL; if (status & UTSR1_TO_SM(UTSR1_PRE UTSR1_FRE UTSR1_ROR)) goto handle_error; if (uart_handle_sysrq_char(info, ch, regs)) goto ignore_char; error_return: *tty->flip.flag_buf_ptr++ = flg; *tty->flip.char_buf_ptr++ = ch; tty->flip.count++; ignore_char: status = UTSR1_TO_SM(UART_GET_UTSR1(port)) UTSR0_TO_SM(UART_GET_UTSR0(port)); out: tty_flip_buffer_push(tty); return; handle_error: if (status & UTSR1_TO_SM(UTSR1_PRE)) port->icount.parity++; else if (status & UTSR1_TO_SM(UTSR1_FRE)) port->icount.frame++; if (status & UTSR1_TO_SM(UTSR1_ROR)) port->icount.overrun++; if (status & port->ignore_status_mask) if (++ignored > 100) goto out; goto ignore_char;

serial_sa1110.c sa1100_rx_chars function(2) status &= port->read_status_mask; if (status & UTSR1_TO_SM(UTSR1_PRE)) flg = TTY_PARITY; else if (status & UTSR1_TO_SM(UTSR1_FRE)) flg = TTY_FRAME; if (status & UTSR1_TO_SM(UTSR1_ROR)) /* * overrun does *not* affect the character * we read from the FIFO */ *tty->flip.flag_buf_ptr++ = flg; *tty->flip.char_buf_ptr++ = ch; tty->flip.count++; if (tty->flip.count >= TTY_FLIPBUF_SIZE) goto ignore_char; ch = 0; flg = TTY_OVERRUN; goto error_return;

serial_sa1100.c sa1100_stop_rx, sa1100_serial_exit function static void sa1100_stop_rx(struct uart_port *port) u32 utcr3 = UART_GET_UTCR3(port); UART_PUT_UTCR3(port, utcr3 & ~UTCR3_RIE); static void exit sa1100_serial_exit(void) uart_unregister_driver(&sa1100_reg);

Serial_test_host.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <termios.h> #include <sys/ioctl.h> int main( int argc, char **argv ) int sd; struct termios oldtio,newtio; char Buff[255]; int DataCount ; int ending; sd = open( "/dev/ttys0", O_RDWR O_NOCTTY ); if(sd < 0 ) printf( "Serial Open Fail [/dev/ttys00] r n " ); exit(0); tcgetattr(sd, &oldtio ); memset( &newtio, 0, sizeof(newtio) ); cfsetispeed(&newtio,b115200); cfsetospeed(&newtio,b115200); newtio.c_cflag &= ~PARENB; newtio.c_cflag &= ~CSTOPB; newtio.c_cflag &= ~CSIZE ; newtio.c_cflag = CS8 CLOCAL CREAD ; newtio.c_iflag = IGNPAR; newtio.c_oflag &= ~OPOST; newtio.c_lflag = 0; newtio.c_cc[vtime] = 30; newtio.c_cc[vmin] = 0; tcflush(sd, TCIFLUSH ); tcsetattr(sd, TCSANOW, &newtio ); ending = 0; while(!ending) scanf("%s",buff); write(sd, Buff, strlen( Buff ) ); tcsetattr(sd, TCSANOW, &oldtio ); close(sd); return 0;

Serial_test_SA1110.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <fcntl.h> #include <termios.h> #include <sys/ioctl.h> #define BAUDRATE B115200 //termios.h int main( int argc, char **argv ) int sd; struct termios oldtio,newtio; char Buff[255]; int DataCount ; int ending; sd = open( "/dev/test0", O_RDWR O_NOCTTY ); if(sd < 0 ) // printf( "Serial Open Fail [/dev/test0] r n " ); exit(0); tcgetattr( sd, &oldtio ); memset( &newtio, 0, sizeof(newtio) ); //newtio cfsetispeed(&newtio, BAUDRATE); // cfsetospeed(&newtio, BAUDRATE); // newtio.c_cflag &= ~PARENB; // enable newtio.c_cflag &= ~CSIZE ; //mask character sizebit newtio.c_cflag &= ~CSTOPB; //stop bit enable newtio.c_cflag = CS8 CLOCAL CREAD ; //8N1,, newtio.c_iflag = IGNPAR; //parity error newtio.c_oflag &= ~OPOST; // newtio.c_lflag = 0; //canonical newtio.c_cc[vtime] = 30; //time_out : TIME*0.1 newtio.c_cc[vmin] = 0; // tcflush( sd, TCIFLUSH ); // tcsetattr( sd, TCSANOW, &newtio ); // ending = 0; while(!ending) DataCount = read( sd, Buff, 255 ); if(datacount < 0 ) printf( "Read Error n" ); break; if(datacount!= 0 ) Buff[DataCount] = 0; printf( "Read Data [%s] n", Buff ); if( Buff[0] == 'x' ) ending = 1; tcsetattr( sd, TCSANOW, &oldtio ); close( sd ); return 0; //datacount //x // //

Serial_test_host.c gcc Serial_test_SA1110.c arm-linux-gcc Serial_test_SA1110 Serial_test_SA1110 Serial_test_host Host PC