CMPE 401 - Computer Interfacing

Assignment #3 Solutions

Due: In the CMPE 401 assignment box by 15:45 on Monday, Oct. 20, 2003


  1. Design an initialization routine in CPU32 assembly language that initializes the DUART as follows: Serial port A is to use a baud rate of 19200, and character frames with 8 data bits, even parity, and 2 stop bits. Serial port B is to use a baud rate of 38400, and character frames with 7 data bits, fixed low parity bit, and 1.5 stop bits. Interrupts are to be enabled for the receive direction of both serial ports, but not for the transmit direction. Thus, receiving a new character into either port A or port B's receiver is to trigger a hardware interrupt to the CPU. In your code be sure to use the predefined constants that were provided to you in laboratory exercise 2.

    .comm IMR_COPY, 1	/* Copy of IMR in system RAM */
    .EQU DUART,  0xA00800	/* DUART chip base address */
    
    /*  Offsets to read/write-able registers */
    .EQU MR1A,		0x00	/* Mode Register 1A */
    .EQU MR2A,		0x00	/* Mode Register 2A */
    .EQU MR1B,		0x08	/* Mode Register 1B */
    .EQU MR2B,		0x08	/* Mode Register 2B */
    .EQU IVR,		0x0C	/* Interrupt Vector Register */
    
    /*  Offsets to read-only registers */
    .EQU SRA,		0x01	/* Status Register A */
    .EQU RBA,		0x03	/* Receiver Buffer A */
    .EQU IPCR,		0x04	/* Input Port Change Register */
    .EQU ISR,		0x05	/* Interrupt Status Register */
    .EQU CUR,		0x06	/* Counter Upper Register */
    .EQU CLR,		0x07	/* Counter Lower Register */
    .EQU SRB,		0x09	/* Status Register B */
    .EQU RBB,		0x0B	/* Receiver Buffer B */
    
    /*  Offsets to write-only registers */
    .EQU CSRA,		0x01	/* Clock Select Register A */
    .EQU CRA,		0x02	/* Command Register A */
    .EQU TBA,		0x03	/* Transmitter Buffer A */
    .EQU ACR,		0x04	/* Auxiliary Control Register */
    .EQU IMR,		0x05	/* Interrupt Mask Register */
    .EQU CTUR,		0x06	/* Counter/Timer Upper Register */
    .EQU CTLR,		0x07	/* Counter/Timer Lower Register */
    .EQU CSRB,		0x09	/* Clock Select Register B */
    .EQU CRB,		0x0A	/* Command Register B */
    .EQU TBB,		0x0B	/* Transmitter Buffer B */
    .EQU OPCR,		0x0D	/* Output Port Configuration Register */
    .EQU OPUR,		0x0E	/* Output Port Upper Register */
    .EQU OPLR,		0x0F	/* Output Port Lower Register */
    .EQU BSET,		0x0E	/* Bit Set Command */
    .EQU BRST,		0x0F	/* Bit Reset Command */
    
    /*  Mode Register 1A and 1B (MR1A and MR1B) Fields */
    .EQU BITS_5,		0b00000000
    .EQU BITS_6,		0b00000001
    .EQU BITS_7,		0b00000010
    .EQU BITS_8,		0b00000011
    .EQU WITH_PAR,		0b00000000
    .EQU PAR_EVEN,		0b00000000
    .EQU PAR_ODD,		0b00000100
    .EQU FORCE_PAR,		0b00001000
    .EQU FP_LOW,		0b00000000
    .EQU FP_HIGH,		0b00000100
    .EQU NO_PAR,		0b00010000
    .EQU MULTI_DROP,	0b00011000
    .EQU MD_DATA,		0b00000000
    .EQU MD_ADDR,		0b00000100
    .EQU CHAR_MODE,		0b00000000
    .EQU BLK_MODE,		0b00100000
    .EQU RxRDY,		0b00000000
    .EQU FFULL,		0b01000000
    .EQU RTS_Rx_CTL_OFF,	0b00000000
    .EQU RTS_Rx_CTL_ON,	0b10000000
    
    /*  Mode Register 2A and 2B (MR2A and MR2B) Fields */
    .EQU STOP_1, 		0b00000111
    .EQU STOP_1_563, 	0b00001000
    .EQU STOP_2, 		0b00001111
    .EQU CTS_Tx_CTL_OFF,	0b00000000	/*Enable CTS control over Tx */
    .EQU CTS_Tx_CTL_ON,	0b00010000	/*Disable CTS control over Tx */
    .EQU RTS_Tx_CTL_OFF,	0b00000000	/*Enable Tx RTS output */
    .EQU RTS_Tx_CTL_ON,	0b00100000	/*Disable Tx RTS output */
    .EQU MD_NORM,		0b00000000	/*Normal Channel Mode */
    .EQU MD_AUTO_ECHO,	0b01000000	/*Normal Channel Mode */
    .EQU MD_LOCAL_LOOP,	0b10000000	/*Normal Channel Mode */
    .EQU MD_REM_LOOP,	0b11000000	/*Normal Channel Mode */
    
    /*  Clock Select Register A and B (CSRA and CSRB) Fields
        (Note baud rate set, 1 or 2, must be specified in ACR[7])
        Transmitter Baud Rate */
    .EQU TxBAUD_9600,	0b00001011	/* 9600 bps */
    .EQU TxBAUD_19200,	0b00001100	/* 19200 bps (set 2 only) */
    .EQU TxBAUD_38400,	0b00001100	/* 38400 bps (set 1 only) */
    .EQU TxBAUD_TIMER,	0b00001101	/* Timer used as clock source */
    .EQU TxBAUD_IP3_16X,	0b00001110	/* Channel A only, IP3/16 */
    .EQU TxBAUD_IP3_1X,	0b00001111	/* Channel A only, IP3/1 */
    .EQU TxBAUD_IP5_16X,	0b00001110	/* Channel B only, IP5/16 */
    .EQU TxBAUD_IP5_1X,	0b00001111	/* Channel B only, IP5/1 */
    
    /*    Receiver Baud Rate */
    .EQU RxBAUD_9600,	0b10110000	/* 9600 bps */
    .EQU RxBAUD_19200,	0b11000000	/* 19200 bps (set 2 only) */
    .EQU RxBAUD_38400,	0b11000000	/* 38400 bps (set 1 only) */
    .EQU RxBAUD_TIMER,	0b11010000	/* Timer used as clock source */
    .EQU RxBAUD_IP4_16X,	0b11100000	/* Channel A only, IP4/16 */
    .EQU RxBAUD_IP4_1X,	0b11110000	/* Channel A only, IP4/1 */
    .EQU RxBAUD_IP2_16X,	0b11100000	/* Channel B only, IP2/16 */
    .EQU RxBAUD_IP2_1X,	0b11110000	/* Channel B only, IP2/1 */
    
    /*  Command Registers A and B (CRA and CRB) Fields 
        Note:  registers must be cleared after a command is issued */
    .EQU ENABLE_Rx,		0b00000001
    .EQU DISABLE_Rx,	0b00000010
    .EQU ENABLE_Tx,		0b00000100
    .EQU DISABLE_Tx,	0b00001000
    .EQU RESET_MR_PTR,	0b00010000
    .EQU RESET_Rx,		0b00100000
    .EQU RESET_Tx,		0b00110000
    .EQU RESET_ERROR,	0b01000000
    .EQU RESET_BK_IRQ,	0b01010000
    .EQU START_BREAK,	0b01100000
    .EQU STOP_BREAK,	0b01110000
    .EQU NO_CMD,		0b00000000
    
    /*  Auxiliary Control Register (ACR) Fields */
    .EQU BAUD_SET_1,	0b00000000	/* Use set 1 of baud rates */
    .EQU BAUD_SET_2,	0b10000000	/* Use set 2 of baud rates */
    
    /* Exception Vector offsets and values */
    .EQU VEC_90, 		0x168	/* User exception vector */
    .EQU VEC_90_NUM, 	0x5A
    
    .EQU AUTOVEC_1, 	0x64	/* offset to autovector at priority level 1 */
    .EQU AUTOVEC_1_NUM, 	0x19
    
    /******************************************************************/
    
    .macro	LOCK
    	/* MOVE.W	SR,-(SP) */
    	ORI.W	#0x0700,SR
    .endm
    
    .macro	UNLOCK
            AND.W	#0xF8FF, SR 
    	/* MOVE.W	(SP)+,SR */
    .endm
    
    .globl DuartInit
    DuartInit:
    	LOCK			/* lock out H/W interrupts */
    	MOVEM.L D0/A0,-(SP)	/* save scratchpad registers */
    
    	LEA.L	DUART,A0	/* set up pointer A0 to DUART base address */
    
    	CLR.L	D0
    	ORI.B	#RESET_MR_PTR,D0  /* reset the MR pointer to MR1A and MR2A */
    	
            MOVE.B	D0,CRA(A0)	/* send reset MR ptr command to CRA */
    	MOVE.B	D0,CRB(A0)	/* send reset MR ptr command to CRB */
    	MOVE.B	#NO_CMD,CRA(A0)	/* remove command from CRA */
    	MOVE.B	#NO_CMD,CRB(A0)	/* remove command from CRB */
    
    	CLR.L	D0
    	ORI.B	#BITS_8,D0	/* use 8 bit data words */
    	ORI.B	#PAR_EVEN,D0	/* include even parity bit */
    	ORI.B	#RxRDY,D0	/* interrupts when receiver ready */
    	MOVE.B	D0,MR1A(A0)	/* initialize MR1A */
    
    	CLR.L	D0
    	ORI.B	#STOP_2,D0	/* 2.000 stop bits */
    	ORI.B	#CTS_Tx_CTL_OFF,D0  /* disable CTS H/W flow control input */
    	ORI.B	#RTS_Tx_CTL_OFF,D0  /* disable RTS H/W flow control output */
    	ORI.B	#MD_NORM,D0	/* enable normal duplex mode */
    	MOVE.B	D0,MR2A(A0)	/* initialize MR2A */
    
    	CLR.L	D0
    	ORI.B	#BITS_7,D0	/* use 7 bit data words */
    	ORI.B	#FORCE_PAR,D0	/* force a constant parity bit */
    	ORI.B	#FP_LOW,D0	/* parity bit is fixed low */
    	ORI.B	#RxRDY,D0	/* interrupts when receiver ready */
    	MOVE.B	D0,MR1B(A0)	/* initialize MR1B */
    
    	CLR.L	D0
    	ORI.B	#STOP_1_563,D0	/* 1.563 stop bits */
    	/* Note:  This is the closest available rate to 1.5 stop bits */
    	ORI.B	#CTS_Tx_CTL_OFF,D0  /* disable CTS H/W flow control input */
    	ORI.B	#RTS_Tx_CTL_OFF,D0  /* disable RTS H/W flow control output */
    	ORI.B	#MD_NORM,D0	/* enable normal duplex mode */
    	MOVE.B	D0,MR2B(A0)	/* initialize MR2B */
    
            /* Set baud rate for channel A to 19200 */
    	CLR.L	D0
    	ORI.B	#BAUD_SET_2,D0	  /* select set 2 baud rates */
    	MOVE.B	D0,ACR(A0)	  /* initialize ACR */
    	CLR.L	D0
    	ORI.B	#RxBAUD_19200,D0  /* Tx baud rate is set by TPU */
    	ORI.B	#TxBAUD_19200,D0  /* Rx baud rate is set by TPU */
    	MOVE.B	D0,CSRA(A0)	  /* initialize CSRA */
    
            /* Set baud rate for channel B to 38400 */
    	CLR.L	D0
    	ORI.B	#BAUD_SET_1,D0	  /* select set 1 baud rates */
    	MOVE.B	D0,ACR(A0)	  /* initialize ACR */
    	CLR.L	D0
    	ORI.B	#RxBAUD_38400,D0  /* Tx baud rate is set by TPU */
    	ORI.B	#TxBAUD_38400,D0  /* Rx baud rate is set by TPU */
    	MOVE.B	D0,CSRB(A0)	  /* initialize CSRB */
           
            /* NOTE:  This is probably an error in the assignment.  It
            seems likely that the DUART cannot simultaneously use both
            sets of baud rates for the different channels. */
    
    /* *****************  START INTERRUPT MASKS *********************** */ 
    	CLR.L	D0
    	/* ORI.B	#TxRDYA,D0	 enable Tx A interrupts */
    	/* ORI.B	#RxRDYA,D0	 enable Rx A interrupts */
            /* ORI.B	#TxRDYB,D0	 enable Tx B interrupts */
            /* ORI.B	#RxRDYB,D0	 enable Rx B interrupts */ 
            
    	MOVE.B	D0,IMR(A0)	/* initialize the IMR */
    	MOVE.B	D0,IMR_COPY	/* update copy of IMR */
            
    /* ***********************   END INTERRUPT MASKS *************************************** */
    
    	MOVE.B	#VEC_90_NUM, IVR(A0)	/* initialize the IVR */
    
    	CLR.L	D0
    	ORI.B	#RESET_Rx,D0	/* reset the receiver */
    	ORI.B	#RESET_Tx,D0	/* reset the transmitter */
    	ORI.B	#RESET_ERROR,D0	/* reset the error status */
    	MOVE.B	D0,CRA(A0)	/* send reset commands to CRA */
    	MOVE.B	D0,CRB(A0)	/* send reset commands to CRB */
    	MOVE.B	#NO_CMD,CRA(A0)	/* remove commands from CRA */
    	MOVE.B	#NO_CMD,CRB(A0)	/* remove commands from CRB */
    
    	CLR.L	D0
    	ORI.B	#ENABLE_Rx,D0	/* enable the receiver */
    	ORI.B	#ENABLE_Tx,D0	/* enable the transmitter */
    	MOVE.B	D0,CRA(A0)	/* send enable commands to CRA */
    	MOVE.B	D0,CRB(A0)	/* send enable commands to CRB */
    	MOVE.B	#NO_CMD,CRA(A0)	/* remove commands from CRA */
    	MOVE.B	#NO_CMD,CRB(A0)	/* remove commands from CRB */
            				   /* install the ISR vector */
            MOVE.L	#DuartISR, AUTOVEC_1
    	MOVE.B  ISR(A0), D0	/* read the ISR */
    	MOVEM.L (SP)+,D0/A0	/* restore scratchpad registers */
    	UNLOCK			/* re-enable H/W interrupts */
    	RTS
    

  2. Briefly describe the similarities and differences between routers, bridges and repeaters. In your answer make reference to the layers of the ISO OSI-RM model for data communications.

    Routers, bridges and repeaters are all devices that can be used to
    interface communication networks.  They differ in the extent to which
    they process protocols associated with the data packets.
    
    The lowest three layers of the ISO OSI-RM are: (1) the physical layer,
    (2) the data link layer, and (3) the network layer.  A repeater operates
    at the physical layer, and simply transfers all bits between the 
    connected networks.  A repeater is concerned only with preserving
    correct bit timing and the physical signal levels across the interface.
    
    A bridge can process the layer 2 data link protocol, as well as passing
    bits back and forth between the two connected networks.  This allows
    a bridge to do simple packet processing operations, such as filtering
    packets according to the destination address field.  This can be
    a useful operation for containing packet traffic withing different
    segments of a network.
    
    A router can process the layer 3 (and also layer 2 and 1) protocol.
    This allows a router to do even more complex packet processing than
    can a bridge.  The packet structure can be re-organized during passage
    between the networks.  This allows two networks of different packet
    formats (e.g. FDDI and Ethernet) to be interfaced.
    

  3. Briefly explain the different roles played by the IP and TCP layers in the TCP/IP protocol stack.

    The Internetworking Protocol (IP) layer is concerned primarily with
    the routing of data packets (datagrams in IP terminology) through
    the network from the source node to a specified destination node.
    IP includes a naming convention that associates unique IP addresses
    to each node in the Internet.  IP does not guarantee that a datagram
    will be delivered along any particular route between the source and
    the destination.  In fact, IP does not guarantee delivery at all.
    IP is allowed to break up user incoming packets into a sequence of
    shorter packets.  Each such packet is prepended with an IP header
    than contains information (e.g. source and destination node addresses)
    that is required for IP processing.
    
    The Transmission Layer Protocol (TCP) is built upon the services
    provided by the IP layer.  TCP turns the connectionless datagram
    service of IP into a connection-oriented service that reliably
    conveys a sequence of user data bytes from a port in the source node
    to a port in the receiver node.  TCP adds its own header to the
    user data packets so that the local TCP entities in the source
    and destination nodes will have the necessary information to
    operate the TCP protocol.  The data byte packet, together with the
    TCP header, is called a TCP segment.  The TCP header includes
    the source and destination port numbers, sequence numbers (used
    to preserve byte order), an acknowledgement number (used to detect 
    lost, out-of-order and repeated segments), and other fields.
    

  4. Error detection and correction actions can take place at different possible layers in the 7-layer ISO OSI-RM model. If the physical transmission medium is very reliable, would one wish to have the error detection and correction take place at a higher layer or a lower layer? Briefly justify your answer. Now consider the situation of a a physical transmission medium that is rather noisy and unreliable. At what layer would you now prefer to perform error detection and correction?

    Performing error detection and correction takes time, and so one
    would want to put this activity at a layer that guarantees an
    acceptable balance between processing time, and error detection
    and correction performance.
    
    If the transmission medium is very reliable, then it would be
    desirable to perform error detection and correction only at
    the end-points of a network connection.  In this way, unnecessary
    work is avoided at all intervening nodes.  Layers 4, 5, 6 and 7
    operate at the ends of a connection, and so they should be considered
    as the best place to implement error detection and correction.
    
    If the transmission medium is noisy and/or unreliable, then
    performing error detection and correction at only the extreme
    ends of a connection would be inefficient.  Much of the time,
    data will arrive at the destination node in a corrupted state
    using only end-point processing.  Layers 1, 2 and 3 operate
    between each pair of nodes in a route through a network.  
    Layer 1 would not be appropriate since it only sees individual
    bits.  Layers 2 (data link) would be the most appropriate
    layer for implementing error detection and correction at
    each node-to-node connection through the network.  Layer 3
    would likely be less desirable than layer 2 since layer 2
    only operates between adjacent nodes.
    

  5. Briefly explain why it might be preferable to use the UDP protocol instead of the TCP protocol for broadcasting audio and video information streams over the Internet.

    The assumption here is that, in multimedia (eg. audio and video)
    streams, it is not a serious matter if some of the datagrams
    occasionally get lost, get duplicated, or arrive out-of-order.
    If this assumption is true, then the transport layer needs to
    add very little in the way of services beyond what is already
    provided by IP.  This is clear from the very simple UDP header,
    which merely adds source and destination port numbers, an optional
    segment checksum, and a segment length.  In this sense, UDP is
    a "lightweight" protocol compared to the other major transport
    layer protocol, TCP.
    

  6. What were some of the major strategies and design techniques that were used by the designer of the "Lightweight IP" stack to make the software portable across different operating systems and hardware platforms. Which of this techniques were also used to make MicroC/OS-II portable across different processors?

    The major strategies and design techniques used in the lightweight
    IP stack (lwIP) are:
    
    1.  lwIP is written in ANSI C, which is very well supported across 
        different processor architectures.  So too is MicroC/OS-II.
    
    2.  lwIP needs only a small set of services from the host's operating
        system.  True too with MicroC/OS-II.
    
    3.  An operating system emulation layer is used to isolate the core
        functions of lwIP from the details of the host's operating system.
        Not applicable for MicroC/OS-II since MicroC/OS-II is the operating
        system.
    
    4.  As in the implementation of TCP/IP in Unix systems, device drivers
        are used to hide the details of the network interface hardware.
        All network interfaces can be accessed using the same device
        driver interface.  Not really applicable to MicroC/OS-II.  The
        CPU hardware is mostly hidden by the compiler.  The timer hardware
        is indeed hidden inside a driver in MicroC/OS-II.
    
    5.  Application programmers can use a simplified lwIP API, which
        insulates their code from the details of lwIP.  In MicroC/OS-II,
        the users must be familiar with the system calls, and those
        system calls do sometimes involve pointers to complex objects.
        However, the users are reasonably well shielded against having
        to know the internal field structure of those objects.
    

  7. Design an CPU32 assembly language program that implements a circular queue. The data elements in the queue are to be word-sized (16 bits wide). Two byte-sized flags are to be used to keep track of whether the buffer is full or empty. Two word-sized indexes are to be used to keep track of the queue locations where next data word is to be inserted, and where the next data word is to be read. Use traps to access the queue. A TRAP #4 is called with no parameters to initialize the circular queue. A TRAP #5 is used to read the next word in the queue. It returns -1 in D7.B if the circular queue is empty. It returns the data item in D0.W and has D7.B set to 0 if the circular queue was not empty when the trap was called. A TRAP #6 is used to write the next word in the queue. The data word to be inserted is passed in D0.W. This trap returns 0 in D7.B if the word was inserted successfully; otherwise, -1 is returned in D7.B. In your solution, be sure to include code that reserves memory locations for all required data structures. Express the size of the queue as a symbolic constant value.

    .equ    EMPTY_FLAG,	0           /* offset to empty flag */
    .equ    FULL_FLAG,	1           /* offset to full flag */
    .equ    READ_PTR,	2           /* offset to read ptr */
    .equ    WRITE_PTR,	4           /* offset to write ptr */
    
    QUEUE_BASE:
    .comm	2	/* space for two byte-sized flags */
    .comm	8	/* space for read and write long-sized pointers */
    ELEM_ARRAY:
    .org	ELEM_ARRAY + NUM_ELEMS
    
    /* The following code needs to be called in the system initialization */
            MOVE.L   #CircQInit,0x90    /* install TRAP #4 vector */
            MOVE.L   #CircQRead,0x94    /* install TRAP #5 vector */
            MOVE.L   #CircQWrite,0x98   /* install TRAP #6 vector */
    
    CircQInit:       /* TRAP #4 exception handling routine */
            MOVEM.L  A1,-(SP)             /* save regs */
    	LEA.L    QUEUE_BASE,A0
            CLR.B    EMPTY_FLAG(A0)
            CLR.B    FULL_FLAG(A0)
            CLR.W    READ_PTR(A0)
            CLR.W    WRITE_PTR(A0)
            MOVEM.L  (SP)+,A0             /* restore regs */
            RTE
    
    CircQRead:       /* TRAP #5 exception handling routine */
            MOVEM.L  A0-A1/D1,-(SP)       /* save regs */
    	LEA.L    QUEUE_BASE,A0
            TST.B    EMPTY_FLAG(A0)       /* is queue empty? */
            BNE      CANT_READ            /* yes, load error code */
                                          /* no, read old data */
            LEA.L    ELEM_ARRAY,A1
            MOVE.W   READ_PTR(A0),D1
            MOVE.W   (0,A1,D1.W*2),D0     /* read data from queue */
            ADDQ.W   #1,D1                /* increment read ptr */
            MOVE.W   D1,READ_PTR(A0)
    	CMPI.W   #NUM_ELEMS,D1        /* check for ptr wraparound */
            BLT      SKIP_RESET_READ_PTR
            CLR.W    READ_PTR(A0)         /* wrap around the read ptr */
    SKIP_RESET_READ_PTR:
            CLR.B    D7		      /* load success return code */
            BRA      EXIT_CIRCQWrite
    CANT_WRITE:
            MOVE.B   #-1,D7               /* load full buffer error code */
    EXIT_CIRCQWrite:
            MOVEM.L  (SP)+,A0-A1/D1       /* restore regs */
            RTE
    
    CircQWrite:      /* TRAP #6 exception handling routine */
            MOVEM.L  A0-A1/D1,-(SP)       /* save regs */
    	LEA.L    QUEUE_BASE,A0
            TST.B    FULL_FLAG(A0)        /* is queue full? */
            BNE      CANT_WRITE           /* yes, load error code */
                                          /* no, write new data */
            LEA.L    ELEM_ARRAY,A1
            MOVE.W   WRITE_PTR(A0),D1
            MOVE.W   D0,(0,A1,D1.W*2)     /* write the data word */
            ADDQ.W   #1,D1                /* increment write ptr */
            MOVE.W   D1,WRITE_PTR(A0) 
    	CMPI.W   #NUM_ELEMS,D1        /* check for ptr wrap-around */
            BLT      SKIP_RESET_WRITE_PTR
            CLR.W    WRITE_PTR(A0)        /* wrap around the write ptr */
    SKIP_RESET_WRITE_PTR:
            CLR.B    D7                   /* load success return code */
            BRA      EXIT_CIRCQWrite
    CANT_WRITE:
            MOVE.B   #-1,D7               /* load full buffer error code */
    EXIT_CIRCQWrite:
            MOVEM.L  (SP)+,A0-A1/D1       /* restore regs */
            RTE