X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=target%2Fserial%2Fserial.c;fp=target%2Fserial%2Fserial.c;h=63f6c6de0c32ec477249f2cfb5db3c0995f509a6;hp=0000000000000000000000000000000000000000;hb=17d2432a8b9c15963cd3b821f025ad33972ef477;hpb=210dbaa23cdacf3a6f2d6e23493e96ee2ac9bca7 diff --git a/target/serial/serial.c b/target/serial/serial.c new file mode 100644 index 00000000..63f6c6de --- /dev/null +++ b/target/serial/serial.c @@ -0,0 +1,270 @@ +/* + * Copyright © 2008 Keith Packard + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include + +/* + * Validate UART1 + */ + +sfr at 0x80 P0; +sfr at 0x90 P1; +sfr at 0xA0 P2; +sfr at 0xC6 CLKCON; +sfr at 0xbe SLEEP; + +# define SLEEP_USB_EN (1 << 7) +# define SLEEP_XOSC_STB (1 << 6) + +sfr at 0xF1 PERCFG; +#define PERCFG_T1CFG_ALT_1 (0 << 6) +#define PERCFG_T1CFG_ALT_2 (1 << 6) + +#define PERCFG_T3CFG_ALT_1 (0 << 5) +#define PERCFG_T3CFG_ALT_2 (1 << 5) + +#define PERCFG_T4CFG_ALT_1 (0 << 4) +#define PERCFG_T4CFG_ALT_2 (1 << 4) + +#define PERCFG_U1CFG_ALT_1 (0 << 1) +#define PERCFG_U1CFG_ALT_2 (1 << 1) + +#define PERCFG_U0CFG_ALT_1 (0 << 0) +#define PERCFG_U0CFG_ALT_2 (1 << 0) + +sfr at 0xF2 ADCCFG; +sfr at 0xF3 P0SEL; +sfr at 0xF4 P1SEL; +sfr at 0xF5 P2SEL; + +sfr at 0xFD P0DIR; +sfr at 0xFE P1DIR; +sfr at 0xFF P2DIR; +sfr at 0x8F P0INP; +sfr at 0xF6 P1INP; +sfr at 0xF7 P2INP; + +sfr at 0x89 P0IFG; +sfr at 0x8A P1IFG; +sfr at 0x8B P2IFG; + +sbit at 0x90 P1_0; +sbit at 0x91 P1_1; +sbit at 0x92 P1_2; +sbit at 0x93 P1_3; +sbit at 0x94 P1_4; +sbit at 0x95 P1_5; +sbit at 0x96 P1_6; +sbit at 0x97 P1_7; + +/* + * UART registers + */ + +sfr at 0x86 U0CSR; +sfr at 0xF8 U1CSR; + +/* + * IRCON2 + */ +sfr at 0xE8 IRCON2; /* CPU Interrupt Flag 5 */ + +sbit at 0xE8 USBIF; /* USB interrupt flag (shared with Port2) */ +sbit at 0xE8 P2IF; /* Port2 interrupt flag (shared with USB) */ +sbit at 0xE9 UTX0IF; /* USART0 TX interrupt flag */ +sbit at 0xEA UTX1IF; /* USART1 TX interrupt flag (shared with I2S TX) */ +sbit at 0xEA I2STXIF; /* I2S TX interrupt flag (shared with USART1 TX) */ +sbit at 0xEB P1IF; /* Port1 interrupt flag */ +sbit at 0xEC WDTIF; /* Watchdog timer interrupt flag */ + +# define UxCSR_MODE_UART (1 << 7) +# define UxCSR_MODE_SPI (0 << 7) +# define UxCSR_RE (1 << 6) +# define UxCSR_SLAVE (1 << 5) +# define UxCSR_MASTER (0 << 5) +# define UxCSR_FE (1 << 4) +# define UxCSR_ERR (1 << 3) +# define UxCSR_RX_BYTE (1 << 2) +# define UxCSR_TX_BYTE (1 << 1) +# define UxCSR_ACTIVE (1 << 0) + +sfr at 0xc4 U0UCR; +sfr at 0xfb U1UCR; + +# define UxUCR_FLUSH (1 << 7) +# define UxUCR_FLOW_DISABLE (0 << 6) +# define UxUCR_FLOW_ENABLE (1 << 6) +# define UxUCR_D9_EVEN_PARITY (0 << 5) +# define UxUCR_D9_ODD_PARITY (1 << 5) +# define UxUCR_BIT9_8_BITS (0 << 4) +# define UxUCR_BIT9_9_BITS (1 << 4) +# define UxUCR_PARITY_DISABLE (0 << 3) +# define UxUCR_PARITY_ENABLE (1 << 3) +# define UxUCR_SPB_1_STOP_BIT (0 << 2) +# define UxUCR_SPB_2_STOP_BITS (1 << 2) +# define UxUCR_STOP_LOW (0 << 1) +# define UxUCR_STOP_HIGH (1 << 1) +# define UxUCR_START_LOW (0 << 0) +# define UxUCR_START_HIGH (1 << 0) + +sfr at 0xc5 U0GCR; +sfr at 0xfc U1GCR; + +# define UxGCR_CPOL_NEGATIVE (0 << 7) +# define UxGCR_CPOL_POSITIVE (1 << 7) +# define UxGCR_CPHA_FIRST_EDGE (0 << 6) +# define UxGCR_CPHA_SECOND_EDGE (1 << 6) +# define UxGCR_ORDER_LSB (0 << 5) +# define UxGCR_ORDER_MSB (1 << 5) +# define UxGCR_BAUD_E_MASK (0x1f) +# define UxGCR_BAUD_E_SHIFT 0 + +sfr at 0xc1 U0DBUF; +sfr at 0xf9 U1DBUF; +sfr at 0xc2 U0BAUD; +sfr at 0xfa U1BAUD; + +#define MOSI P1_5 +#define MISO P1_4 +#define SCK P1_3 +#define CS P1_2 + +#define DEBUG P1_1 + +#define USART 1 + +#define nop() _asm nop _endasm; + +void +delay (unsigned char n) +{ + unsigned char i = 0; + unsigned char j = 0; + + n++; + while (--n != 0) + while (--i != 0) + while (--j != 0) + nop(); +} + +/* + * This version uses the USART in SPI mode + */ +void +usart_init(void) +{ + P1DIR |= (1 << 2); + /* + * Configure the peripheral pin choices + * for both of the serial ports + * + * Note that telemetrum will use U1CFG_ALT_2 + * but that overlaps with SPI ALT_2, so until + * we can test that this works, we'll set this + * to ALT_1 + */ + PERCFG = (PERCFG_U1CFG_ALT_2 | + PERCFG_U0CFG_ALT_1); + + /* + * Make the UART pins controlled by the UART + * hardware + */ + P1SEL |= ((1 << 6) | (1 << 7)); + + /* + * UART mode with the receiver enabled + */ + U1CSR = (UxCSR_MODE_UART | + UxCSR_RE); + /* + * Pick a 38.4kbaud rate + */ + U1BAUD = 163; + U1GCR = 10 << UxGCR_BAUD_E_SHIFT; /* 38400 */ +// U1GCR = 3 << UxGCR_BAUD_E_SHIFT; /* 300 */ + /* + * Reasonable serial parameters + */ + U1UCR = (UxUCR_FLUSH | + UxUCR_FLOW_DISABLE | + UxUCR_D9_ODD_PARITY | + UxUCR_BIT9_8_BITS | + UxUCR_PARITY_DISABLE | + UxUCR_SPB_2_STOP_BITS | + UxUCR_STOP_HIGH | + UxUCR_START_LOW); +} + +void +usart_out_byte(uint8_t byte) +{ + U1DBUF = byte; + while (!UTX1IF) + ; + UTX1IF = 0; +} + +void +usart_out_string(uint8_t *string) +{ + uint8_t b; + + while (b = *string++) + usart_out_byte(b); +} + +uint8_t +usart_in_byte(void) +{ + uint8_t b; + while ((U1CSR & UxCSR_RX_BYTE) == 0) + ; + b = U1DBUF; + U1CSR &= ~UxCSR_RX_BYTE; + return b; +} + +void +debug_byte(uint8_t byte) +{ + uint8_t s; + + for (s = 0; s < 8; s++) { + DEBUG = byte & 1; + delay(5); + byte >>= 1; + } +} + +main () +{ + P1DIR |= 2; + CLKCON = 0; + while (!(SLEEP & SLEEP_XOSC_STB)) + ; + + usart_init(); + + for (;;) { + usart_out_string("hello world\r\n"); + debug_byte(usart_in_byte()); + } + +}