MCC version: Core v5.0.2
MPLAB X version: 5.45
Operating System and version: Windows 7
Compiler version: XC8 2.31
Device name: PIC16F1829LIN
Peripheral: LINBUS
我使用MCC LIN libraries 產生slave端程式碼後,注意到在case LIN_RX_PID: 中只判斷 LIN_packet.type 為RECEIVE 或 else。
想請問如果遇到LIN_getFromTable() 回傳的type為ERROR,
這樣執行到 case LIN_RX_TX_DATA : 的LIN_queuePacket(LIN_packet.PID)時,是否會傳送不可預期的資料給Master端?
還是有甚麼特性讓這種狀況不會發生,目前使用還沒有遇到狀況。
感謝!!
以下為MCC生成code :
lin_rx_state_t LIN_handler(void){
static lin_rx_state_t LIN_rxState = LIN_RX_IDLE;
static uint8_t rxDataIndex = 0;
if(LIN_rxInProgress == true){
if(LIN_timerRunning == false){
//Timeout
LIN_rxState = LIN_RX_ERROR;
}
}
switch(LIN_rxState){
case LIN_RX_IDLE:
if(EUSART_is_rx_ready() > 0){
//Start Timer
LIN_startTimer(READ_TIMEOUT);
LIN_rxInProgress = true;
LIN_rxState = LIN_RX_BREAK;
}
break;
case LIN_RX_BREAK:
if(EUSART_is_rx_ready() > 0){
if(LIN_breakCheck() == true){ //Read Break
LIN_rxState = LIN_RX_SYNC;
} else {
LIN_rxState = LIN_RX_ERROR;
}
}
break;
case LIN_RX_SYNC:
if(EUSART_is_rx_ready() > 0){
if(EUSART_Read() == 0x55){ //Read sync - discard
LIN_rxState = LIN_RX_PID;
} else {
LIN_rxState = LIN_RX_ERROR;
}
}
break;
case LIN_RX_PID:
if(EUSART_is_rx_ready() > 0){
LIN_packet.PID = EUSART_Read();
//check LIN Parity bits
if(LIN_checkPID(LIN_packet.PID) == false){
LIN_rxState = LIN_RX_ERROR;
break;
}
LIN_packet.type = LIN_getFromTable(LIN_packet.PID, TYPE);
if(LIN_packet.type == RECEIVE){
LIN_packet.length = LIN_getFromTable(LIN_packet.PID, LENGTH);
LIN_rxState = LIN_RX_DATA;
}
else{
LIN_disableRx();
LIN_rxState = LIN_RX_TX_DATA;
}
}
break;
case LIN_RX_DATA:
if(EUSART_is_rx_ready() > 0){
LIN_packet.data[rxDataIndex] = EUSART_Read();
if(++rxDataIndex >= LIN_packet.length){
//received all data bytes
rxDataIndex = 0;
LIN_rxState = LIN_RX_CHECKSUM;
}
}
break;
case LIN_RX_CHECKSUM:
if(EUSART_is_rx_ready() > 0){
LIN_packet.checksum = EUSART_Read();
if(LIN_packet.checksum != LIN_getChecksum(LIN_packet.length, LIN_packet.PID, LIN_packet.data)) {
LIN_rxState = LIN_RX_ERROR;
}
else {
LIN_rxState = LIN_RX_RDY;
}
}
break;
case LIN_RX_TX_DATA:
LIN_queuePacket(LIN_packet.PID); //Send response automatically
LIN_rxState = LIN_RX_RDY;
case LIN_RX_RDY:
LIN_processData();
case LIN_RX_ERROR:
LIN_stopTimer();
rxDataIndex = 0;
LIN_rxInProgress = false;
memset(LIN_packet.rawPacket, 0, sizeof(LIN_packet.rawPacket)); //clear receive data
case LIN_RX_WAIT:
if(TXSTAbits.TRMT){
LIN_enableRx();
LIN_rxState = LIN_RX_IDLE;
} else {
LIN_rxState = LIN_RX_WAIT;
}
break;
}
return LIN_rxState;
}
比對PID部分 :
uint8_t LIN_getFromTable(uint8_t cmd, lin_sch_param_t param){
const lin_rx_cmd_t* rxCommand = LIN_rxCommand; //copy table pointer so we can modify it
cmd &= 0x3F; //clear possible parity bits
//check table
for(uint8_t length = 0; length cmd){
break;
}
rxCommand++; //go to next entry
if(length == (LIN_rxCommandLength-1)){
return ERROR; //command not in schedule table
}
}
switch(param){
case CMD:
return rxCommand->cmd;
case TYPE:
return rxCommand->type;
case LENGTH:
return rxCommand->length;
default:
break;
}
return ERROR;
}
發送response資料部分 :
void LIN_queuePacket(uint8_t cmd){
const lin_rx_cmd_t* tempSchedule = LIN_rxCommand; //copy table pointer so we can modify it
cmd &= 0x3F; //clear possible parity bits
for(uint8_t i = 0; i cmd){
break;
}
tempSchedule++; //go to next entry
}
LIN_packet.type = tempSchedule->type;
LIN_packet.length = tempSchedule->length;
//Build Packet - User defined data
//add data
memcpy(LIN_packet.data, tempSchedule->data, LIN_packet.length);
//Add Checksum
LIN_packet.checksum = LIN_getChecksum(LIN_packet.length, LIN_packet.PID, LIN_packet.data);
LIN_sendPacket(LIN_packet.length, LIN_packet.PID, LIN_packet.data);
}