#include "SharedMemory.h" #include "Serial.h" #include "I2C.h" // Count MAX_WAIT times before timing out #define MAX_WAIT 16383 // If greater than 0, it holds the number of bytes received from I2C level unsigned char SharedMemory_receivedSize; // True if a read is being attempted // False if read causes time out or read is returned successfully bit SharedMemory_attemptingRead; // True if responding to a read bit SharedMemory_respondingToRead; // True if a chat message has been received bit SharedMemory_receivedChatMessage; // Holds the size of a transmitted chat command unsigned char SharedMemory_transmitSize; // Holds the value assigned to shared memory during a write command unsigned char SharedMemory_writeValue; // Buffer to hold the received response from a read request unsigned char SharedMemory_receivedReadResponse[5]; // Buffer to hold the message that is sent in response to a read unsigned char SharedMemory_sendReadResponse[5]; // Buffer to hold message received from I2C level unsigned char SharedMemory_receiveBuffer[COMMAND_BUFFER_SIZE]; // Buffer to hold chat messages unsigned char SharedMemory_chatBuffer[COMMAND_BUFFER_SIZE]; // Buffer to hold the command entered (also used for transmitting to I2C) unsigned char SharedMemory_commandString[COMMAND_BUFFER_SIZE]; // Shared memory of a processor unsigned char SharedMemory_shared[SHARED_MEMORY_BYTES]; // Clear the local processor's shared memory (set it to zero) void SharedMemory_Zero() { unsigned char i; // Initialize the shared memory to 0 for(i = 0; i < SHARED_MEMORY_BYTES; i++) SharedMemory_shared[i] = 0; } // Display the contents of the local processor's shared memory void SharedMemory_View() { unsigned char i; // Initialize the shared memory to 0 for(i = 0; i < SHARED_MEMORY_BYTES; i++) { Serial_SendNewLine(); Serial_SendString("Processor <~",'~',80); Serial_SendCharacter(ADDRESS_SELF); Serial_SendString("> Memory <~",'~',80); Serial_SendDecimal(i); Serial_SendString("> = ~",'~',80); Serial_SendDecimal(SharedMemory_shared[i]); } Serial_SendNewLine(); Serial_SendNewLine(); } // Display the contents of the local memory location i void SharedMemory_Read(unsigned char i) { Serial_SendNewLine(); Serial_SendString("Processor <~",'~',80); Serial_SendCharacter(ADDRESS_SELF); Serial_SendString("> Memory <~",'~',80); Serial_SendDecimal(i); Serial_SendString("> = ~",'~',80); Serial_SendDecimal(SharedMemory_shared[i]); Serial_SendNewLine(); Serial_SendNewLine(); } // Write value to the local memory location i void SharedMemory_Write(unsigned char i, unsigned char value) { SharedMemory_shared[i] = value; } // Display the last received message void SharedMemory_DisplayReceive() { if(SharedMemory_receivedSize > 0) { Serial_SendNewLine(); Serial_SendString("To: ~",'~',80); Serial_SendCharacter(SharedMemory_receiveBuffer[0]); Serial_SendNewLine(); Serial_SendString("From: ~",'~',80); Serial_SendCharacter(SharedMemory_receiveBuffer[1]); Serial_SendNewLine(); Serial_SendString("Type: ~",'~',80); switch(SharedMemory_receiveBuffer[2]) { // READ case 'r': Serial_SendString("READ~",'~',80); Serial_SendNewLine(); Serial_SendString("Variable: ~",'~',80); Serial_SendDecimal(SharedMemory_receiveBuffer[3]); Serial_SendNewLine(); break; // RETURNED READ case 'R': Serial_SendString("RETURNED READ~",'~',80); Serial_SendNewLine(); Serial_SendString("Variable: ~",'~',80); Serial_SendDecimal(SharedMemory_receiveBuffer[3]); Serial_SendNewLine(); Serial_SendString("Value: ~",'~',80); Serial_SendDecimal(SharedMemory_receiveBuffer[4]); Serial_SendNewLine(); break; // WRITE case 'w': Serial_SendString("WRITE~",'~',80); Serial_SendNewLine(); Serial_SendString("Variable: ~",'~',80); Serial_SendDecimal(SharedMemory_receiveBuffer[3]); Serial_SendNewLine(); Serial_SendString("Assigned: ~",'~',80); Serial_SendDecimal(SharedMemory_receiveBuffer[4]); Serial_SendNewLine(); break; // CHAT case 'c': Serial_SendString("CHAT~",'~',80); Serial_SendNewLine(); Serial_SendString("Message: ~",'~',80); Serial_SendString(&SharedMemory_receiveBuffer[3],CARRIAGE_RETURN,SharedMemory_receivedSize-3); Serial_SendNewLine(); break; // ERROR default: Serial_SendString("ERROR - Unrecognized type!~",'~',80); Serial_SendNewLine(); break; } Serial_SendNewLine(); } else { Serial_SendNewLine(); Serial_SendString("No messages have been received.~",'~',80); Serial_SendNewLine(); Serial_SendNewLine(); } } // Display an error message for an unrecognized command void SharedMemory_CommandError() { Serial_SendNewLine(); Serial_SendString("Unrecognized command (type '?' for command syntax).~",'~',80); Serial_SendNewLine(); Serial_SendNewLine(); } // Initialize variables, serial interface, and I2C devices // Display program name, authors, etc... void SharedMemory_Init() { Serial_Init(BAUD_RATE_9600); I2C_Init(ADDRESS_SELF,SharedMemory_receiveBuffer); SharedMemory_respondingToRead = 0; SharedMemory_attemptingRead = 0; SharedMemory_receivedSize = 0; SharedMemory_receivedChatMessage = 0; SharedMemory_Zero(); Serial_SendNewLine(); Serial_SendNewLine(); Serial_SendString("***********************************************************~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** I2C Chat 1.30 ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** Final Project ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** CSE 466 Autumn 2001 ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** Michael Fernandes ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** Shirley Gaw ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** Type '?' for command syntax ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ***~",'~',80); Serial_SendNewLine(); Serial_SendString("***********************************************************~",'~',80); Serial_SendNewLine(); Serial_SendNewLine(); } // Display help (describes command syntax) void SharedMemory_Help() { Serial_SendNewLine(); Serial_SendString("***********************************************************~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** COMMANDS ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** HELP: '?' ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** PING: 'P' ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ZERO: 'Z' ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** VIEW: 'V' ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** CHAT:
'c' ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** READ:
'r' ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** WRITE:
'w' ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** Entering nothing displays the last message received ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** PARAMETERS ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** ***~",'~',80); Serial_SendNewLine(); Serial_SendString("***
- address of processor ('a' to 'z') ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** - memory location ('0' to '9') ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** - message to send ***~",'~',80); Serial_SendNewLine(); Serial_SendString("*** - value to assign ('0' to '255') ***~",'~',80); Serial_SendNewLine(); Serial_SendString("***********************************************************~",'~',80); Serial_SendNewLine(); Serial_SendNewLine(); } // Give the user a prompt to enter commands and parse the commands void SharedMemory_Input() { unsigned char i; unsigned int waitCount; Serial_SendString("I2C Chat ~",'~',80); Serial_SendCharacter(ADDRESS_SELF); Serial_SendString(":\> ~",'~',80); Serial_ReceiveString(SharedMemory_commandString,CARRIAGE_RETURN,COMMAND_BUFFER_SIZE); while(SERIAL_getReceivingString()) { // Handle the request to respond to a read if(SharedMemory_respondingToRead) { // No longer responding to a read SharedMemory_respondingToRead = 0; I2C_Transmit(SharedMemory_sendReadResponse[0], SharedMemory_sendReadResponse, 5); } // Display the chat message if(SharedMemory_receivedChatMessage) { Serial_SendNewLine(); Serial_SendNewLine(); Serial_SendString("Message from ~",'~',80); Serial_SendCharacter(SharedMemory_chatBuffer[1]); Serial_SendString(": ~",'~',80); Serial_SendString(&SharedMemory_chatBuffer[3],CARRIAGE_RETURN,SharedMemory_receivedSize-3); Serial_SendNewLine(); Serial_SendNewLine(); Serial_SendString("I2C Chat cont... ~",'~',80); Serial_SendCharacter(ADDRESS_SELF); Serial_SendString(":\> ~",'~',80); SharedMemory_receivedChatMessage = 0; } } Serial_SendNewLine(); if(SharedMemory_commandString[0] == CARRIAGE_RETURN) { SharedMemory_DisplayReceive(); } else if(SharedMemory_commandString[0] == '?') { if(SharedMemory_commandString[1] != CARRIAGE_RETURN) { SharedMemory_CommandError(); return; } else { SharedMemory_Help(); return; } } else if(SharedMemory_commandString[0] == 'Z') { if(SharedMemory_commandString[1] != CARRIAGE_RETURN) { SharedMemory_CommandError(); return; } else { SharedMemory_Zero(); return; } } else if(SharedMemory_commandString[0] == 'V') { if(SharedMemory_commandString[1] != CARRIAGE_RETURN) { SharedMemory_CommandError(); return; } else { SharedMemory_View(); return; } } else if(SharedMemory_commandString[0] == 'P') { if(SharedMemory_commandString[1] != CARRIAGE_RETURN) { SharedMemory_CommandError(); return; } SharedMemory_commandString[1] = ADDRESS_SELF; SharedMemory_commandString[2] = 'r'; SharedMemory_commandString[3] = 0; Serial_SendNewLine(); Serial_SendString("Searching for processors: a b c d e f g h i j k l m n o p q r s t u v w x y z~",'~',80); Serial_SendNewLine(); Serial_SendString("Marked with 'X' if found: ~",'~',80); // PING for(i = 'a'; i <= 'z'; i++) { // Don't need to ping yourself if(i == ADDRESS_SELF) { Serial_SendString("X ~",'~',80); continue; } SharedMemory_commandString[0] = i; // About to attempt a read SharedMemory_attemptingRead = 1; I2C_Transmit(SharedMemory_commandString[0], SharedMemory_commandString, 4); // Attempt to read until waitCount exceeds MAX_WAIT waitCount = 0; while(SharedMemory_attemptingRead) { if(waitCount < MAX_WAIT) { waitCount++; } else { Serial_SendString(". ~",'~',80); // No longer attempting a read SharedMemory_attemptingRead = 0; break; } } if(waitCount < MAX_WAIT) { Serial_SendString("X ~",'~',80); } } Serial_SendNewLine(); Serial_SendNewLine(); } else if(SharedMemory_commandString[0] < 'a' || SharedMemory_commandString[0] > 'z') { Serial_SendNewLine(); Serial_SendString("Invalid address (must be from 'a' to 'z').~",'~',80); Serial_SendNewLine(); Serial_SendNewLine(); } else { if(SharedMemory_commandString[1] != ' ') { SharedMemory_CommandError(); return; } SharedMemory_commandString[1] = ADDRESS_SELF; switch(SharedMemory_commandString[2]) { // READ case 'r': if(SharedMemory_commandString[0] == ADDRESS_SELF) { if(SharedMemory_commandString[3] != ' ' || SharedMemory_commandString[4] > '9' || SharedMemory_commandString[4] < '0' || SharedMemory_commandString[5] != CARRIAGE_RETURN) { SharedMemory_CommandError(); return; } else { SharedMemory_Read(SharedMemory_commandString[4] - '0'); return; } } else { if(SharedMemory_commandString[3] != ' ' || SharedMemory_commandString[4] > '9' || SharedMemory_commandString[4] < '0' || SharedMemory_commandString[5] != CARRIAGE_RETURN) { SharedMemory_CommandError(); return; } else { SharedMemory_commandString[3] = SharedMemory_commandString[4] - '0'; // About to attempt a read SharedMemory_attemptingRead = 1; I2C_Transmit(SharedMemory_commandString[0], SharedMemory_commandString, 4); // Attempt to read until waitCount exceeds MAX_WAIT waitCount = 0; while(SharedMemory_attemptingRead) { if(waitCount < MAX_WAIT) { waitCount++; } else { // No longer attempting a read SharedMemory_attemptingRead = 0; Serial_SendNewLine(); Serial_SendString("Read timed out, please try again later.~",'~',80); Serial_SendNewLine(); Serial_SendNewLine(); return; } } Serial_SendNewLine(); Serial_SendString("Processor <~",'~',80); Serial_SendCharacter(SharedMemory_receivedReadResponse[1]); Serial_SendString("> Memory <~",'~',80); Serial_SendDecimal(SharedMemory_receivedReadResponse[3]); Serial_SendString("> = ~",'~',80); Serial_SendDecimal(SharedMemory_receivedReadResponse[4]); Serial_SendNewLine(); Serial_SendNewLine(); return; } } break; // WRITE case 'w': if(SharedMemory_commandString[0] == ADDRESS_SELF) { if(SharedMemory_commandString[3] != ' ' || SharedMemory_commandString[4] > '9' || SharedMemory_commandString[4] < '0') { SharedMemory_CommandError(); return; } else { if(SharedMemory_commandString[5] != ' ') { SharedMemory_CommandError(); return; } else { SharedMemory_writeValue = 0; // very poor error checking here, but it will only assign a bad value for(i = 6; SharedMemory_commandString[i] != CARRIAGE_RETURN; i++) { SharedMemory_writeValue *= 10; SharedMemory_writeValue += SharedMemory_commandString[i] - '0'; } SharedMemory_Write(SharedMemory_commandString[4] - '0',SharedMemory_writeValue); return; } } } else { if(SharedMemory_commandString[3] != ' ' || SharedMemory_commandString[4] > '9' || SharedMemory_commandString[4] < '0') { SharedMemory_CommandError(); return; } else { if(SharedMemory_commandString[5] != ' ') { SharedMemory_CommandError(); return; } else { SharedMemory_writeValue = 0; // very poor error checking here, but it will only assign a bad value for(i = 6; SharedMemory_commandString[i] != CARRIAGE_RETURN; i++) { SharedMemory_writeValue *= 10; SharedMemory_writeValue += SharedMemory_commandString[i] - '0'; } SharedMemory_commandString[3] = SharedMemory_commandString[4] - '0'; SharedMemory_commandString[4] = SharedMemory_writeValue; I2C_Transmit(SharedMemory_commandString[0], SharedMemory_commandString, 5); return; } } } break; // CHAT case 'c': if(SharedMemory_commandString[0] == ADDRESS_SELF) { // Do nothing for now, need to fix this up Serial_SendNewLine(); Serial_SendString("Stop sending yourself messages!~",'~',80); Serial_SendNewLine(); Serial_SendNewLine(); return; } else { if(SharedMemory_commandString[3] != ' ') { SharedMemory_CommandError(); return; } SharedMemory_transmitSize = 0; while(SharedMemory_commandString[SharedMemory_transmitSize+4] != CARRIAGE_RETURN) { SharedMemory_commandString[SharedMemory_transmitSize+3] = SharedMemory_commandString[SharedMemory_transmitSize+4]; SharedMemory_transmitSize++; } if(SharedMemory_transmitSize > 0) I2C_Transmit(SharedMemory_commandString[0], SharedMemory_commandString, SharedMemory_transmitSize+3); else SharedMemory_CommandError(); return; } break; default: SharedMemory_CommandError(); return; } } } // Interrupt handler called from I2C when a receive has completed void SharedMemory_Receive(unsigned char* receiveBuffer, unsigned char size) { unsigned char i; SharedMemory_receivedSize = size; // Handle message switch(SharedMemory_receiveBuffer[2]) { // READ case 'r': // If already responding to a read, ignore all incoming read requests (will cause reqeuster to timeout) if(!SharedMemory_respondingToRead) { // Prepare a message to respond to the read request SharedMemory_sendReadResponse[0] = receiveBuffer[1]; SharedMemory_sendReadResponse[1] = receiveBuffer[0]; SharedMemory_sendReadResponse[2] = 'R'; SharedMemory_sendReadResponse[3] = receiveBuffer[3]; SharedMemory_sendReadResponse[4] = SharedMemory_shared[receiveBuffer[3]]; SharedMemory_respondingToRead = 1; } break; // WRITE case 'w': SharedMemory_Write(receiveBuffer[3],receiveBuffer[4]); break; // CHAT case 'c': // If already receiving a chat message, ignore all incoming messages if(!SharedMemory_receivedChatMessage) { for(i = 0; i < size; i++) SharedMemory_chatBuffer[i] = receiveBuffer[i]; SharedMemory_receivedChatMessage = 1; } break; // RETURNED READ case 'R': // Buffer the read response to dislay the results SharedMemory_receivedReadResponse[0] = receiveBuffer[0]; SharedMemory_receivedReadResponse[1] = receiveBuffer[1]; SharedMemory_receivedReadResponse[2] = receiveBuffer[2]; SharedMemory_receivedReadResponse[3] = receiveBuffer[3]; SharedMemory_receivedReadResponse[4] = receiveBuffer[4]; // No longer attempting a read SharedMemory_attemptingRead = 0; break; // ERROR default: break; } }