/* * Copyright (c) 2014, Analog Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * \author Maxim Salov , Ian Martin */ #include "rl78.h" /* for f_CLK */ #include "sfrs.h" #include "sfrs-ext.h" #include "uart0.h" #define DESIRED_BAUDRATE 38400 /* Note that only 9600, 38400, and 115200 bps were tested. */ #define PRESCALE_THRESH ((38400 + 115200) / 2) #define PRS_VALUE ((DESIRED_BAUDRATE < PRESCALE_THRESH) ? 4 : 0) #define f_MCK (f_CLK / (1 << PRS_VALUE)) #define SDR_VALUE (f_MCK / DESIRED_BAUDRATE / 2 - 1) void uart0_init(void) { /* Reference R01AN0459EJ0100 or hardware manual for details */ PIOR = 0U; /* Disable IO redirection */ PM1 |= 0x06U; /* Set P11 and P12 as inputs */ SAU0EN = 1; /* Supply clock to serial array unit 0 */ SPS0 = (PRS_VALUE << 4) | PRS_VALUE; /* Set input clock (CK00 and CK01) to fclk/16 = 2MHz */ ST0 = 0x03U; /* Stop operation of channel 0 and 1 */ /* Setup interrupts (disable) */ STMK0 = 1; /* Disable INTST0 interrupt */ STIF0 = 0; /* Clear INTST0 interrupt request flag */ STPR10 = 1; /* Set INTST0 priority: lowest */ STPR00 = 1; SRMK0 = 1; /* Disable INTSR0 interrupt */ SRIF0 = 0; /* Clear INTSR0 interrupt request flag */ SRPR10 = 1; /* Set INTSR0 priority: lowest */ SRPR00 = 1; SREMK0 = 1; /* Disable INTSRE0 interrupt */ SREIF0 = 0; /* Clear INTSRE0 interrupt request flag */ SREPR10 = 1; /* Set INTSRE0 priority: lowest */ SREPR00 = 1; /* Setup operation mode for transmitter (channel 0) */ SMR00 = 0x0023U; /* Operation clock : CK00, Transfer clock : division of CK00 Start trigger : software Detect falling edge as start bit Operation mode : UART Interrupt source : buffer empty */ SCR00 = 0x8097U; /* Transmission only Reception error interrupt masked Phase clock : type 1 No parity LSB first 1 stop bit 8-bit data length */ SDR00 = SDR_VALUE << 9; /* Setup operation mode for receiver (channel 1) */ NFEN0 |= 1; /* Enable noise filter on RxD0 pin */ SIR01 = 0x0007U; /* Clear error flags */ SMR01 = 0x0122U; /* Operation clock : CK00 Transfer clock : division of CK00 Start trigger : valid edge on RxD pin Detect falling edge as start bit Operation mode : UART Interrupt source : transfer end */ SCR01 = 0x4097U; /* Reception only Reception error interrupt masked Phase clock : type 1 No parity LSB first 1 stop bit 8-bit data length */ SDR01 = SDR_VALUE << 9; SO0 |= 1; /* Prepare for use of channel 0 */ SOE0 |= 1; P1 |= (1 << 2); /* Set TxD0 high */ PM1 &= ~(1 << 2); /* Set output mode for TxD0 */ PM1 |= (1 << 1); /* Set input mode for RxD0 */ SS0 |= 0x03U; /* Enable UART0 operation (both channels) */ STIF0 = 1; /* Set buffer empty interrupt request flag */ } void uart0_putchar(int c) { while(0 == STIF0) ; STIF0 = 0; SDR00 = c; } char uart0_getchar(void) { char c; while(!uart0_can_getchar()) ; c = SDR01; SRIF0 = 0; return c; } int uart0_puts(const char *s) { int len = 0; SMR00 |= 0x0001U; /* Set buffer empty interrupt */ while('\0' != *s) { uart0_putchar(*s); s++; ++len; } #if 0 while(0 == STIF0) ; STIF0 = 0; SDR00.sdr00 = '\r'; #endif SMR00 &= ~0x0001U; uart0_putchar('\n'); #if 0 while(0 != SSR00.BIT.bit6) ; /* Wait until TSF00 == 0 */ #endif return len; }