jazzman, afterburn ,and surfingcat have made a collaborative effort to set the microcontroller to send data out via serial COM to the router.
teknick had code written for sending data of type char, string, and large buffer. There is a different call function for each one. Make sure you call the setup_SCI2_to_TX() function in main before you call any of the data output functions. Also, put the typedef into the header file.
//put these defines wherever they should be and use them well:
typedef unsigned char UINT8;
typedef unsigned short UINT16;
typedef unsigned long UINT32;
typedef signed char INT8;
typedef short INT16;
typedef long int INT32;
//call this to set up serial port 2 to 104 kbaud:
void setup_SCI2_to_TX(void)
{
SCI2C1 = 0x00;
SCI2C2 = 0x2C; //Note: New Change to activate receiver interrupt
SCI2BDH = 0x00;
SCI2BDL = 0x0B;
}
// send a single byte out serial port 2
void send_byte_SCI2(UINT8 c)
{
while(!(SCI2S1 & 0x80));
SCI2D = c;
}
// Send a string out serial port 2 (think of it as puts() without /n at end
void Terminal_Send_String(const UINT8* s)
{
__RESET_WATCHDOG();
for(;*s;s++)
send_byte_SCI2(*s);
}
// send a buffer as hex digits
void send_buffer_hex(const UINT8* buf,UINT16 size)
{
UINT16 j;
for (j=0;j<size;j++)
{
Terminal_Send_String_As_Hex(&buf[j],1);
Terminal_Send_Byte(' ');
}
Terminal_Send_String("\n\r");
}
//send a string as hex digits
void Terminal_Send_String_As_Hex(const UINT8* str, UINT16 len)
{
UINT16 x;
UINT8 t;
for(x=0; x < len; x++)
{
t = (str[x]>>0x04) + 0x30; // convert MSN 'n' to ascii
if (t > 0x39) t+=0x07; // correct for gap between '9' and 'A'
Terminal_Send_Byte(t);
t = (str[x] & 0x0f) + 0x30; // convert to ascii
if(t > 0x39) t+=0x07; // correct for gap between '9' and 'A'
Terminal_Send_Byte(t);
}
}
Thank you teknick!!! We are currently working on the receiving data functions. These will help us be able to have the router have special control of the microcontroller.
hal0 and jazzman have formed the Tx output function for every type of function. For each of the sensor teams, you will need to eventually call this function when your data is ready to be outputted via serial COM.
/***************************************************************************/
// Send a SensorWord over the serial line
/***************************************************************************/
void sendWord(SensorWord sword)
{
UINT8 sendString[3];
sendString[0] = sword.raw.byte0;
sendString[1] = sword.raw.byte1;
sendString[2] = '\0'; //NULL terminating character
Terminal_Send_String(sendString);
}
The SensorWord type can be found in hal0's blog. Once your data is formatted for type SensorWord, it can transmitted via serial using this function.
The receiver will only be active when the rx interrupt is triggered. This occurs when data is sent into the serial port data register (SCI2D), where an automatic flag (data received) is set high, telling the system to enter the rx interrupt service routine. Also, note that the echo capability has been commented out for right now because we are testing currently that one byte can be transmitted and received by the microcontroller and that this data can also be manipulated.
Note that above in the transmitting code, the setup_SCI2_to_TX() for the control register was changed to: SCI2C2 = 0x2C. The change adds receiver interrupt functionality. There is also a transmitting interrupt enabled.
void interrupt VectorNumber_Vsci2rx ReceiveByte() {
buffer = SCI2D;
//SCI2D = SCI2D; //Echo the data has been received
LED1 = 0;
// send_byte_SCI2(buffer);
}
Final note: The microcontroller will connect to the router via port Cl, bits 0 and 1. PTCD0 is the transmitting pin, and PTCD1 is the receiving pin. Thank you.
We will use a sentinel (semi-colon(;)) for receiving data from the microcontroller. This will be easy to know when an inputed command is complete. jazzman will put the code up tomorrow morning.
void interrupt VectorNumber_Vsci2rx ReceiveByte() {
while(!SCI2S1_RDRF); //wait for receive
if(SCI2D != ';') { //we are using the semi-colon as a sentinel
rxbuffer[rx_buf_write_pointer++] = SCI2D; //move along buffer
LED1 = 0;
if(rx_buf_write_pointer >= BUF_SIZE) rx_buf_write_pointer = 0; //check that the input string is not bigger than array size
}
else {
rx_buf_write_pointer = 0;
command = interpret_rxbuffer(rxbuffer); //Copy rxbuffer for string input to command
}
//SCI2D = SCI2D; //Echo that the data has been received
//Terminal_Send_String("I can has rob3ars pr0n?\r\n");
//Terminal_Send_String(rxbuffer);
}
The following function will interpret the received code by copying it into a new array and be accessed using a 'command' pointer.
UINT8* interpret_rxbuffer( UINT8* c ) {
UINT8 inputCommand[BUF_SIZE];
UINT8 index = 0;
while( c[index] != ';') {
inputCommand[index] = c[index];
index++;
}
return inputCommand;
}
Previously, we were going to use a buffer to take input commands. While this worked, it was unnecessary. Instead, we will use a SWITCH cases for single byte commands. There is a ASCII shift of '48' so that an inputted character '0' will have the numeric value 0. When a specific input is provided from the router, a corresponding flag and function will be called. Right now all the functions are dummy functions. They will eventually be replaced by the real functions written by other team members.
/***************************************************************************/
// Receive (Rx) Interrupt Service Routine
/***************************************************************************/
void interrupt VectorNumber_Vsci2rx ReceiveByte() {
while(!SCI2S1_RDRF); //Wait for SCI2D register to be complete
command = SCI2D;
command = command - 48; //shift input so that '0' is the number 0, '1' is 1, '2' is 2, ...
switch(command) {
case DLEVEL:
dLevelFlag = 1;
tripsFlag = 0;
micFlag = 0;
stopFlag = 0;
break;
case TRIPS:
dLevelFlag = 0;
tripsFlag = 1;
micFlag = 0;
stopFlag = 0;
break;
case MIC:
dLevelFlag = 0;
tripsFlag = 0;
micFlag = 1;
stopFlag = 0;
break;
case STOP:
dLevelFlag = 0;
tripsFlag = 0;
micFlag = 0;
stopFlag = 1;
break;
default:
doNothing = 1;
}
//SCI2D = SCI2D; //Echo that the data has been received
}
| Input Character | Operation | C Code Flag Triggered |
|---|---|---|
| 0 | Return Danger Level | DLEVEL |
| 1 | Return Trip Wire Data | TRIPS |
| 2 | Return Mic Analysis | MIC |
| 3 | Return to Low-Power Mode | STOP |
More commands and corresponding input characters will follow. jazzman will update this as soon as our analysis techniques are finalized.
If you are connecting between the micocontroller and router , make sure the board has the following setting: Check for the five 2-bit pins under the name COM_EN on the GB60 microcontroller. They should have the following grouping, otherwise the receive pin will have a DC offset.
Note: If you are testing between two microcontrollers or a microcontroller and a computer, the five sets of pins must all be parallel.