2014-01-05 00:56:51 +01:00
|
|
|
/*
|
|
|
|
* 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 <max.salov@gmail.com>, Ian Martin <martini@redwirellc.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "rl78.h" /* for f_CLK */
|
|
|
|
#include "sfrs.h"
|
|
|
|
#include "sfrs-ext.h"
|
|
|
|
|
2012-10-03 20:37:11 +02:00
|
|
|
#include "uart0.h"
|
2014-01-05 00:56:51 +01:00
|
|
|
|
|
|
|
#define DESIRED_BAUDRATE 9600
|
|
|
|
#define FUDGE_FACTOR 4
|
|
|
|
|
|
|
|
/* Note that only 9600 and 115200 bps were tested: */
|
|
|
|
#define PRESCALE_THRESH ((9600 + 115200) / 2)
|
|
|
|
#define PRS_VALUE ((DESIRED_BAUDRATE < PRESCALE_THRESH) ? 4 : 0)
|
|
|
|
#define f_MCK (f_CLK / (1 << PRS_VALUE) / FUDGE_FACTOR)
|
|
|
|
#define SDR_VALUE ((f_MCK / DESIRED_BAUDRATE) >> 1)
|
2012-10-03 20:37:11 +02:00
|
|
|
|
2014-01-04 23:27:24 +01:00
|
|
|
void
|
|
|
|
uart0_init(void)
|
2012-10-03 20:37:11 +02:00
|
|
|
{
|
2014-01-04 23:27:24 +01:00
|
|
|
/* Reference R01AN0459EJ0100 or hardware manual for details */
|
2014-01-05 00:56:51 +01:00
|
|
|
PIOR = 0U; /* Disable IO redirection */
|
|
|
|
PM1 |= 0x06U; /* Set P11 and P12 as inputs */
|
2014-01-04 23:27:24 +01:00
|
|
|
SAU0EN = 1; /* Supply clock to serial array unit 0 */
|
2014-01-05 00:56:51 +01:00
|
|
|
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 */
|
2014-01-04 23:27:24 +01:00
|
|
|
/* 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) */
|
2014-01-05 00:56:51 +01:00
|
|
|
SMR00 = 0x0023U; /* Operation clock : CK00,
|
2012-10-03 20:37:11 +02:00
|
|
|
Transfer clock : division of CK00
|
|
|
|
Start trigger : software
|
|
|
|
Detect falling edge as start bit
|
|
|
|
Operation mode : UART
|
|
|
|
Interrupt source : buffer empty
|
2014-01-05 00:56:51 +01:00
|
|
|
*/
|
|
|
|
SCR00 = 0x8097U; /* Transmission only
|
2012-10-03 20:37:11 +02:00
|
|
|
Reception error interrupt masked
|
|
|
|
Phase clock : type 1
|
|
|
|
No parity
|
|
|
|
LSB first
|
|
|
|
1 stop bit
|
|
|
|
8-bit data length
|
2014-01-05 00:56:51 +01:00
|
|
|
*/
|
|
|
|
SDR00 = SDR_VALUE << 9;
|
2014-01-04 23:27:24 +01:00
|
|
|
/* Setup operation mode for receiver (channel 1) */
|
2014-01-05 00:56:51 +01:00
|
|
|
NFEN0 |= 1; /* Enable noise filter on RxD0 pin */
|
|
|
|
SIR01 = 0x0007U; /* Clear error flags */
|
|
|
|
SMR01 = 0x0122U; /* Operation clock : CK00
|
2012-10-03 20:37:11 +02:00
|
|
|
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
|
2014-01-05 00:56:51 +01:00
|
|
|
*/
|
|
|
|
SCR01 = 0x4097U; /* Reception only
|
2012-10-03 20:37:11 +02:00
|
|
|
Reception error interrupt masked
|
|
|
|
Phase clock : type 1
|
|
|
|
No parity
|
|
|
|
LSB first
|
|
|
|
1 stop bit
|
|
|
|
8-bit data length
|
2014-01-05 00:56:51 +01:00
|
|
|
*/
|
|
|
|
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) */
|
2014-01-04 23:27:24 +01:00
|
|
|
STIF0 = 1; /* Set buffer empty interrupt request flag */
|
2012-10-03 20:37:11 +02:00
|
|
|
}
|
2014-01-05 00:56:51 +01:00
|
|
|
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;
|
|
|
|
}
|
2014-01-04 23:27:24 +01:00
|
|
|
int
|
2014-01-05 00:56:51 +01:00
|
|
|
uart0_puts(const char *s)
|
2012-10-03 20:37:11 +02:00
|
|
|
{
|
2014-01-04 23:27:24 +01:00
|
|
|
int len = 0;
|
2014-01-05 00:56:51 +01:00
|
|
|
SMR00 |= 0x0001U; /* Set buffer empty interrupt */
|
2014-01-04 23:27:24 +01:00
|
|
|
while('\0' != *s) {
|
2014-01-05 00:56:51 +01:00
|
|
|
uart0_putchar(*s);
|
|
|
|
s++;
|
2014-01-04 23:27:24 +01:00
|
|
|
++len;
|
|
|
|
}
|
|
|
|
#if 0
|
|
|
|
while(0 == STIF0) ;
|
|
|
|
STIF0 = 0;
|
|
|
|
SDR00.sdr00 = '\r';
|
2012-10-03 20:37:11 +02:00
|
|
|
#endif
|
2014-01-05 00:56:51 +01:00
|
|
|
SMR00 &= ~0x0001U;
|
|
|
|
uart0_putchar('\n');
|
2012-10-03 20:37:11 +02:00
|
|
|
#if 0
|
2014-01-04 23:27:24 +01:00
|
|
|
while(0 != SSR00.BIT.bit6) ; /* Wait until TSF00 == 0 */
|
2012-10-03 20:37:11 +02:00
|
|
|
#endif
|
2014-01-04 23:27:24 +01:00
|
|
|
return len;
|
2012-10-03 20:37:11 +02:00
|
|
|
}
|