CPR E 381x/382x - Lab13a

Messaging Service

 

1. Objectives

This lab involves writing a relatively large program using assembly language. As a result, it is expected to pull you up the learning curve, by putting into practice topics that have been discussed in lecture as well as by building upon skills used in the lab. This lab also introduces you to managing a data buffer between I/O devices.

 

1.1 Reference Files for Lab

Lab Evaluation Form

 

2. Prelab

Make sure you have a good understanding of the topics covered in lab 12a.  Specifically the use of the COM port to read and write data will be used extensively in this lab.  If you have any questions, please do not hesitate to ask you lab instructor.

3. Setup

As you did in previous labs, make sure you create the folder in your home directory U:\CPRE381\Labw13a to save all your work from this lab.

 

A. Text Buffer: Buffering Data Between Input and Output

Write an assembly program that reads a key from the QTerm keypad, puts the key into a data buffer, and writes it to the QTerm LCD display. If bit 7 of DIP Switch 1 is set, send the data to the display – that is, output is active. If bit 7 of DIP Switch 1 is not set, do not send the data to the display – that is, output is suspended. Input remains active. No data should be lost.

·         You should modify your code from Lab 12a.

Design Components

·         data buffer - QTBufferIn (for characters from QTerm Keypad)

·         position variables for the buffer

·         input position, i.e., where the next character read in goes

·         output position, i.e., where the next character to be output comes from

·         function Read_QTerm - Reads up to 1 character from COM2 (QTerm) and places the character into a buffer 

·         function Write_QTerm - Writes up to 1 character to the QTerm LCD from a buffer

Consider the buffer depicted below.

location 0

 

 

 

 

next input ê

 

 

 

location N-1

3

A

8

9

F

 

 

 

 

é buffer begin

 

 

é next output

 

 

 

 

 

é buffer end

The buffer is of size N characters (bytes). The first character typed on the keypad was ‘3’, placed in location 0 of the buffer. The next character was ‘A’, at location 1, or an offset of 1 past buffer begin. Assume that five characters have been typed in and added to the buffer, and only three characters have been sent to the display so far, i.e., the display reads “3A8”. As a result, the next input location is 5, and the next output location is 3. The buffer could be viewed as an array in C, as follows:

·        char buffer [N]

·        int position

·        buffer[position] denotes an element of the buffer; so for position = 5, gives the element for the next character received from the keypad; for position = 3, gives the element for the next character to send to the display

·        buffer itself is the address of the array in memory; so buffer+5 is the address of the next input location; buffer+3 is the address of the next output location

Notice that the next input is always greater than or equal to the next output. If next input = next output, then all characters have been displayed.  Your program should work if, for example, output is temporarily suspended, such that new characters received increment next input while next output remains the same.

You should consider and implement a solution to how to deal with the case when next input is past the end of the buffer, as well as a full buffer.

Code Snippets

Several coding examples related to this program are shown below. These are separate fragments.

.data

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

; Memory allocation for data

;

QT_In_Pos:             

      .short 0                ; short global variable for input position

QT_Out_Pos:

      .short 0                ; short global variable for output position

QTBufferIn:

      .space 512              ; 512 bytes of storage space for data buffer from QTerm

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

; r21  = key pressed on QTerm

; r22 = address of QTBufferIn array

; r23 = address of QT_In_Pos

; r24 = value of QT_In_Pos

...

Add_Key_Buffer:

      ; Store key pressed (r21) to QTBufferIn + QT_In_Pos

      stbx  r21, r22, r24           ; r21 -> M[r22 + r24]

      ; Write QT_In_Pos + 1 to move position for added character 

      addi  r24, r24, 1             ; increment the QT_In_Pos by 1

      sth   r24, 0(r23)             ; store QT_In_Pos to address in r23

; r15 = address of QT_Out_Pos

; r16 = value of QT_Out_Pos

; compare the buffer input and output positions

...

      ; Get value of QT_In_Pos and place in r24

      lhz   r24, 0(r23)       ; r24 <- M[r23 + 0]

      ; Get value of QT_Out_Pos and place in r16

      lhz   r16, 0(r15)       ; r16 <- M[r15 + 0]

      ; Compare QT_In_Pos and QT_Out_Pos

      cmpw  r24, r16

      ; Branch if QT_In_Pos <= QT_Out_Pos, i.e., no data to output, already done

      ble   QTerm_NoOutput

Compile, debug, and test the buffer code. Demonstrate the program to the TA.

B. Two Way Messaging

In the remainder of this lab, you will be designing a messaging service. The QTerm unit will be used as a terminal in a tractor for communicating with a remote station.  Using the QTerm terminal, a farmer or service technician in the field can report and retrieve information to/from a remote computer – at home, in the shop, or even in another tractor.  In the actual system, information would be sent via either a wireless-based networking protocol (e.g., IEEE 802.11) or a cellular dialup connection.  In the lab, we will be emulating the remote station and wireless interface using the desktop PC, HyperTerminal, and serial communication.

 

 


 

Messages can be sent in either direction.  For example, when the user types in a message at the QTerm keypad, the information is sent to the PC.  Messages move from right to left in the illustration above, read from the keypad over COM2, put in the QTBuffer, and written to the HyperTerminal over COM1. Alternatively, when the user types in a message at the HyperTerminal keyboard, the information is sent to the QTerm LCD.  Messages move from left to right in the illustration above, read from the PC keyboard over COM1, put in the PCBuffer, and written to the QTerm LCD over COM2. Messages can be simultaneously typed in. Message data should not be lost.

You will need to extend the code developed in Section 2 of this lab to include two data buffers.  Each data buffer is handled with its own read and write functions and respective serial ports. Data is added to QTBuffer from COM2, and removed onto COM1; vice versa for PCBuffer.

2.      There are two steps to this part of the lab: Activity 1 and Activity 2.

Activity 1: Write assembly code to implement the QTBuffer and messaging from the QTerm to the HyperTerminal.

·        Reuse the code to read the QTerm; write a new function to write to the HyperTerminal.

·        Be sure to use the correct COM ports.

Activity 2: Write assembly code to implement the PCBuffer and messaging from the HyperTerminal to the QTerm.

·        Reuse the code to write the QTerm; write a new function to read from the HyperTerminal.

·        Be sure to use the correct COM ports.

The behavior of the software system can be partitioned as follows:

·         Reading QTerm for input from its keypad (COM2)

·         Reading the PC for input from the keyboard (COM1)

·         Writing information to the QTerm (COM2)

·         Writing information to the PC (COM1)

Design Components

·         2 buffers - QTBuffer, PCBuffer

·         Position variables for the buffers (i.e., where to put/get next data)

·         Read_QTerm - Reads up to 1 character from COM2 (QTerm) and places the character into a buffer 

·         Read_PC - Reads up to 1 character from COM1 and places the character into a buffer

·         Write_PC - Writes up to 1 character to the PC via COM1

·         Write_QTerm - Writes up to 1 character to the QTerm LCD via COM2

Code Structure

Set up the code to read/write only one character at a time over a serial connection per pass through the main loop, repeatedly calling the functions to read and write characters.

MainLoop:

Call Read_QTerm
Call Read_PC
Call Write_QTerm
Call Write_PC

b MainLoop

All functions should be non-blocking, meaning that they should not loop inside of the function until a QTerm or HyperTerm character is pressed - they should return in some fairly quick amount of time.

 

Compile, debug, and test the text messaging code. Demonstrate the program to the TA.

REMINDERS

The actual setup for the serial ports will still be done using the same methods as in previous labs.  Be sure to call LCD_Init and PC_Init.  These two functions initialize the serial ports to 9600 baud (bps) and clear out any outstanding communications that are pending. 

Serial I/O Addresses

COM1 - Connected to PC

Name

Address

Description

Com1Status

0x0030500C

COM1 Status (16 bits)
  - Bit 8 - Ready to transmit/send/write
  - Bit 6 - Ready to receive/read

Com1Data

0x0030500E

COM1 Data (16 bits)
  - Only use the lower 8 bits

COM2 - Connected to QTerm

Name

Address

Description

Com2Status

0x00305024

COM2 Status (16 bits)
  - Bit 8 - Ready to transmit/send/write
  - Bit 6 - Ready to receive/read

Com2Data

0x00305026

COM2 Data (16 bits)
  - Only use the lower 8 bits