You are on page 1of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.1

AN014 eCOG1 Using the UART Function in the DUSART


Version 1.6

Contents
1 2 3 Introduction.......................................................................................... 4 Glossary .............................................................................................. 4 Clocks.................................................................................................. 5
3.1 3.2 Clock Sources ........................................................................................... 5 DUSART Clock.......................................................................................... 5 Overview............................................................................................. 5 Clock Selection................................................................................... 5

3.2.1 3.2.2

DUSART Configuration........................................................................ 6
4.1 4.2 Overview.................................................................................................... 6 Registers ................................................................................................... 6 Configuration ...................................................................................... 6 Sample Clock ..................................................................................... 6 Symbol Clock...................................................................................... 6 Baud Rates ......................................................................................... 7 Receive Timeout and Guard Time...................................................... 7 UART Configuration ........................................................................... 8 UART Control ..................................................................................... 8 Interrupt control .................................................................................. 8

4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.3 4.4

Port Assignment ........................................................................................ 8 DUSART Initialisation Example Code ....................................................... 9

Development Board Configuration..................................................... 10 Software Listings................................................................ 11


A.1 uart.c........................................................................................................ 11 A.2 cstartup.asm ............................................................................................ 16 A.3 irq.asm..................................................................................................... 20 A.4 devboard.asm.......................................................................................... 21

Appendix A

26 May 2006

Cyan Technology Ltd.

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

Confidential and Proprietary Information


Cyan Technology Ltd, 2005-2006 This document contains confidential and proprietary information of Cyan Technology Ltd and is protected by copyright laws. Its receipt or possession does not convey any rights to reproduce, manufacture, use or sell anything based on information contained within this document. Cyan TechnologyTM, the Cyan Technology logo and Max-eICETM are trademarks of Cyan Holdings Ltd. CyanIDE and eCOG are registered trademarks of Cyan Holdings Ltd. Cyan Technology Ltd recognises other brand and product names as trademarks or registered trademarks of their respective holders. Any product described in this document is subject to continuous developments and improvements. All particulars of the product and its use contained in this document are given by Cyan Technology Ltd in good faith. However, all warranties implied or expressed, including but not limited to implied warranties of merchantability, or fitness for purpose, are excluded. This document is intended only to assist the reader in the use of the product. Cyan Technology Ltd shall not be liable for any loss or damage arising from the use of any information in this guide, any error or omission in such information, or any incorrect use of the product. This product is not designed or intended to be used for on-line control of aircraft, aircraft navigation or communications systems or in air traffic control applications or in the design, construction, operation or maintenance of any nuclear facility, or for any medical use related to either life support equipment or any other life-critical application. Cyan Technology Ltd specifically disclaims any express or implied warranty of fitness for any or all of such uses. Ask your sales representative for details.

26 May 2006

Cyan Technology Ltd.

Page 2 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

Revision History
Version V1.1 V1.2 V1.3 V1.4 V1.5 V1.6 Date 19/07/2004 23/09/2004 02/11/2004 28/02/2005 12/09/2005 26/05/2006 Notes Initial revision. Updated list of trademarks. Changed font sizes. Updated for new release of CyanIDE. Updated serial buffer indexing code. Corrected error in example code in section 4.2.3.

26 May 2006

Cyan Technology Ltd.

Page 3 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

1 Introduction
This application note describes how to set up the DUSART peripheral for the standard UART protocol. The example software demonstrates the use of interrupt-driven buffering for both transmitted and received characters. The application is a simple loop which echoes received characters and also shows them on the development board LCD. The example code is available as a project for the CyanIDE development environment and runs on the eCOG1 development board.

2 Glossary
CPU DUSART eCOG1 PLL SSM UART Central Processor Unit Dual Universal Synchronous/Asynchronous Receiver/Transmitter Cyan Technology target micro controller Phase Locked Loop System Support Module Universal Asynchronous Receiver/Transmitter

The on-chip I/O registers may be accessed as complete registers, or as named bit fields within the registers. The include file ecog1.h contains structure definitions for all on-chip registers and bit fields. To access any register, use the structure prefix rg. To access a bit field within a register, use the structure prefix fd. For example: // Write to flash program data register rg.flash_prg_data = 0xA55A; // Write to period bit field in configuration register fd.flash_prg_cfg.period = 0x01F1;

26 May 2006

Cyan Technology Ltd.

Page 4 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

3 Clocks
3.1

Clock Sources
LOW_REF HIGH_REF LOW_PLL HIGH_PLL 32.768 kHz crystal oscillator input 5 MHz crystal oscillator input 4.9152 MHz clock, synthesized from LOW_REF 100 MHz clock, synthesized from HIGH_REF

The eCOG1 supports a range of clock sources.

Registers in the System Support Module (SSM) control the selection of the clock source for the processor and for each peripheral module.

3.2
3.2.1

DUSART Clock
Overview

The DUSART module clock is derived from one of the main clock sources via a ripple counter with 16 outputs. This allows the DUSART clock frequency to be set to the selected main clock frequency divided by between 22 and 217.

3.2.2

Clock Selection

Two bits in register ssm.div_sel are used to select the DUSART modules clock source, bit 11 and bit 1. Bit 11 = 0 and bit 1 = 0 selects HIGH_REF Bit 11 = 0 and bit 1 = 1 selects HIGH_PLL Bit 11 = 1 and bit 1 = 0 selects LOW_REF Bit 11 = 1 and bit 1 = 1 selects LOW_PLL

Bits 11:8 in register ssm.tap_sel1 select the ripple counter tap and thus the division ratio for the DUSART module clock. B0000 selects the least significant tap of the counter and divides by 4. (If the HIGH_PLL clock source is selected, values of 0 and 1 both set the division ratio to 23 = 8.) B0001 selects the next tap of the counter and divides by 8. . B1111 selects the most significant tap of the counter and divides by 217.

Setting bit 5 in register ssm.clk_en enables the module clock for the DUSART. In the example, the clock initialisation for the DUSART is performed by the supplied library function ssm_dusart_clk(). // Set dusart clock to 100MHz / 8 = 12.5 MHz ssm_dusart_clk(SSM_HIGH_PLL, 1);

26 May 2006

Cyan Technology Ltd.

Page 5 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

4 DUSART Configuration
4.1 Overview
The DUSART peripheral block provides a general purpose dual serial port. A number of different protocols are supported by hardware controllers, and any two different protocols may be assigned to the two channels of the DUSART. One of the available protocols provides a standard UART function. Note that the configuration tool within the CyanIDE package does not yet fully support all the DUSART options, and the application must configure the DUSART registers as required. For simplicity, the descriptions in this document refer only to channel A of the DUSART. Channel B operates in the same way and has a similar set of control registers.

4.2
4.2.1

Registers
Configuration

The configuration register dusart.a_cfg controls the DUSART protocol configuration for channel A, with the following options: Protocol: I2C, SPI, IFR, SCI, UART or user-defined Endianness: lsb first or msb first (user-defined protocol only) Parity: none, even or odd

In the example code, the configuration register is set for the UART protocol with no parity. // Configure dusart A for uart rg.dusart.a_cfg = 4;

4.2.2

Sample Clock

The register dusart.a_smpl_cfg defines the oversampling clock period for the selected protocol, and controls what filtering is applied to the three available input signals. The example code sets a period value of 35, giving the required clock frequency for 18x oversampling at 9600 baud. // Set oversampling clock for 9600 baud rg.dusart.a_smpl_cfg = 35;

4.2.3

Symbol Clock

Register dusart.a_sym_cfg defines the bit clock high and low times and thus the bit clock period (and duty cycle for synchronous protocols). The example code sets the high and low times of the serial data bit clock to 9 sample clock periods each. // Serial clock 9 ticks high, 9 ticks low rg.dusart.a_sym_cfg = 0x0808;

26 May 2006

Cyan Technology Ltd.

Page 6 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

4.2.4

Baud Rates

The following tables give suggested values for the sample clock period and symbol clock times for various baud rates, minimising the error in the actual baud rate. Other combinations of values are equally valid. Clock source set to HIGH_PLL, tap select set to 1 => divide by 23 = 8 => DUSART input clock = 12.5MHz. Baud rate 1200 2400 3600 4800 7200 9600 19200 38400 57600 115200 a_smpl_cfg 161 161 101 80 50 35 17 8 5 2 a_sym_cfg 0x0f0f 0x0707 0x0807 0x0707 0x0807 0x0808 0x0808 0x0808 0x0808 0x0808 Actual Baud rate 1205.6 2411.3 3604.4 4822.5 7208.8 9645.1 19290 38580 57870 115740 % error 0.5% 0.5% 0.1% 0.5% 0.1% 0.5% 0.5% 0.5% 0.5% 0.5%

Clock source set to LOW_PLL, tap select set to 0 => divide by 22 = 4 => DUSART input clock = 1.2288MHz. Baud rate 1200 2400 3600 4800 7200 9600 19200 38400 a_smpl_cfg 31 15 9 7 4 3 1 1 a_sym_cfg 0x0707 0x0707 0x0807 0x0707 0x0807 0x0707 0x0707 0x0303 Actual Baud rate 1200 2400 3614.1 4800 7228.2 9600 19200 38400 % error 0.0% 0.0% 0.4% 0.0% 0.4% 0.0% 0.0% 0.0%

4.2.5

Receive Timeout and Guard Time

Register dusart.a_tim_cfg defines the receive timeout and guard times for protocols which require them. In this example both are set to zero. // Receive timeout and guard time set to zero rg.dusart.a_tim_cfg = 0;

26 May 2006

Cyan Technology Ltd.

Page 7 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

4.2.6

UART Configuration

Register dusart.uart_cfg defines options specific to the UART protocol. Character size: 5, 6, 7 or 8 bits Stop bits: 1, 1.5 or 2 stop bits Receive input polarity Transmit output polarity

The example is written to use the RS-232 transceiver on the development board and requires the transmit and receive polarities set to active-high. // 8 data bits, 1 stop bit, normal polarity rg.dusart.uart_cfg = 0xc0;

4.2.7

UART Control

Register dusart.uart_ctrl controls the UART transmit, receive and break functions. Enable the transmitter and receiver by setting the appropriate bit fields. fd.dusart.uart_ctrl.tx_en = 1; fd.dusart.uart_ctrl.rx_en = 1; // Enable tx // Enable rx

4.2.8

Interrupt control

The interrupt control registers dusart.a_int_en, dusart.a_int_dis and dusart.a_int_clr are used to control interrupts from the DUSART. Register dusart.a_int_sts allows the interrupt status to be read. In this example application only two bits in these registers are used. Bit 2 rx0_1b_rdy. Register dusart.a0_rx8 contains one byte of data. The interrupt is cleared by reading from dusart.a0_rx8. An 8 bit value is returned. Bit 0 tx0_rdy. The transmit buffer is empty. The interrupt is cleared by writing to dusart.a0_tx8.

4.3

Port Assignment

The external interface for the UART function of the DUSART module can be assigned to port A, B or C. Normally this is set up using the configuration editor in the CyanIDE environment, but the register settings are described here for completeness. Register port.sel1 controls the configuration of I/O ports A to F. For this example, writing B011 to bits [6:4] configures port B for the UART signals on pins B.6 and B.7. Bit 1 of register port.en is set to enable the port output drivers for port B.

26 May 2006

Cyan Technology Ltd.

Page 8 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

4.4

DUSART Initialisation Example Code

The following example code shows how to configure the DUSART for the UART function. Note that the CyanIDE configuration editor now supports this function, and most of this code is not required in the application. The last line of code which enables the DUSART receive data ready interrupt is required in the application code, and should be included at a point when the application is ready to handle interrupts. // Set dusart clock to 100MHz / 8 = 12.5 MHz ssm_dusart_clk(SSM_HIGH_PLL, 1); // Configure dusart A for uart rg.dusart.a_cfg = 4; // Set oversampling clock divisor and bit clock times for 9600 baud rg.dusart.a_smpl_cfg = 35; rg.dusart.a_sym_cfg = 0x0808; rg.dusart.a_tim_cfg = 0; // Configure uart rg.dusart.uart_cfg = 0xc0; fd.dusart.uart_ctrl.tx_en = 1; fd.dusart.uart_ctrl.rx_en = 1; // Enable receive interrupt fd.dusart.a_int_en.rx0_1b_rdy = 1; // No timeouts // Normal polarity // Enable tx // Enable rx

26 May 2006

Cyan Technology Ltd.

Page 9 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

5 Development Board Configuration


The example project configuration has the DUSART serial port pins assigned to port B pins 6 and 7 on the eCOG1 chip. These signals are available on header J17 on the development board. To connect these signals to one of the RS-232 transceiver devices, it is necessary to remove some of the jumper links from J16 and connect two wire links. Remove jumper links on J16 pins 3-4 and pins 9-10 Connect J17 pin 2 to J16 pin 4 (Tx) Connect J17 pin 3 to J16 pin 10 (Rx)

With these links fitted, the DUSART serial port is connected to the 9 way D-type plug J15 instead of DUART B.

26 May 2006

Cyan Technology Ltd.

Page 10 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

Appendix A Software Listings


A.1 uart.c
/*============================================================================= Cyan Technology Limited FILE - uart.c Example eCOG1 application - buffered interrupt driven serial port. DESCRIPTION Uses the dusart UART function This example uses dusart channel A MODIFICATION DETAILS =============================================================================*/ /****************************************************************************** Project level include files. ******************************************************************************/ #include <ecog1.h> #include <stdio.h> #include "driver_lib.h" /****************************************************************************** Include files for public interfaces from other modules. ******************************************************************************/ /****************************************************************************** Declaration of public functions. ******************************************************************************/ /****************************************************************************** Private constants and types. ******************************************************************************/ // Buffer sizes #define TXBUFSIZE #define RXBUFSIZE 48 128 // Transmit buffer size // Receive buffer size

/****************************************************************************** Declaration of static functions. ******************************************************************************/ int putchar(int c); int _getchar(void); int txcount(void); int rxcount(void); // Read number of characters in transmit buffer // Read number of characters in receive buffer

// Called from irq service routines int __irq_code itxcount(void); // Read number of characters in transmit buffer int __irq_code irxcount(void); // Read number of characters in receive buffer /****************************************************************************** Global variables. ******************************************************************************/ char txbuf[TXBUFSIZE]; char rxbuf[RXBUFSIZE]; // Buffer index values int txeptr = 0; int txfptr = 0; int rxeptr = 0; int rxfptr = 0; // Transmit buffer // Receive buffer // // // // Transmit buffer empty index Transmit buffer fill index Receive buffer empty index Receive buffer fill index

26 May 2006

Cyan Technology Ltd.

Page 11 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

/****************************************************************************** Module global variables. ******************************************************************************/ /****************************************************************************** Definition of API functions. ******************************************************************************/ /****************************************************************************** NAME main SYNOPSIS int main(int argc, char *argv[]) FUNCTION When a character is received, display it on LCD, and echo it on both sw uart and normal uart RETURNS Exit code. ******************************************************************************/ int main(int argc, char *argv[]) { int count = 0; int c; lcd_rst(); lcd_puts("Example: uart"); lcd_xy(1, 2); // Dusart is now set up in configurator /* // Set dusart clock to 100MHz / 8 = 12.5 MHz ssm_dusart_clk(SSM_HIGH_PLL, 1); // Configure dusart A for uart rg.dusart.a_cfg = 4; // Set 18x oversampling clock (divide by 36) for 9600 baud rg.dusart.a_smpl_cfg = 35; rg.dusart.a_sym_cfg = 0x0808; // Serial clock 9 ticks high, 9 ticks low rg.dusart.a_tim_cfg = 0; // No timeouts // *** This code works for 9600 baud // Configure uart rg.dusart.uart_cfg = 0xc0; fd.dusart.uart_ctrl.tx_en = 1; fd.dusart.uart_ctrl.rx_en = 1; */ // Normal polarity // Enable tx // Enable rx

// Enable receive interrupt fd.dusart.a_int_en.rx0_1b_rdy = 1; // Main loop - read any received characters and echo them while (1) { if (rxcount() > 0) // Any characters received? { c = getchar(); // Yes, read character putchar(c); // Echo it count++; count %= 16; if (count == 0) { lcd_xy(1, 2); } lcd_putc(c); duart_a_tx(c); // Count character (for lcd) // Wrap at 16 chars, lcd is 16 columns wide // Reposition cursor at start of 2nd display line // Send character to lcd // Also send character to std serial port A

// Check for a carriage return and send line feed if ('\r' == c) { putchar('\n');

26 May 2006

Cyan Technology Ltd.

Page 12 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

count = 0; // Reset lcd counter lcd_xy(1, 2); // Reposition cursor duart_a_tx('\n'); } } } return 0; } // Put character in transmit buffer int putchar(int c) { while (txcount() >= (TXBUFSIZE - 1)) // Wait for space in transmit buffer ; if (txcount() < (TXBUFSIZE - 1)) { txbuf[txfptr] = (char)c; if (++txfptr >= TXBUFSIZE) txfptr = 0; } fd.dusart.a_int_en.tx0_rdy = 1; return (c); } // Read character from receive buffer int _getchar(void) { int c = 0; if (rxcount() > 0) { c = (int)rxbuf[rxeptr]; if (++rxeptr >= RXBUFSIZE) rxeptr = 0; } return (c); } // Returns number of characters in transmit buffer int txcount(void) { int chars_pending = txfptr - txeptr; if (chars_pending < 0) chars_pending += TXBUFSIZE; return (chars_pending); } // Returns number of characters in receive buffer int rxcount(void) { int chars_received = rxfptr - rxeptr; if (chars_received < 0) chars_received += RXBUFSIZE; return (chars_received); } /****************************************************************************** NAME usr_tx_handler SYNOPSIS void __irq_entry usr_tx_handler(void) // Any characters received? // Yes, read character from buffer // Check for index pointer wraparound // Is there space in transmit buffer? // Yes, put character into buffer // Check for index pointer wraparound

// Enable transmit ready interrupt

// Return received character

26 May 2006

Cyan Technology Ltd.

Page 13 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

FUNCTION Interrupt handler for usr transmit ready RETURNS Nothing. ******************************************************************************/ void __irq_entry usr_tx_handler(void) { // Read tx interrupt status register int test = fd.dusart.a_int_sts.tx0_rdy; // Transmitter ready? if (1 == test) { // Yes, any characters to send? if (itxcount() > 0) { // Yes, get character from buffer rg.dusart.a0_tx8 = txbuf[txeptr]; if (++txeptr >= TXBUFSIZE) // Check for index pointer wraparound txeptr = 0; } else // No characters left in transmit buffer { // Disable transmitter ready interrupt fd.dusart.a_int_dis.tx0_rdy = 1; } } } /****************************************************************************** NAME usr_rx_handler SYNOPSIS void __irq_entry usr_rx_handler(void) FUNCTION Interrupt handler for usr receive ready RETURNS Nothing. ******************************************************************************/ void __irq_entry usr_rx_handler(void) { // Read rx interrupt status register int test = fd.dusart.a_int_sts.rx0_1b_rdy; // Received character ready? if (1 == test) { // Yes, read receive register char c = rg.dusart.a0_rx8; // Is there space in receive buffer? if (irxcount() < (RXBUFSIZE - 1)) { // Yes, put character into input buffer rxbuf[rxfptr] = c; if (++rxfptr >= RXBUFSIZE) // Check for index pointer wraparound rxfptr = 0; } } } // Duplicate buffer count routines for use by interrupt service routines // Return number of characters in transmit buffer int __irq_code itxcount(void) { int chars_pending = txfptr - txeptr;

26 May 2006

Cyan Technology Ltd.

Page 14 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

if (chars_pending < 0) chars_pending += TXBUFSIZE; return (chars_pending); } // Return number of characters in receive buffer int __irq_code irxcount(void) { int chars_received = rxfptr - rxeptr; if (chars_received < 0) chars_received += RXBUFSIZE; return (chars_received); } /****************************************************************************** NAME usr_ex_handler SYNOPSIS void __irq_entry usr_ex_handler(void) FUNCTION Interrupt handler for usr exceptions RETURNS Nothing. ******************************************************************************/ void __irq_entry usr_ex_handler(void) { // Clear any interrupt rg.dusart.a_ex_clr = 0xfff; // Disable any interrupt rg.dusart.a_ex_dis = 0xfff; }

26 May 2006

Cyan Technology Ltd.

Page 15 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

A.2

cstartup.asm

;============================================================================== ; Cyan Technology Ltd ; ; FILE ; cstartup.asm - Assembler startup for C programs. ; ; DESCRIPTION ; Defines C segments. Contains initial code called before C is started ;============================================================================== MODULE .ALL ; ; ; ; ; ; cstartup

C reserves DATA address 0 for the NULL pointer. The value H'DEAD is put in here so that it is easier to spot the effect of a NULL pointer during debugging. User memory for constants grows upwards from H'0001. The first address is given the equate symbol $??LO_ADDR. .SEG ORG dc EQU C_RESERVED1 0 H'DEAD $

$??LO_ADDR ; ; ; ; ; ; ; ; ; ; ;

DATA addresses H'EFE0-H'EFFF are used for scratchpad RAM in interrupt mode. DATA addresses H'EFC0-H'EFDF are used for scratchpad RAM in user mode. DATA addresses H'EFB8-H'EFBF are used for register storage in interrupt mode. Then follows the interrupt stack, user stack and user heap. User memory for variables grows downwards from the end of the user stack. This version of cstartup only contains one area of scratchpad RAM which constrains users not to write re-entrant re-interruptable code. The interrupt stack must start at IY-38 to be compatible with the C compiler. .SEG ORG C_RESERVED2 H'EFB8 $ 8 32 $ $ 32 ; Interrupt register storage ; User Scratchpad

$??HI_ADDR

DEQU ds ds DEQU

IY_SCRATCH

$?irq_scratchpad? DEQU ds ; ; ; ; ; ;

; Interrupt Scratchpad

The registers that control the functional blocks of the eCOG1 are located at addresses H'FEA0 to H'FFCF. The C header file <ecog1.h> declares an external structure that descibes the registers. This variable is defined below. .SEG ORG REGISTERS H'FEA0 304

$fd: $rg

ds

; ; C requires the following segments: ; CONST - Constants in ROM. For example: ; const char c = 'c' ; ; printf( "Hello World!" ) ; ; VAR - Variables in RAM. These are set to zero by the cstartup code. ; For example: ; int i ; (in file scope) ; static int i ; (in function scope) ; INIT - Initialisd variables in RAM. For example: ; int i = 9 ; (in file scope) ; static int i = 9 ; (in function scope) ; INITC - Initialisation data for the INIT segment ; HEAP - The heap. Required if malloc() etc. are used. ; STACK - The stack. Always required.

26 May 2006

Cyan Technology Ltd.

Page 16 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

; ; The memory allocated to each segment is defined by the value of ; $??<segment_name>_SIZE as set below. These sizes can be set manually or, if ; the appropriate line is tagged with !PACK and the -pack option is specified ; to ECOGCL, ECOGCL will write in the size actually required for the segment. ; The sizes of the STACK and HEAP segments must be set by the user. ; $??ISTACK_SIZE = H'0040 $??STACK_SIZE = H'0100 $??HEAP_SIZE = H'0080 ; ROM segments $??INITC_SIZE $??CONST_SIZE ; RAM segments $??INIT_SIZE $??VAR_SIZE = = = = h'0005 h'0009 h'0005 h'0058 ; !PACK ; !PACK ; !PACK ; !PACK

; -- Locate DATA segments in memory -; ; Segments are allocated sequentially by the ??ALLOCATE macro. They may be ; set at fixed addresses by setting ADDR prior to calling ??ALLOCATE. ; ??ALLOCATE MACRO seg .SEG &seg ORG ADDR $??&seg!_LO = ADDR ADDR = ADDR + $??&seg!_SIZE $??&seg!_HI = ADDR-1 ENDMAC ; Allocate DATA ROM ADDR = $??LO_ADDR ??ALLOCATE INITC ??ALLOCATE CONST ; Allocate DATA RAM ADDR = $??HI_ADDR - $??VAR_SIZE - $??INIT_SIZE ADDR = ADDR - $??ISTACK_SIZE - $??STACK_SIZE - $??HEAP_SIZE ??ALLOCATE INIT ??ALLOCATE VAR ??ALLOCATE HEAP ??ALLOCATE STACK ??ALLOCATE ISTACK ; -- Memory initialisation macros -; ; Segments may be initialised by filling with a constant value using the ; ??SEGFILL macro. Two symbols are passed, the segment name and the value to ; fill with. A third symbol (the size) is assumed. ; ??SEGFILL MACRO seg, value LOCAL fill_loop IF $??&seg!_SIZE ld x, #$??&seg ld al, #$??&seg!_SIZE ld ah, &value &fill_loop: st ah, @(0,x) add x, #1 sub al, #1 bne &fill_loop ENDIF ENDMAC ; ; Segments may be initialised by copying an initialisation segment with ; the ??SEGCOPY macro. Two symbols are passed, the source and destination ; segment names. ; ??SEGCOPY MACRO src, dest IF $??&src!_SIZE NE $??&dest!_SIZE .ERR "Copy segments different sizes" ENDIF IF $??&src!_SIZE

26 May 2006

Cyan Technology Ltd.

Page 17 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

ld ld ld bc ENDIF ENDMAC

x, #$??&src y, #$??&dest al, #$??&src!_SIZE

; ; Fills a block of memory with a value. Three values are passed, the start ; address for the block, the number of addresses to write to and the value ; to be written. ; ??MEMFILL MACRO start, length, value LOCAL fill_loop ld x, &start ld al, &length ld ah, &value &fill_loop: st ah, @(0,x) add x, #1 sub al, #1 bne &fill_loop ENDMAC ; ; Input argument for main(). ; .SEG CONST argv dc 0,0 ; ; Start of Code. ; .CODE ORG $?cstart_code: bra $ecog1ConfigMMU ; configure MMU and Cache Banks $ecog1ConfigContinue: ; ; Initialise segments. The HEAP and STACK are filled with H'9999 and H'aaaa ; respectively so that their maximum runtime extents can be checked. The ; INIT segment is set from the ROM initialisers in the INITC segment. The non ; initialised RAM segment VAR is set to zero (compiler puts 0 initialised ; variables in these segments as well as uninitialised ones,x). ; ??SEGFILL HEAP, #h'9999 ??SEGFILL STACK, #h'AAAA ??SEGFILL ISTACK, #h'BBBB ??SEGCOPY INITC, INIT ??SEGFILL VAR, #h'0 ; Set interrupt stack pointer. ld y, #IY_SCRATCH ; Set user mode flag st ld or st ld to allow interupts. flags, @(-1,y) al, @(-1,y) al, #h'10 al, @(-1,y) flags, @(-1,y) H'40

; NULL as two-word byte address

; Set usermode stack pointer ld y, #$??STACK_HI ; Call ecog1Config to setup eCOG1 peripherals ; Defined in module produced by configuration compiler bsr $ecog1Config ; Call main, setting argc and argv[0] to 0. ld ah, #argv ld al, #0 bsr $main

26 May 2006

Cyan Technology Ltd.

Page 18 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

; ; Main may exit by returning or by explicitly calling $exit. In either case ; exit code will be in AL. ; $exit: brk ; Alert the user if in debug mode bra 0 ; Restart ; ; This is the minimal interrupt routine. The contents of FLAGS is restored ; as the program counter is restored using rti. ; $minimal_handler: st flags,@(-33,y) ; Store Flags st al, @(-34,y) ; Store AL ld al, @(-33,y) or al, #h'0010 st al, @(-33,y) brk ld al, @(-34,y) rti @(-33,y) ; Put Flags into AL ; Set usermode ; Store the value to be restored to Flags ; Alert the user if in debug mode ; Restore AL ; Restore PC and Flags

; ; The address exception can happen often during development. A handler ; is put here to catch the exception. ; $address_error: st flags,@(-33,y) ; Store Flags st al, @(-34,y) ; Store AL ld al, @(-33,y) or al, #h'0010 st al, @(-33,y) brk ld al, #h'a st al, @h'ff69 ld al, #h'200 st al, @h'ff7a ld al, @(-34,y) rti @(-33,y) ; End of startup code $??CSTARTUP_END EQU $ ENDMOD ; Put Flags into AL ; Set usermode ; Store the value to be restored to Flags ; Alert the user if in debug mode ; Clear status in mmu.address_exception ; Clear status in emi.ctrl_sts ; Restore AL ; Restore PC and Flags

26 May 2006

Cyan Technology Ltd.

Page 19 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

A.3

irq.asm

;============================================================================== ; Cyan Technology Ltd ; Example application software for eCOG ; ; FILE - irq.asm ; Contains the interrupt vectors and the initial branch to the main code. ;============================================================================== MODULE irq .ALL ; Interrupt vectors are sign-extended 24 bit absolute branch addresses. For ; example a vector containing H'1234 will start executing at H'1234 and a ; vector containing H'8765 will start executing at H'ff8765. ; ORG H'0 bra $?cstart_code ORG ex_debug ex_tim_wdog_ufl ex_adr_err reserved ex_tim ex_intact ex_usart_a ex_usart_b ex_uart_a ex_uart_b int_tim_tmr_ufl int_tim_cnt1_ufl int_tim_cnt2_ufl int_tim_cnt1_match int_tim_cnt2_match int_tim_pwm1_ufl int_tim_pwm2_ufl int_tim_pwm1_match int_tim_pwm2_match int_tim_cap_ofl int_tim_cap1 int_tim_cap2 int_tim_cap3 int_tim_cap4 int_tim_cap5 int_tim_cap6 int_tim_ltmr_ufl int_intact_cpu_rx_rdy int_intact_cpu_tx_rdy int_intact_dma_rdy int_intact_dma_done int_intact_up_clk_inact int_intact_up_rx_purge int_intact_down_clk_inact int_intact_down_rx_purge int_usart_a_rx int_usart_a_tx int_usart_b_rx int_usart_b_tx int_sci_tx_done int_sci_tx_err int_sci int_ifr_tx_done int_ifr_rx_done int_ifr_rx_err int_ifr_frame_done int_uart_a_tx_rdy int_uart_a_rx_rdy int_uart_b_tx_rdy int_uart_b_rx_rdy int_ehi int_gpio int_adc ENDMOD H'4 DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC DC $minimal_handler $minimal_handler $address_error $minimal_handler $minimal_handler $minimal_handler $usr_ex_handler?? $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $usr_rx_handler?? $usr_tx_handler?? $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler $minimal_handler

26 May 2006

Cyan Technology Ltd.

Page 20 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

A.4
; ; ; ; ; ; ; ; ; ; ; ;

devboard.asm

============================================================================= CREATED by eCOG1 Configuration Compiler Version 1.00.0001 DATE 28/02/2005 14:22:41 INPUT : devboard.cfg WARNING! Any changes made to this file will be lost when it is regenerated by the eCOG1 Configuration Compiler ============================================================================= MODULE devboard .CODE .LARGE ORG $??CSTARTUP_END

; Define symbols used in mmu initialisation ; Internal flash code area addresses $??code_log = 0 $??code_phy = 0 $??code_siz = H'8000 $ecog1ConfigMMU: ; ; ; ; ; ; ; -----------------------; Configure MMU (part 1) -----------------------Setup MMU to enable cache configuration Get address of mmu registers ld x, #h'ff43 Disable all (flash code ld al, st al, ; &mmu.translate_en

unwanted mmu translations initially and sram data areas are always enabled) #0 @(0,x) ; mmu.translate_en

; ;

Initialise mmu for flash code area 1. CODE H'0000-H'7FFF IROM H'0000-H'7FFF 32Kwords ld al, #($??code_log SHR 8) st al, @(1,x) ; mmu.flash_code_log ld al, #($??code_phy SHR 8) st al, @(2,x) ; mmu.flash_code_phy ld al, #(($??code_siz - 1) SHR 8) st al, @(3,x) ; mmu.flash_code_size ------------------Cache Configuration -------------------

; ; ;

; macro used for initialisation of cache banks ??MEMFILL MACRO start, length, value LOCAL fill_loop ld x, &start ld al, &length ld ah, &value &fill_loop: st ah, @(0,x) add x, #1 sub al, #1 bne &fill_loop ENDMAC ld st ; AH,#H'0 AH,@H'ff42 ; Enable both Cache banks for data access

Set physical mappings of cache banks ld al, #h'10 ; map cache bank 0 at 0x1000 - 0x11ff st al, @h'ff59 ; mmu.cache0_data_log ld al, #h'12 ; map cache bank 1 at 0x1200 - 0x13ff

26 May 2006

Cyan Technology Ltd.

Page 21 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

st ;

al, @h'ff5a

; mmu.cache1_data_log

Map both cache banks in data space ld al, @h'ff43 ; read mmu.translate_en or al, #h'180 ; map both cache banks to data space st al, @h'ff43 ; set mmu.translate_en Invalidate cache contents ??MEMFILL #h'1000, #h'100, ??MEMFILL #h'1100, #h'100, ??MEMFILL #h'1200, #h'100, ??MEMFILL #h'1300, #h'100, #h'0 #h'8000 #h'0 #h'8000

Unmap both cache banks from data space ld al, @h'ff43 ; read mmu.translate_en and al, #h'fe7f ; unmap both cache banks from data space st al, @h'ff43 ; set mmu.translate_en Enable cache memory Mode is 'One Way 512 Words' ld AH,#H'10 st AH,@H'ff41 ; ld st AH,#H'3 AH,@H'ff42 ;

; ;

; Configure Cache ; Enable Cache ; Three NOPs are required following ; the enable

Wait for HW nop nop nop Clock Setup Notes 32kHz and 5 MHz xtal fitted

; ; ; ; ; ; ; ; ; ; ; ; ; ;

Possible peripheral clock sources are: Low Ref Low PLL High Ref High PLL --------------------------------Configuring CPU and memory clocks --------------------------------Enabling in_clk source - High PLL ld AH,#H'8001 st AH,@H'ff6c ; ssm.clk_en CPU frequency > 10 MHz - inserting flash wait state ld AH,#H'2 st AH,@H'ff67 ; mmu.flash_ctrl Setting prescalar and divider ld AH,#H'37 st AH,@H'ff72 ; ssm.cpu

; Setting in_clk source ?LOOP1: ld AH,#H'20 st AH,@H'ff74 ; ssm.cfg ld asr and cmp bne ; ; AL,@H'ff72 #8 AL,#15 AL,#2 ?LOOP1 ; ssm.cpu

------------------Port configuration: ; A 11 ; B 3 ; C 7 ; D 1 ; E 0

26 May 2006

Cyan Technology Ltd.

Page 22 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

; F 0 ; G 0 ; H 0 ; I 0 ; J 3 ; K 99 ; L 2 ------------------ld st ld st ld st ld st AH,#H'7bb AH,@H'ff9c AH,#H'bc0 AH,@H'ff9d AH,#H'fff AH,@H'ff9e AH,#H'0 AH,@H'ff9f ; port.sel1 ; port.sel2 ; port.en ; port.dis

; ; ;

------------------;GPIO Configuration ------------------st st st st st st st st ld st ld st ld st st ld st ld st st ld st AH,@H'ffa5 AH,@H'ffa6 AH,@H'ffa7 AH,@H'ffa8 AH,@H'ffa9 AH,@H'ffaa AH,@H'ffab AH,@H'ffac AH,#H'5555 AH,@H'ffad AH,#H'a5aa AH,@H'ffae AH,#H'aaaa AH,@H'ffaf AH,@H'ffb0 AH,#H'aaa5 AH,@H'ffb1 AH,#H'aaaa AH,@H'ffb2 AH,@H'ffb3 AH,#H'a AH,@H'ffb4 ; io.gp0_3_cfg ; io.gp4_7_cfg ; io.gp8_11_cfg ; io.gp12_15_cfg ; io.gp16_19_cfg ; io.gp20_23_cfg ; io.gp24_27_cfg ; io.gp28_cfg ; io.gp0_3_out ; io.gp4_7_out ; io.gp8_11_out ; io.gp12_15_out ; io.gp16_19_out ; io.gp20_23_out ; io.gp24_27_out ; io.gp28_out

; ; ;

----------------EMI Configuration ----------------ld st ld st ld st AH,#H'37 AH,@H'ff7b AH,#H'3000 AH,@H'ff7c AH,#H'940d AH,@H'ff7d ; emi.bus_cfg1 ; emi.bus_cfg2 ; emi.sdram_cfg

26 May 2006

Cyan Technology Ltd.

Page 23 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

ld st ld st ld st ld st st ld st ; ; ;

AH,#H'330c AH,@H'ff80 AH,#H'10 AH,@H'ff81 AH,#H'8a4 AH,@H'ff7a AH,#H'4000 AH,@H'ff6b AH,@H'ff6c AH,#H'200 AH,@H'ff7a

; emi.sdram_refr_per ; emi.sdram_refr_cnt ; emi.ctrl_sts ; ssm.rst_clr ; ssm.clk_en ; emi.ctrl_sts, clear address error

---------------------Configure MMU (part 2) ---------------------ld x, #h'ff43 ; mmu base pointer

Map CodeFlash Physical 0 - 7fff to Logical Code 0 - 7fff ld al, #h'0 st al, @(1,x) ; mmu.xxx_log h'ff44 st al, @(2,x) ; mmu.xxx_phys h'ff45 ld al, #h'7f st al, @(3,x) ; mmu.xxx_size h'ff46 Map DataFlash Physical 7800 - 7fff to Logical Data 0 - 7ff ld al, #h'0 st al, @(13,x) ; mmu.xxx_log h'ff50 ld al, #h'78 st al, @(14,x) ; mmu.xxx_phys h'ff51 ld al, #h'7 st al, @(15,x) ; mmu.xxx_size h'ff52 Map DataRam0 Physical 0 - 7ff to Logical Data e800 - efff ld al, #h'e8 st al, @(16,x) ; mmu.xxx_log h'ff53 ld al, #h'0 st al, @(17,x) ; mmu.xxx_phys h'ff54 ld al, #h'7 st al, @(18,x) ; mmu.xxx_size h'ff55 Enable translations ld al, #h'10 st al, @(0,x)

; mmu.translate_enable

; ;

Clear the address exception. These can be active when the software has done a self reset using the if_reset and cpu_reset bits. ld al,#h'a st al,@h'ff69 ; Clear status in mmu.address_exception bra $ecog1ConfigContinue

; ; ;

-----------------Main Configuration ------------------

$ecog1Config: ; ; ; ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;UART on USART Configuration ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Setting up UART on DUSART Channel A ld AH,#H'4 st AH,@H'feb4 ; dusart.a_cfg ld st ; AH,#H'0 AH,@H'feb7 ; dusart.a_tim_cfg

; Set Baud Rate to 9600 ld AH,#H'23

26 May 2006

Cyan Technology Ltd.

Page 24 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

st ld st ld st ld st ; ; ;

AH,@H'feb5 AH,#H'808 AH,@H'feb6 AH,#H'c0 AH,@H'fef4 AH,#H'5 AH,@H'fef5

; dusart.a_smpl_cfg ; dusart.a_sym_cfg ; dusart.uart_cfg ; duart.uart_ctrl

Enable DUSART clock source Enable divider chain for DUSART Using High PLL ld AH,#H'4 st AH,@H'ff6b ; ssm.rst_clr Select ld and or st Select ld and or st DUSART clock source AH,@H'ff75 ; ssm.div_sel AH,#B'1111011111111101 ; clear DUSART selections AH,#H'2 AH,@H'ff75 DUSART Divider tap AH,@H'ff76 AH,#H'f0ff AH,#H'100 AH,@H'ff76 ; ssm.tap_sel1

Enable DUSART clock ld AH,#H'20 st AH,@H'ff6b st AH,@H'ff6c

; ssm.rst_clr ; ssm.clk_en

; ; ;

-----------------------UART A & B Configuration -----------------------ld st st st AH,#H'0 AH,@H'fea1 AH,@H'fea2 AH,@H'feab ; duart.frame_cfg ; duart.a_tmr_cfg ; duart.b_tmr_cfg

; ; ;

Configure DUART clock source Enable divider chain for DUART Using High PLL ld AH,#H'4 st AH,@H'ff6b ; ssm.rst_clr Select ld and or st Select ld and st DUART clock source AH,@H'ff75 ; ssm.div_sel AH,#B'1111101111111110 ; clear DUART selections AH,#H'1 AH,@H'ff75 DUART Divider tap AH,@H'ff76 AH,#H'ff0f AH,@H'ff76 ; ssm.tap_sel1

Setting UARTA baud rate to 9600 (actual = 9645.06, divider = 80) ld AH,#H'50 st AH,@H'fea3 ; duart.a_baud Setting UARTB baud rate to 9600 (actual = 9645.06, divider = 80) st AH,@H'feac ; duart.b_baud Enabling duart clocks ld AH,#H'10 st AH,@H'ff6b ; ssm.rst_clr

; ;

26 May 2006

Cyan Technology Ltd.

Page 25 of 26

AN014

eCOG1 Using the UART Function in the DUSART

Version 1.6

ld st ;

AH,#H'18 AH,@H'ff6c

; ssm.clk_en

Enabling duart tx/rx ld AH,#H'145 st AH,@H'fea0 ------------------Sleep Configuration ------------------Select ld and st ld and st rts ENDMOD

; duart.ctrl

; ; ; ;

Sleep Timeout clock source AH,@H'ff75 ; ssm.div_sel AH,#B'1101111111111111 ; clear Sleep timeout selections AH,@H'ff75 AH,@H'ff76 AH,#H'fff0 AH,@H'ff76 ; ssm.tap_sel1

; ; ;

----------END OF FILE -----------

26 May 2006

Cyan Technology Ltd.

Page 26 of 26

You might also like