// Copyright 2016 ETH Zurich and University of Bologna. // Copyright and related rights are licensed under the Solderpad Hardware // License, Version 0.51 (the “License”); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law // or agreed to in writing, software, hardware and materials distributed under // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #include "uart.h" #include "utils.h" #include "uart.h" #include "pulpino.h" /** * Setup UART. The UART defaults to 8 bit character mode with 1 stop bit. * * parity Enable/disable parity mode * clk_counter Clock counter value that is used to derive the UART clock. * It has to be in the range of 1..2^16. * There is a prescaler in place that already divides the SoC * clock by 16. Since this is a counter, a value of 1 means that * the SoC clock divided by 16*2 = 32 is used. A value of 31 would mean * that we use the SoC clock divided by 16*32 = 512. */ void uart_set_cfg(int parity, uint16_t clk_counter) { unsigned int i; CGREG |= (1 << CGUART); *(volatile unsigned int*)(UART_REG_LCR) = 0x83; //sets 8N1 and set DLAB to 1 *(volatile unsigned int*)(UART_REG_DLM) = (clk_counter >> 8) & 0xFF; *(volatile unsigned int*)(UART_REG_DLL) = clk_counter & 0xFF; *(volatile unsigned int*)(UART_REG_FCR) = 0xA7; //enables 16byte FIFO and clear FIFOs *(volatile unsigned int*)(UART_REG_LCR) = 0x03; //sets 8N1 and set DLAB to 0 *(volatile unsigned int*)(UART_REG_IER) = ((*(volatile unsigned int*)(UART_REG_IER)) & 0xF0) | 0x02; // set IER (interrupt enable register) on UART } void uart_send(const char* str, unsigned int len) { unsigned int i; while(len > 0) { // process this in batches of 16 bytes to actually use the FIFO in the UART for(i = 0; (i < UART_FIFO_DEPTH) && (len > 0); i++) { // wait until there is space in the fifo while( (*(volatile unsigned int*)(UART_REG_LSR) & 0x20) == 0); // load FIFO *(volatile unsigned int*)(UART_REG_THR) = *str++; len--; } } } char uart_getchar() { while((*((volatile int*)UART_REG_LSR) & 0x1) != 0x1); return *(volatile int*)UART_REG_RBR; } void uart_sendchar(const char c) { // wait until there is space in the fifo while( (*(volatile unsigned int*)(UART_REG_LSR) & 0x20) == 0); // load FIFO *(volatile unsigned int*)(UART_REG_THR) = c; } void uart_wait_tx_done(void) { // wait until there is space in the fifo while( (*(volatile unsigned int*)(UART_REG_LSR) & 0x40) == 0); }