void CodaMotorController::handleCanFrame(CAN_FRAME *frame) { int RotorTemp, invTemp, StatorTemp; int temp; online = 1; //if a frame got to here then it passed the filter and must come from UQM running=true; Logger::debug("UQM inverter msg: %X %X %X %X %X %X %X %X %X", frame->id, frame->data.bytes[0], frame->data.bytes[1],frame->data.bytes[2],frame->data.bytes[3],frame->data.bytes[4], frame->data.bytes[5],frame->data.bytes[6],frame->data.bytes[7]); switch (frame->id) { case 0x209: //Accurate Feedback Message torqueActual = ((((frame->data.bytes[1] * 256) + frame->data.bytes[0])-32128)) ; dcVoltage = (((frame->data.bytes[3] * 256) + frame->data.bytes[2])-32128); if(dcVoltage<1000){dcVoltage=1000;}//Lowest value we can display on dashboard dcCurrent = (((frame->data.bytes[5] * 256) + frame->data.bytes[4])-32128); speedActual = abs((((frame->data.bytes[7] * 256) + frame->data.bytes[6])-32128)/2); Logger::debug("UQM Actual Torque: %d DC Voltage: %d Amps: %d RPM: %d", torqueActual/10,dcVoltage/10,dcCurrent/10,speedActual); break; case 0x20A: //System Status Message Logger::debug("UQM inverter 20A System Status Message Received"); break; case 0x20B: //Emergency Fuel Cutback Message Logger::debug("UQM inverter 20B Emergency Fuel Cutback Message Received"); break; case 0x20C: //Reserved Message Logger::debug("UQM inverter 20C Reserved Message Received"); break; case 0x20D: //Limited Torque Percentage Message Logger::debug("UQM inverter 20D Limited Torque Percentage Message Received"); break; case 0x20E: //Temperature Feedback Message invTemp = frame->data.bytes[2]; RotorTemp = frame->data.bytes[3]; StatorTemp = frame->data.bytes[4]; temperatureInverter = (invTemp-40)*10; if (RotorTemp > StatorTemp) {temperatureMotor = (RotorTemp-40)*10;} else {temperatureMotor = (StatorTemp-40)*10;} Logger::debug("UQM 20E Inverter temp: %d Motor temp: %d", temperatureInverter,temperatureMotor); break; case 0x20F: //CAN Watchdog Status Message Logger::debug("UQM 20F CAN Watchdog status error"); warning=true; running=false; sendCmd2(); //If we get a Watchdog status, we need to respond with Watchdog reset break; } }
uint32_t identifyCard( void ) { // NOTE: see OMAP35x.pdf page 3164, starterware and sd_spec 2.0 uint8_t hcsFlag = 0; memset( &cardInfo, 0, sizeof( CARD_INFO ) ); // send GO_IDLE_STATE if ( sendCmd0() ) { // an error occured sending CMD0 return 1; } // cmd5 is reserved for I/O cards: SDIO. will return 0 if it is SDIO if ( 0 == sendCmd5() ) { return 1; } // send GO_IDLE_STATE again if ( sendCmd0() ) { // an error occured sending CMD0 return 1; } // send SEND_IF_COND if ( 0 == sendCmd8() ) { // NOTE: it is an SD card compliant with standard 2.0 or later uint32_t rsp0 = MMCHS_RSP10 & 0x0000FFFF; uint32_t supportedVoltage = rsp0 & 0xFFF; if ( supportedVoltage != 0x1AA ) { // NOT supported: return 1; } hcsFlag = TRUE; } while ( 1 ) { // send SD_SEND_OP_COND // NOTE: sd_spec 2.0 page 26: While repeating ACMD41, the host shall not issue another command except CMD0. => other sources say repeat CMD55 too if ( 0 == sendACmd41( hcsFlag ) ) { // if card is busy, repeat again, otherwise card is identified if ( ! isCardBusy() ) { // NOTE: it is a SD card compliant with standard 1.x // store ocr in card-info cardInfo.ocr = MMCHS_RSP10; // check if card is high-capacity or not (HCR-bit in OCR at position 30) cardInfo.highCap = ( cardInfo.ocr & ( 1 << 30 ) ) ? 1 : 0; goto cardIdentified; } } // no response => its no SD meory card else { break; } } // NOTE: at this point we are a MMC card - we don't support them return 1; cardIdentified: // send ALL_SEND_CID if ( sendCmd2() ) { return 1; } // store card-info just returned by CMD2 in RSP10-76 cardInfo.raw_cid[ 0 ] = MMCHS_RSP10; cardInfo.raw_cid[ 1 ] = MMCHS_RSP32; cardInfo.raw_cid[ 2 ] = MMCHS_RSP54; cardInfo.raw_cid[ 3 ] = MMCHS_RSP76; // send SEND_RELATIVE_ADDR to ask card to publish new realtive address if ( sendCmd3() ) { return 1; } // store RCA just returned by CMD3 cardInfo.rca = ( MMCHS_RSP10 & 0xFFFF0000 ) >> 16; // send SEND_CSD: request card-specific data if ( sendCmd9() ) { return 1; } // store card-specific data just returned by CMD9 in RSP10-76 cardInfo.raw_csd[ 0 ] = MMCHS_RSP10; cardInfo.raw_csd[ 1 ] = MMCHS_RSP32; cardInfo.raw_csd[ 2 ] = MMCHS_RSP54; cardInfo.raw_csd[ 3 ] = MMCHS_RSP76; if ( SD_CARD_CSD_VERSION( cardInfo ) ) { cardInfo.tranSpeed = SD_CARD1_TRANSPEED(cardInfo); cardInfo.blkLen = 1 << (SD_CARD1_RDBLKLEN(cardInfo)); cardInfo.size = SD_CARD1_SIZE(cardInfo); cardInfo.nBlks = cardInfo.size / cardInfo.blkLen; } else { cardInfo.tranSpeed = SD_CARD0_TRANSPEED(cardInfo); cardInfo.blkLen = 1 << (SD_CARD0_RDBLKLEN(cardInfo)); cardInfo.nBlks = SD_CARD0_NUMBLK(cardInfo); cardInfo.size = SD_CARD0_SIZE(cardInfo); } // send SELECT/DESELECT_CARD to select card - now in transfer mode if ( sendCmd7() ) { return 1; } // NOTE: at this point the card is initialized, identified and ready to be used // send block length only in case of standard capacity-card, send it ONCE after selection if ( ! cardInfo.highCap ) { // send block length if ( sendCmd16() ) { // an error occured during sending the command, return immediately return 1; } } // request SCR - will be transmitted throug a data-read! if ( sendACmd51() ) { return 1; } uint8_t scrBuffer[ 8 ]; memset( scrBuffer, 0, 8 ); // SCR is transmitted in 8 bytes through a data-read if ( readTransferBuffer( 8, scrBuffer ) ) { return 1; } cardInfo.raw_scr[ 0 ] = ( scrBuffer[ 3 ] << 24 ) | ( scrBuffer[ 2 ] << 16 ) | ( scrBuffer[ 1 ] << 8 ) | ( scrBuffer[ 0 ] ); cardInfo.raw_scr[ 1 ] = ( scrBuffer[ 7 ] << 24 ) | ( scrBuffer[ 6 ] << 16 ) | ( scrBuffer[ 5 ] << 8 ) | ( scrBuffer[ 4 ] ); cardInfo.sd_ver = SD_CARD_VERSION( cardInfo ); cardInfo.busWidth = SD_CARD_BUSWIDTH( cardInfo ); return 0; }