// This is the actual task that is run static portTASK_FUNCTION( vConductorUpdateTask, pvParameters ) { uint8_t rxLen, status; uint8_t Buffer[vtI2CMLen]; uint8_t *valPtr = &(Buffer[0]); // Get the parameters vtConductorStruct *param = (vtConductorStruct *) pvParameters; // Get the I2C device pointer vtI2CStruct *devPtr = param->dev; // Get the LCD information pointer vtVoltStruct *voltData = param->voltData; uint8_t recvMsgType; // Like all good tasks, this should never exit for(;;) { // Wait for a message from an I2C operation if (vtI2CDeQ(devPtr,vtI2CMLen,Buffer,&rxLen,&recvMsgType,&status) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } // Decide where to send the message // This just shows going to one task/queue, but you could easily send to // other Q/tasks for other message types // This isn't a state machine, it is just acting as a router for messages switch(recvMsgType) { case vtI2CMsgTypeVoltInit: { SendVoltValueMsg(voltData,recvMsgType,Buffer,0,portMAX_DELAY); break; } case vtI2CMsgTypeVoltRead: { SendVoltValueMsg(voltData,recvMsgType,Buffer,8,portMAX_DELAY); break; } default: { VT_HANDLE_FATAL_ERROR(recvMsgType); break; } } } }
portTASK_FUNCTION(sensorimotorTask, pvParameters) { uint8_t rxLen, status; uint8_t buffer[I2C_MAX_LEN]; struct SensorimotorParams * params = (struct SensorimotorParams *) pvParameters; vtI2CStruct * i2cDev = params->i2cDev; // LCD Information Pointer struct localizationParams * localization = params->localization; enum sensorType receivedMessageType; for (;;) { if (vtI2CDeQ(i2cDev, I2C_MAX_LEN, buffer, &rxLen, &receivedMessageType, &status) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } struct sensorMessage message; message.messageID = buffer[0]; message.type = receivedMessageType; memcpy(message.values, &buffer[3], SENSOR_MESSAGE_LEN); message.updateMask = (buffer[1] << 8) | (buffer[2] << 8); switch(receivedMessageType) { case STATUS: sendLocalizationSensorMessage(localization, &message, portMAX_DELAY); break; default: VT_HANDLE_FATAL_ERROR(receivedMessageType); break; } } }
// This is the actual task that is run static portTASK_FUNCTION( I2CTask, pvParameters ) { portTickType xUpdateRate, xLastUpdateTime; const uint8_t ReturnADCValue = 0xAA; //const uint8_t InsteonReserved; //reserved for Insteon if we are only requesting insteon data //uint8_t InsteonSendValue[12]; //reserved for Insteon send uint8_t MidiSendCount = 1; uint8_t MidiSendValue[9] = {0xAF, 0x80, 0x64, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00}; uint8_t InstSendValue[9] = {0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; int msgcount = 0; uint8_t temp1, rxLen, status; uint8_t ADCValueReceived[12]; uint8_t MidiReceived[2]; // Get the parameters i2cParamStruct *param = (i2cParamStruct *) pvParameters; // Get the I2C device pointer vtI2CStruct *devPtr = param->i2cDev; // Get the LCD information pointer vtLCDMsgQueue *lcdData = param->lcdQ; vtLCDMsg lcdBuffer; MasterMsgQueue * masterData = param->masterQ; MasterMsgQueueMsg masterBuffer; I2CMsgQueue * i2cQ = param->i2cQ; I2CMsgQueueMsg i2cBuffer; vTaskDelay(10/portTICK_RATE_MS); xUpdateRate = i2cREAD_RATE_BASE / portTICK_RATE_MS; /* We need to initialise xLastUpdateTime prior to the first call to vTaskDelayUntil(). */ xLastUpdateTime = xTaskGetTickCount(); for(;;) { //delay for some amount of time before looping again //vTaskDelayUntil( &xLastUpdateTime, xUpdateRate ); //Send a request to the PIC for ADC values if (vtI2CEnQ(devPtr,0x01,0x4F,1,&ReturnADCValue,12) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } //wait for message from I2C //bit0 is first portion of ADC value //bit1 is last portion of ADC value //bit2 is timer value //bit3 thru bit7 are garbage (all 0's) //bit8 is the size of the Midi buffer on the PIC //bit9 is the count //bit10 is the ADC channel number //bit11 is the OPCode we sent (0xAA) if (vtI2CDeQ(devPtr,12,&ADCValueReceived[0],&rxLen,&status) != pdTRUE) { //VT_HANDLE_FATAL_ERROR(0); } //check the message returned for errors: //0xAA signifying it's the correct op-code, verify the ADC is in the right order, //ensure the proper range of channel numbers is used. if ((ADCValueReceived[11] != 0xAA || ADCValueReceived[0] > 3 || ADCValueReceived[10] < 0 || ADCValueReceived[10] > 5) && ADCValueReceived[11] != 0xBB) { FlipBit(6); } else { //check the inbound i2c message queue from messages either from the Main Thread or the LCD //thread. Forward them to the PIC depending on op-code if (ADCValueReceived[8] < 4 && uxQueueMessagesWaiting(i2cQ->inQ) > 0)//check for room on the PIC and if a message exists { if (xQueueReceive(i2cQ->inQ,(void *) &i2cBuffer,portMAX_DELAY) != pdTRUE) //receive message from message queue { VT_HANDLE_FATAL_ERROR(0); } /*if (i2cBuffer.buf[0] == 0x13) { InstSendValue[0] = i2cBuffer.buf[0]; InstSendValue[1] = 0x02; InstSendValue[2] = 0x62; InstSendValue[3] = 0x12; InstSendValue[4] = 0x07; InstSendValue[5] = 0x4F; InstSendValue[6] = 0x00; InstSendValue[7] = 0x11; InstSendValue[8] = i2cBuffer.buf[1]; if (i2cBuffer.buf[1] == 8) FlipBit(3); if (vtI2CEnQ(devPtr,0x00,0x4F,9,InstSendValue,0) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } //wait for message from I2C if (vtI2CDeQ(devPtr,0,&MidiReceived[0],&rxLen,&status) != pdTRUE) { //VT_HANDLE_FATAL_ERROR(0); } } */ else if (i2cBuffer.buf[0] == 0x4) //MIDI message to be forwarded { MidiSendValue[1] = i2cBuffer.buf[1]; //Here are the three MIDI control bytes sent MidiSendValue[2] = i2cBuffer.buf[2]; //They are formulated in the mainthread and sent here MidiSendValue[3] = i2cBuffer.buf[3]; //Midi message to I2C to the PIC, there is also a count to maintain messages if (MidiSendCount > 100) MidiSendCount = 1; MidiSendValue[4] = MidiSendCount; if (vtI2CEnQ(devPtr,0x00,0x4F,9,MidiSendValue,0) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } //wait for message from I2C if (vtI2CDeQ(devPtr,0,&MidiReceived[0],&rxLen,&status) != pdTRUE) { //VT_HANDLE_FATAL_ERROR(0); } //Whenever a "note on" message is being sent to the MIDI device, we want to update the LED display as well //this checks the command portion of the MIDI message then changes the LED accordingly. The 0x90 signifies //that the message came from instrument 1 since it operates on MIDI channel 0; 0x91 means Instrument 2 since //it operates on MIDI channel 1 if (i2cBuffer.buf[1] == 0x90) { if (i2cBuffer.buf[2] == 60) InstSendValue[2] = 0x80; else if (i2cBuffer.buf[2] == 62) InstSendValue[2] = 0x40; else if (i2cBuffer.buf[2] == 64) InstSendValue[2] = 0x20; else if (i2cBuffer.buf[2] == 65) InstSendValue[2] = 0x10; else if (i2cBuffer.buf[2] == 67) InstSendValue[2] = 0x08; else if (i2cBuffer.buf[2] == 69) InstSendValue[2] = 0x04; else if (i2cBuffer.buf[2] == 71) InstSendValue[2] = 0x02; else if (i2cBuffer.buf[2] == 72) InstSendValue[2] = 0x01; InstSendValue[0] = 0x00; InstSendValue[1] = 0x16; //InstSendValue[2] = 0x80; InstSendValue[3] = 0x00; InstSendValue[4] = 0x00; InstSendValue[5] = 0x00; if (vtI2CEnQ(devPtr,0x00,0x38,6,InstSendValue,0) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } if (vtI2CDeQ(devPtr,0,&MidiReceived[0],&rxLen,&status) != pdTRUE) { //VT_HANDLE_FATAL_ERROR(0); } MidiSendCount++; } else if (i2cBuffer.buf[1] == 0x91) { if (i2cBuffer.buf[2] == 60) InstSendValue[2] = 0x80; else if (i2cBuffer.buf[2] == 62) InstSendValue[2] = 0x40; else if (i2cBuffer.buf[2] == 64) InstSendValue[2] = 0x20; else if (i2cBuffer.buf[2] == 65) InstSendValue[2] = 0x10; else if (i2cBuffer.buf[2] == 67) InstSendValue[2] = 0x08; else if (i2cBuffer.buf[2] == 69) InstSendValue[2] = 0x04; else if (i2cBuffer.buf[2] == 71) InstSendValue[2] = 0x02; else if (i2cBuffer.buf[2] == 72) InstSendValue[2] = 0x01; InstSendValue[0] = 0x00; InstSendValue[1] = 0x16; //InstSendValue[2] = 0x80; InstSendValue[3] = 0x00; InstSendValue[4] = 0x00; InstSendValue[5] = 0x00; if (vtI2CEnQ(devPtr,0x00,0x3B,6,InstSendValue,0) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } if (vtI2CDeQ(devPtr,0,&MidiReceived[0],&rxLen,&status) != pdTRUE) { //VT_HANDLE_FATAL_ERROR(0); } MidiSendCount++; } //Here are similar checks on the MIDI messages for a change in pitch. The same checkes are made //for different channels if (i2cBuffer.buf[1] == 0xE0) { if (i2cBuffer.buf[3] == 0x00) InstSendValue[1] = 0x04; else if (i2cBuffer.buf[3] == 0x40) InstSendValue[1] = 0x02; else if (i2cBuffer.buf[3] == 0x7F) InstSendValue[1] = 0x01; InstSendValue[0] = 0x02; InstSendValue[3] = 0x00; InstSendValue[2] = 0x00; InstSendValue[4] = 0x00; InstSendValue[5] = 0x00; if (vtI2CEnQ(devPtr,0x00,0x38,6,InstSendValue,0) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } if (vtI2CDeQ(devPtr,0,&MidiReceived[0],&rxLen,&status) != pdTRUE) { //VT_HANDLE_FATAL_ERROR(0); } MidiSendCount++; } else if (i2cBuffer.buf[1] == 0xE1) { if (i2cBuffer.buf[3] == 0x00) InstSendValue[1] = 0x04; else if (i2cBuffer.buf[3] == 0x40) InstSendValue[1] = 0x02; else if (i2cBuffer.buf[3] == 0x7F) InstSendValue[1] = 0x01; InstSendValue[0] = 0x02; InstSendValue[3] = 0x00; InstSendValue[2] = 0x00; InstSendValue[4] = 0x00; InstSendValue[5] = 0x00; if (vtI2CEnQ(devPtr,0x00,0x3B,6,InstSendValue,0) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } if (vtI2CDeQ(devPtr,0,&MidiReceived[0],&rxLen,&status) != pdTRUE) { //VT_HANDLE_FATAL_ERROR(0); } MidiSendCount++; } //wait for message from I2C } } //If the message is not NULL then it is an ADC message, this message gets forwarded to MainThread.c where //the data is used for calculations. FlipBit(7); if (lcdData != NULL) { //message sent to the master message queue masterBuffer.length = 13; masterBuffer.buf[0] = 0x08; //means the message is from I2C - change to 0x09 for Nick's program masterBuffer.buf[1] = ADCValueReceived[0]; masterBuffer.buf[2] = ADCValueReceived[1]; masterBuffer.buf[3] = ADCValueReceived[2]; masterBuffer.buf[4] = ADCValueReceived[3]; masterBuffer.buf[5] = ADCValueReceived[4]; masterBuffer.buf[6] = ADCValueReceived[5]; masterBuffer.buf[7] = ADCValueReceived[6]; masterBuffer.buf[8] = ADCValueReceived[7]; masterBuffer.buf[9] = ADCValueReceived[8]; masterBuffer.buf[10] = ADCValueReceived[9]; masterBuffer.buf[11] = ADCValueReceived[10]; masterBuffer.buf[12] = ADCValueReceived[11]; if (xQueueSend(masterData->inQ,(void *) (&masterBuffer),portMAX_DELAY) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } } } } }
static portTASK_FUNCTION( vConductorUpdateTask, pvParameters ) { uint8_t rxLen, status; uint8_t Buffer[vtI2CMLen]; uint8_t *valPtr = &(Buffer[0]); // Get the parameters vtConductorStruct *param = (vtConductorStruct *) pvParameters; // Get the I2C device pointer vtI2CStruct *devPtr = param->dev; // Get the LCD information pointer vtTempStruct *tempData = param->tempData; myNavStruct *navData = param->navData; myMapStruct *mapData = param->mapData; uint8_t recvMsgType; mapStruct.mappingFlag = 0; uint8_t i2cRoverMoveStop[] = {0x05, 0x00}; // 255 will always be a bad message countDefArray[255] = BadMsg; uint8_t i; for(i = 0; i < 255; i++) { countDefArray[i] = CleanMsg; } uint8_t i2cRoverMoveStop[] = {0x05, 0x00}; // Like all good tasks, this should never exit for(;;) { // Wait for a message from an I2C operation if (vtI2CDeQ(devPtr,vtI2CMLen,Buffer,&rxLen,&recvMsgType,&status) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } // Decide where to send the message // This just shows going to one task/queue, but you could easily send to // other Q/tasks for other message types // This isn't a state machine, it is just acting as a router for messages // If it is the initialization message if ( recvMsgType == vtI2CMsgTypeTempInit ) { SendTempValueMsg(tempData,recvMsgType,Buffer,portMAX_DELAY); } else { // Switch on the definition of the incoming count switch(countDefArray[Buffer[0]]) { case RoverMsgSensorAllData: { //printf("SensorData\n"); GPIO_ClearValue(0,0x78000); GPIO_SetValue(0, 0x48000); SendMapValueMsg(mapData,RoverMsgSensorAllData, Buffer, portMAX_DELAY); if (!speedRun) SendNavValueMsg(navData,0x11,Buffer,portMAX_DELAY); break; } case RoverMsgSensorForwardRight: { //SendTempValueMsg(tempData,recvMsgType,Buffer,portMAX_DELAY); break; } case RoverMsgMotorLeftData: { //printf("MotorLeftData\n"); GPIO_ClearValue(0,0x78000); GPIO_SetValue(0, 0x40000); SendTempValueMsg(tempData,RoverMsgMotorLeftData,Buffer,portMAX_DELAY); if (!speedRun) SendNavValueMsg(navData,RoverMsgMotorLeftData,Buffer,portMAX_DELAY); SendMapValueMsg(mapData,RoverMsgMotorLeftData,Buffer,portMAX_DELAY); break; } case RoverMsgMotorLeft90: { printf("RoverData\n"); break; // SendTempValueMsg(tempData,recvMsgType,Buffer,portMAX_DELAY); } case BadMsg: { printf("Bad Message; Restart Pics\n"); break; } default: { //printf("ConductDefault\n"); SendMapValueMsg(mapData,0x11,Buffer,portMAX_DELAY); break; } } if(Buffer[6] == 1) { if (vtI2CEnQ(devPtr,vtI2CMsgTypeTempRead1,0x4F,sizeof(i2cRoverMoveStop),i2cRoverMoveStop,10) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } mapStruct.mappingFlag = 0; mapStruct.timerFlag = 0; restart_nav(); printf("\nFINISH LINE DETECTED!\n"); stopGettingMotor("DATASTOP"); } } // Clear the count defition countDefArray[Buffer[0]] = CleanMsg; // Check if retransmission is needed if ( countDefArray[Buffer[0]-3] == RoverMsgMotorLeft90 ) { printf("Retrans of motor\n"); SendNavValueMsg(navData,0x89,Buffer,portMAX_DELAY); } // Check to see if the last five have been retrieved /*uint8_t i; for (i = Buffer[0]-1; i > Buffer[0] - 5; i--) { printf("Buf Check: %d\n", i); if ( countDefArray[i] == RoverMsgMotorLeft90 ) { printf("Retrans of motor\n"); SendNavValueMsg(navData,0x89,Buffer,portMAX_DELAY); } }*/ } }
// This is the actual task that is run static portTASK_FUNCTION( SomeTask, pvParameters ) { portTickType xUpdateRate, xLastUpdateTime; const uint8_t i2cCmdReadVals[]= {0xAA}; uint8_t temp1, rxLen, status; uint8_t messageReceived[2]; // Get the parameters i2cTempStruct *param = (i2cTempStruct *) pvParameters; // Get the I2C device pointer vtI2CStruct *devPtr = param->dev; // Get the LCD information pointer vtLCDStruct *lcdData = param->lcdData; vtLCDMsg lcdBuffer; vTaskDelay(10/portTICK_RATE_MS); xUpdateRate = i2cREAD_RATE_BASE / portTICK_RATE_MS; /* We need to initialise xLastUpdateTime prior to the first call to vTaskDelayUntil(). */ xLastUpdateTime = xTaskGetTickCount(); for(;;) { //delay for some amount of time before looping again vTaskDelayUntil( &xLastUpdateTime, xUpdateRate ); int i = 0; //toggle the bottom LED uint8_t ulCurrentState = GPIO2->FIOPIN; if( ulCurrentState & 0x40 ) { GPIO2->FIOCLR = 0x40; } else { GPIO2->FIOSET = 0x40; } //Ask for message from I2C if (vtI2CEnQ(devPtr,0x01,0x48,sizeof(i2cCmdReadVals),0x00/*i2cCmdReadVals*/,2) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } //wait for message from I2C if (vtI2CDeQ(devPtr,2,&messageReceived[0],&rxLen,&status) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } uint8_t testint = 0; //load the read message from I2C into the lcd Buffer lcdBuffer.buf[0] = messageReceived[1]; lcdBuffer.buf[1] = messageReceived[0]; if (lcdData != NULL && lcdBuffer.buf[0] != 0xFF) { // Send a message to the LCD task for it to print (and the LCD task must be configured to receive this message) lcdBuffer.length = strlen((char*)(lcdBuffer.buf))+1; if (xQueueSend(lcdData->inQ,(void *) (&lcdBuffer),portMAX_DELAY) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } } } }
// This is the actual task that is run static portTASK_FUNCTION( sensorTask, pvParameters ) { uint8_t rxLen, status; // not using status, and rxLen is always maxReceiveBytesForSpecificNumOfSensorSamples (define in .h) uint8_t buffer[vtI2CMLen]; // receive message uint8_t recvMsgType; // message type of the message put on I2C queue by moveTask (defined in I2CtaskMsgtypes) // Get the parameters SensorAStruct *sensorT = (SensorAStruct *) pvParameters; webServerTaskStruct *webServerData = sensorT->webServerData; // Get the I2C device pointer vtI2CStruct *i2cDevPtr = sensorT->i2cDev; MoveTaskStruct *moveTPtr = sensorT->moveT; uint8_t count = 0; uint16_t frontBuf[numOfSensorToDebounce] = {0, 0, 0}; uint16_t sideTopBuf[numOfSensorToDebounce] = {0, 0, 0}; uint16_t sideBottomBuf[numOfSensorToDebounce] = {0, 0, 0}; int i = 0; for( i = 0; i < numOfSensorToDebounce; i++ ) { frontBuf[i] = 0; sideTopBuf[i] = 0; sideBottomBuf[i] = 0; } // Like all good tasks, this should never exit for(;;) { // Wait for a message from an I2C operation if (vtI2CDeQ(i2cDevPtr, vtI2CMLen,buffer,&rxLen,&recvMsgType,&status) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } // printf("buffer %x\n", buffer[0]); // // uint8_t index = 0; // for (index = 0; index < rxLen; index++) // { // printf("buffer %x\n", buffer[index]); // } switch(recvMsgType) { case (sensor1): { break; } case (sensor2): { if( rxLen != 0 ) { // make sure the check sum is ok //printf("valid = %d\n", validateMessage(buffer, rxLen)); if( validateMessage(buffer, rxLen) ) { switch( getMessageId(buffer, rxLen) ) // recognize the msgID { case RoverWaitingForCommand: { /* * We need to disable the timer so that the arm doesn't * retrieve multiple sensor values when the rover is stationary. * It is important to enable the timer back again so that the * Arm receives distance values the rover has travelled from the * last poll. */ /* * Retrieve the sensor distances */ uint16_t frontDistanceInches = getFrontSensorDistanceInInches(buffer, rxLen); uint16_t topRightDistanceInches = getTopRightSensorDistanceInInches(buffer, rxLen); uint16_t bottomRightDistanceInches = getBottomRightSensorDistanceInInches(buffer, rxLen); uint8_t canFront = updateSensorBuf(frontBuf, frontDistanceInches); uint8_t canSideT = updateSensorBuf(sideTopBuf, topRightDistanceInches); uint8_t canSideB = updateSensorBuf(sideBottomBuf, bottomRightDistanceInches); uint8_t rightFeet = getRightFeet(buffer, rxLen); uint8_t rightInches = getRightInches(buffer, rxLen); uint8_t leftFeet = getLeftFeet(buffer, rxLen); uint8_t leftInches = getLeftInches(buffer, rxLen); // printf("rightF = %d, rightI = %d, leftF = %d, leftI = %d\n", rightFeet, rightInches, leftFeet // , leftInches); if ( canFront != 1 || canSideT != 1 || canSideB != 1){ break; } sendWheelDistancesOnly(sensorT->mapT, leftFeet, leftInches, rightFeet, rightInches, 0); printf("Front %d\n", frontDistanceInches); printf("TR %d\n", topRightDistanceInches); printf("BR %d\n", bottomRightDistanceInches); SendWebServerSensorData(webServerData,frontDistanceInches, topRightDistanceInches,bottomRightDistanceInches, 0); performLogic(buffer , rxLen, moveTPtr, sensorT); break; } case RoverBusy: { /* * Simply pass the buffer received from the rover to the MAP Task. */ /* * Since the rover has received the command, we want * to enable the timer so that we poll rover to receive * the distance in feet and inches the rover has moved. */ break; }; case RoverHitStartFinshLine: { /* * Simply pass the buffer received from the rover to the MAP Task. */ uint8_t cmd [] = {stop_cmd_ToRover}; uint8_t t [] = {0}; uint8_t deg [] = {0}; uint8_t dist [] = {0,0}; SendWebServerCommandBuf(webServerData, fillWebServerBuf(cmd[0], t[0], deg[0], dist[0], dist[1]), portMAX_DELAY); //SendStopToRover(moveTPtr, portMAX_DELAY); SendStFinNotification(sensorT->mapT, portMAX_DELAY); performLogic(buffer , rxLen, moveTPtr, sensorT); RUN++; break; }; case RoverReceiveMoveCommand: { /* * Since the rover has received the command, we want * to enable the timer so that we poll rover to receive * the distance in feet and inches the rover has moved. */ break; }; case MessageDrop: { // msg wasn't received in time SendDroppedNotification(moveTPtr, 0); break; }; } } else { // notify the moveTask that a message was droped or went bad SendDroppedNotification(moveTPtr, 0); } } else { // message dropped SendDroppedNotification(moveTPtr, 0); } break; } case (cmdSend): { break; } default: { //VT_HANDLE_FATAL_ERROR(0); break; } } } }
// This is the actual task that is run static portTASK_FUNCTION( vConductorUpdateTask, pvParameters ) { // Get the parameters param = (vtConductorStruct *) pvParameters; // Get the I2C device pointer devPtr = param->dev; // Get the I2C task pointer i2cData = param->i2cData; // Get the Motor Control task pointer motorControl = param->motorControl; // Get the IR Control task pointer irData = param->irData; // Get the Speed Limit task pointer speedData = param->speedData; //Get the Power task pointer powerData = param->powerData; // Get the LCD pointer information lcdData = param->lcdData; // Message counts colorSensorMsgCount = 0, encodersMsgCount = 0, IRMsgCount = 0, ADCMsgCount = 0, powerMsgCount = 0, recvMsgType = 0; // The value 0 is a temporary initial value for recvMsgType, rxLen; it's overwritten when vtI2CDeQ occurs. // Like all good tasks, this should never exit for(;;) { // Wait for a message from an I2C operation if (vtI2CDeQ(devPtr,vtI2CMLen,Buffer,&rxLen,&recvMsgType,&status) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } // Decide where to send the message // This isn't a state machine, it is just acting as a router for messages switch(recvMsgType) { case vtI2CReadMsgType: { // If it is a read, send it to the appropriate task switch(vtGetI2CMsgType(Buffer)){ /*---EMPTY MESSAGES---*/ case COLOR_SENSOR_EMPTY_MESSAGE: { notifyRequestRecvd(i2cData,portMAX_DELAY); colorSensorMsgCount++; if(colorSensorMsgCount != vtGetI2CMsgCount(Buffer)){ //Send Web Server an error with vtGetI2CMsgCount(Buffer) - colorSensorMsgCount colorSensorMsgCount = vtGetI2CMsgCount(Buffer); } break; } case ENCODERS_EMPTY_MESSAGE: { notifyRequestRecvd(i2cData,portMAX_DELAY); encodersMsgCount++; if(encodersMsgCount != vtGetI2CMsgCount(Buffer)){ //Send Web Server an error with vtGetI2CMsgCount(Buffer) - encodersMsgCount encodersMsgCount = vtGetI2CMsgCount(Buffer); } break; } case IR_EMPTY_MESSAGE: { notifyRequestRecvd(i2cData,portMAX_DELAY); IRMsgCount++; if(IRMsgCount != vtGetI2CMsgCount(Buffer)){ //Send Web Server an error with vtGetI2CMsgCount(Buffer) - IRMsgCount IRMsgCount = vtGetI2CMsgCount(Buffer); } break; } case POWER_EMPTY_MESSAGE: { notifyRequestRecvd(i2cData,portMAX_DELAY); powerMsgCount++; if(powerMsgCount != vtGetI2CMsgCount(Buffer)){ //Send Web Server an error with vtGetI2CMsgCount(Buffer) - powerMsgCount powerMsgCount = vtGetI2CMsgCount(Buffer); } break; } case GENERIC_EMPTY_MESSAGE: { break; } /*---DATA MESSAGES---*/ case COLOR_SENSOR_MESSAGE: { notifyRequestRecvd(i2cData,portMAX_DELAY); conductorSendColorSensorDataMsg(speedData, (Buffer + 2), 8); colorSensorMsgCount++; if(colorSensorMsgCount != vtGetI2CMsgCount(Buffer)){ //Send Web Server an error with vtGetI2CMsgCount(Buffer) - colorSensorMsgCount colorSensorMsgCount = vtGetI2CMsgCount(Buffer); } break; } case ENCODERS_MESSAGE: { notifyRequestRecvd(i2cData,portMAX_DELAY); conductorSendMotorEncoderDataMsg(motorControl, (Buffer + 2), 8); encodersMsgCount++; if(encodersMsgCount != vtGetI2CMsgCount(Buffer)){ //Send Web Server an error with vtGetI2CMsgCount(Buffer) - encodersMsgCount encodersMsgCount = vtGetI2CMsgCount(Buffer); } break; } case IR_MESSAGE: { notifyRequestRecvd(i2cData,portMAX_DELAY); conductorSendIRSensorDataMsg(irData, (Buffer + 2), 8); // Still figuring out if this should be 2, 4, or 8 but I'm pretty sure this should be 8 IRMsgCount++; if(IRMsgCount != vtGetI2CMsgCount(Buffer)){ //Send Web Server an error with vtGetI2CMsgCount(Buffer) - IRMsgCount IRMsgCount = vtGetI2CMsgCount(Buffer); } break; } case POWER_MESSAGE: { notifyRequestRecvd(i2cData,portMAX_DELAY); conductorSendPowerDataMsg(powerData, (Buffer + 2), 4); powerMsgCount++; if(powerMsgCount != vtGetI2CMsgCount(Buffer)){ //Send Web Server an error with vtGetI2CMsgCount(Buffer) - powerMsgCount powerMsgCount = vtGetI2CMsgCount(Buffer); } break; } } // End switch statement break; } // End vtI2CReadMsgType case case vtI2CMotorMsgType: { // If it is a I2C motor message, just recognize that this is an ack from the slave // Nothing else to do here break; } default: { VT_HANDLE_FATAL_ERROR(recvMsgType); break; } } // End switch statement } // End for loop }