static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode) { unsigned int val; unsigned int ufcr_rfdiv; /* set receiver / transmitter trigger level. * RFDIV is set such way to satisfy requested uartclk value */ val = TXTL<<10 | RXTL; ufcr_rfdiv = (imx_get_perclk1() + sport->port.uartclk / 2) / sport->port.uartclk; if(!ufcr_rfdiv) ufcr_rfdiv = 1; if(ufcr_rfdiv >= 7) ufcr_rfdiv = 6; else ufcr_rfdiv = 6 - ufcr_rfdiv; val |= UFCR_RFDIV & (ufcr_rfdiv << 7); UFCR((u32)sport->port.membase) = val; return 0; }
/* * If the port was already initialised (eg, by a boot loader), * try to determine the current setup. */ static void __init imx_console_get_options(struct imx_port *sport, int *baud, int *parity, int *bits) { if ( UCR1((u32)sport->port.membase) | UCR1_UARTEN ) { /* ok, the port was enabled */ unsigned int ucr2, ubir,ubmr, uartclk; unsigned int baud_raw; unsigned int ucfr_rfdiv; ucr2 = UCR2((u32)sport->port.membase); *parity = 'n'; if (ucr2 & UCR2_PREN) { if (ucr2 & UCR2_PROE) *parity = 'o'; else *parity = 'e'; } if (ucr2 & UCR2_WS) *bits = 8; else *bits = 7; ubir = UBIR((u32)sport->port.membase) & 0xffff; ubmr = UBMR((u32)sport->port.membase) & 0xffff; ucfr_rfdiv = (UFCR((u32)sport->port.membase) & UFCR_RFDIV) >> 7; if (ucfr_rfdiv == 6) ucfr_rfdiv = 7; else ucfr_rfdiv = 6 - ucfr_rfdiv; uartclk = imx_get_perclk1(); uartclk /= ucfr_rfdiv; { /* * The next code provides exact computation of * baud_raw = round(((uartclk/16) * (ubir + 1)) / (ubmr + 1)) * without need of float support or long long division, * which would be required to prevent 32bit arithmetic overflow */ unsigned int mul = ubir + 1; unsigned int div = 16 * (ubmr + 1); unsigned int rem = uartclk % div; baud_raw = (uartclk / div) * mul; baud_raw += (rem * mul + div / 2) / div; *baud = (baud_raw + 50) / 100 * 100; } if(*baud != baud_raw) printk(KERN_INFO "Serial: Console IMX rounded baud rate from %d to %d\n", baud_raw, *baud); }
void HardwareSerial::begin(unsigned int baud) { // for now, do nothing. We will use whatever the ISP had set up. measurePCLK(); #if MCU == MCU_ARM7TDMI //Set up the pins if(port==0) { gpio_set_write(0); gpio_set_read(1); set_pin(0,1); //TX0 set_pin(1,1); //RX0 } else { gpio_set_write(8); gpio_set_read(9); set_pin(8,1); //TX1 set_pin(9,1); //RX1 } #else //This only knows how to set up UART0. IODIR(0)|= (1<<2); //TX set to output IODIR(0)&=~(1<<3); //RX set to input IOCON(0,2)=(0b010 << 0) | //Function TX0 (0b00 << 3) | //No pullup/pulldown (0b0 << 5) | //No hysteresis (0b0 << 6) | //No inversion (0b0 << 9) | //Standard slew (0b0 <<10) ; //Not open-drain IOCON(0,3)=(0b010 << 0) | //Function RX0 (0b00 << 3) | //No pullup/pulldown (0b0 << 5) | //No hysteresis (0b0 << 6) | //No inversion (0b0 << 9) | //Standard slew (0b0 <<10) ; //Not open-drain #endif ULCR(port) = (3 << 0) | //8 data bits (0 << 2) | //1 stop bit (0 << 3) | //No parity (0 << 4) | //I said, no parity! (0 << 6) | //No break transmission (1 << 7); //DLAB = 1 //DLAB - Divisor Latch Access bit. When set, a certain memory address // maps to the divisor latches, which control the baud rate. When // cleared, those same addresses correspond to the processor end // of the FIFOs. In other words, set the DLAB to change the baud // rate, and clear it to use the FIFOs. unsigned int Denom=PCLK/baud; unsigned int UDL=Denom/16; UDLM(port)=(UDL >> 8) & 0xFF; UDLL(port)=(UDL >> 0) & 0xFF; UFDR(port)=0x10; //reset nilpotent value UFCR(port) = (1 << 0) | //FIFOs on (1 << 1) | //Clear rx FIFO (1 << 2) | //Clear tx FIFO (3 << 6); //Rx watermark=14 bytes ULCR(port) = ULCR(port) & ~(1<<7); //Turn of DLAB - FIFOs accessable UIER(port)=0; }
void HardwareSerial::flush(void) {UFCR(port)=((1 << 0) | (1 << 1) | (1 << 2));}; //Enable FIFOs and reset