m3dev

cortex m3 debug tools -- superceded by mdebug
git clone http://frotz.net/git/m3dev.git
Log | Files | Refs | README | LICENSE

serial.c (2394B)


      1 /* serial.c
      2  *
      3  * Copyright 2011 Brian Swetland <swetland@frotz.net>
      4  * 
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #include <fw/types.h>
     19 #include <fw/io.h>
     20 #include <fw/lib.h>
     21 
     22 #include <arch/hardware.h>
     23 
     24 static void (*serial_async_cb)(char c);
     25 
     26 /* only works for multiples of 12MHz and 115.2kbaud right now */
     27 void serial_init(unsigned sysclk_mhz, unsigned baud) {
     28 
     29 	if (sysclk_mhz % 12000000)
     30 		return;
     31 	if (baud != 115200)
     32 		return;
     33 
     34 /* XXX: this is board specific */
     35 	writel(IOCON_FUNC_1 | IOCON_DIGITAL, IOCON_PIO1_6); /* RXD */
     36 	writel(IOCON_FUNC_1 | IOCON_DIGITAL, IOCON_PIO1_7); /* TXD */
     37 
     38 	writel(sysclk_mhz / 12000000, SYS_DIV_UART); /* SYS / n -> 12MHz */
     39 	writel(readl(SYS_CLK_CTRL) | SYS_CLK_UART, SYS_CLK_CTRL);
     40 
     41 	writel(0x80, 0x4000800C); /* DLAB=1 */
     42 	writel(0x04, 0x40008000); /* DLL=4 */
     43 	writel(0x00, 0x40008004); /* DLM=0 */
     44 	writel(0x85, 0x40008028); /* DIVADDVAL=5, MULVAL=8 */
     45 	writel(0x03, 0x4000800C); /* DLAB=0, 8N1 */
     46 	writel(0x00, 0x40008010); /* no flow control */
     47 	writel(1, 0x40008008); /* enable FIFO */
     48 	writel(1, 0x40008008); /* enable FIFO */
     49 }
     50 
     51 void serial_putc(unsigned c) {
     52 	/* wait until xmit holding register is empty */
     53 	while (!(readl(0x40008014) & (1 << 5))) ;
     54 	writel(c, 0x40008000);
     55 }
     56 
     57 void serial_start_async_rx(void (*async_cb)(char c))
     58 {
     59 	serial_async_cb = async_cb;
     60 
     61 	writel((1<<2) | (1<<0), 0x40008004); /* IER=1, receive data avail */
     62 }
     63 
     64 void handle_irq_uart(void)
     65 {
     66 	do {
     67 		u32 lsr = readl(0x40008014);
     68 		if (lsr & (1<<1)) {
     69 			serial_async_cb('O');
     70 		}
     71 		if (lsr & (1<<2)) {
     72 			serial_async_cb('P');
     73 		}
     74 		if (lsr & (1<<3)) {
     75 			serial_async_cb('F');
     76 		}
     77 		if (lsr & (1<<4)) {
     78 			serial_async_cb('B');
     79 		}
     80 		if (lsr & (1<<7)) {
     81 			serial_async_cb('E');
     82 		}
     83 		if (lsr & (1<<0)) {
     84 			char c = readl(0x40008000);
     85 			if (serial_async_cb)
     86 				serial_async_cb(c);
     87 			continue; /* we got a char, try again */
     88 		}
     89 	} while (0);
     90 }
     91