// This is the actual task that is run static portTASK_FUNCTION( oScopeUpdateTask, pvParameters ) { uint8_t rcvByte[2]; // Get the parameters oScopeStruct *param = (oScopeStruct *) pvParameters; // Get the I2C device pointer vtI2CStruct *devPtr = param->dev; // Get the LCD information pointer lcdOScopeStruct *lcdData = param->lcdData; // Buffer for receiving messages oScopeMsg msgBuffer; uint8_t currentState; // Assumes that the I2C device (and thread) have already been initialized // This task is implemented as a Finite State Machine. The incoming messages are examined to see // whether or not the state should change. // // Temperature sensor configuration sequence (DS1621) Address 0x4F if (vtI2CEnQ(devPtr,vtI2CMsgTypeTempInit,0x4F,sizeof(i2cCmdInit),i2cCmdInit,0) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } currentState = fsmRead1; // Like all good tasks, this should never exit for(;;) { // Wait for a message from either a timer or from an I2C operation if (xQueueReceive(param->inQ,(void *) &msgBuffer,portMAX_DELAY) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } // Now, based on the type of the message and the state, we decide on the new state and action to take switch(getMsgType(&msgBuffer)) { case oScopeTimerMsg: { if (vtI2CEnQ(devPtr,oScopeRead1Msg,0x4F,sizeof(i2cCmdReadByte1),i2cCmdReadByte1,2) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } if (vtI2CEnQ(devPtr,oScopeRead2Msg,0x4F,sizeof(i2cCmdReadByte2),i2cCmdReadByte2,1) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } break; } case oScopeRead1Msg: { printf("Read1Msg:"); if (currentState == fsmRead1) { currentState = fsmRead2; rcvByte[0] = getValue(&msgBuffer); } else { // unexpectedly received this message VT_HANDLE_FATAL_ERROR(0); } break; } case oScopeRead2Msg: { printf("Read2Msg:"); if (currentState == fsmRead2) { currentState = fsmRead1; rcvByte[1] = getValue(&msgBuffer); uint16_t msgData = (rcvByte[0])|(rcvByte[1]<<8); if (SendLCDOScopeMsg(lcdData,msgData,portMAX_DELAY) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } } else { // unexpectedly received this message VT_HANDLE_FATAL_ERROR(0); } break; } default: { VT_HANDLE_FATAL_ERROR(getMsgType(&msgBuffer)); break; } } } }
// This is the actual task that is run static portTASK_FUNCTION( vi2cTempUpdateTask, pvParameters ) { int byte1 = 0; int byte2 = 0; //float countPerC = 100.0, countRemain=0.0; // Get the parameters vtTempStruct *param = (vtTempStruct *) pvParameters; // Get the I2C device pointer vtI2CStruct *devPtr = param->dev; // Get the LCD information pointer lcdOScopeStruct *lcdData = param->lcdData; // String buffer for printing char lcdBuffer[vtOScopeMaxLen+1]; // Buffer for receiving messages vtTempMsg msgBuffer; uint8_t currentState; // Assumes that the I2C device (and thread) have already been initialized // This task is implemented as a Finite State Machine. The incoming messages are examined to see // whether or not the state should change. // // Temperature sensor configuration sequence (DS1621) Address 0x4F //if (vtI2CEnQ(devPtr,vtI2CMsgTypeTempInit,0x4F,sizeof(i2cCmdInit),i2cCmdInit,0) != pdTRUE) { // VT_HANDLE_FATAL_ERROR(0); //} currentState = vtI2CMsgTypeTempRead1; // Like all good tasks, this should never exit for(;;) { // Wait for a message from either a timer or from an I2C operation if (xQueueReceive(param->inQ,(void *) &msgBuffer,portMAX_DELAY) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } // Now, based on the type of the message and the state, we decide on the new state and action to take switch(getMsgType(&msgBuffer)) { case vtI2CMsgTypeTempInit: { if (currentState == fsmStateInit1Sent) { currentState = fsmStateInit2Sent; // Must wait 10ms after writing to the temperature sensor's configuration registers(per sensor data sheet) vTaskDelay(10/portTICK_RATE_MS); // Tell it to start converting if (vtI2CEnQ(devPtr,vtI2CMsgTypeTempInit,0x4F,sizeof(i2cCmdStartConvert),i2cCmdStartConvert,0) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } } else if (currentState == fsmStateInit2Sent) { currentState = fsmStateTempRead1; } else { // unexpectedly received this message VT_HANDLE_FATAL_ERROR(0); } break; } case TempMsgTypeTimer: { // Timer messages never change the state, they just cause an action (or not) if ((currentState != fsmStateInit1Sent) && (currentState != fsmStateInit2Sent)) { printf("got a timer call yo"); // Read in the values from the temperature sensor // We have three transactions on i2c to read the full temperature // we send all three requests to the I2C thread (via a Queue) -- responses come back through the conductor thread // Temperature read -- use a convenient routine defined above //if (vtI2CEnQ(devPtr,vtI2CMsgTypeTempRead1,0x4F,sizeof(i2cCmdReadVals),i2cCmdReadVals,2) != pdTRUE) { // VT_HANDLE_FATAL_ERROR(0); //} printf("TIMER GET\n"); if (vtI2CEnQ(devPtr,voidMsg,0x4F,sizeof(i2cCmdReadVals),i2cCmdReadVals,4) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); } // Read in the read counter /*if (vtI2CEnQ(devPtr,vtI2CMsgTypeTempRead2,0x4F,sizeof(i2cCmdReadCnt),i2cCmdReadCnt,2) != pdTRUE) { VT_HANDLE_FATAL_ERROR(0); }*/ // Read in the slope; //if (vtI2CEnQ(devPtr,vtI2CMsgTypeTempRead3,0x4F,sizeof(i2cCmdReadSlope),i2cCmdReadSlope,1) != pdTRUE) { // VT_HANDLE_FATAL_ERROR(0); //} } else { // just ignore timer messages until initialization is complete } break; } case vtI2CMsgTypeTempRead1: { if (currentState == fsmStateTempRead1) { currentState = fsmStateTempRead1; byte1 = msgBuffer.buf[0]; byte2 = msgBuffer.buf[1]; uint16_t data = (byte2<<8)|byte1; SendLCDOScopeMsg(lcdData,data,portMAX_DELAY); } else { // unexpectedly received this message VT_HANDLE_FATAL_ERROR(0); } break; } case vtI2CMsgTypeTempRead2: { if (currentState == fsmStateTempRead2) { currentState = fsmStateTempRead1; byte2 = getValue(&msgBuffer); uint16_t data = (byte2<<8)|byte1; SendLCDOScopeMsg(lcdData,data,portMAX_DELAY); } else { // unexpectedly received this message VT_HANDLE_FATAL_ERROR(0); } break; } default: { VT_HANDLE_FATAL_ERROR(getMsgType(&msgBuffer)); break; } } } }