static int powerup(void) { int ret = 0; u8 cmd[8]; u8 rsp[13]; pSi47xxdata->power(1); cmd[0] = POWER_UP; cmd[1] = POWER_UP_IN_GPO2OEN | POWER_UP_IN_FUNC_FMRX; #ifdef CONFIG_RADIO_USE_MI2S cmd[2] = POWER_UP_IN_OPMODE_RX_DIGITAL; #else cmd[2] = POWER_UP_IN_OPMODE_RX_ANALOG; #endif ret = si47xx_command(3, cmd, 8, rsp); if (ret < 0) { dev_err(Si47xx_dev->dev, "%s failed %d\n", __func__, ret); } else { /* Si4709/09 datasheet: Table 7 */ msleep(110); Si47xx_dev->state.power_state = RADIO_ON; } return ret; }
/*----------------------------------------------------------------------------- Helper function that sends the FM_RDS_STATUS command to the part Inputs: intack: If non-zero the interrupt for STCINT will be cleared. mtfifo: If non-zero the fifo will be cleared. Outputs: Status: Contains bits about the status returned from the part. RdsInts: Contains bits about the interrupts that have fired related to RDS. RdsSync: If non-zero the RDS is currently synced. GrpLost: If non-zero some RDS groups were lost. RdsFifoUsed: The amount of groups currently remaining in the RDS fifo. BlockA: Block A group data from the oldest FIFO entry. BlockB: Block B group data from the oldest FIFO entry. BlockC: Block C group data from the oldest FIFO entry. BlockD: Block D group data from the oldest FIFO entry. BleA: Block A corrected error information. BleB: Block B corrected error information. BleC: Block C corrected error information. BleD: Block D corrected error information. -----------------------------------------------------------------------------*/ static void fmRdsStatus(u8 intack, u8 mtfifo, struct radio_data_t *rds_data, u8 *RdsFifoUsed) { u8 cmd[8]; u8 rsp[13]; int ret = 0; cmd[0] = FM_RDS_STATUS; cmd[1] = 0; if (intack) cmd[1] |= FM_RDS_STATUS_IN_INTACK; if (mtfifo) cmd[1] |= FM_RDS_STATUS_IN_MTFIFO; ret = si47xx_command(2, cmd, 13, rsp); if (ret < 0) { dev_err(Si47xx_dev->dev, "%s fmRdsStatusfailed %d\n", __func__, ret); return; } *RdsFifoUsed = rsp[3]; rds_data->rdsa = ((u16)rsp[4] << 8) | (u16)rsp[5]; rds_data->rdsb = ((u16)rsp[6] << 8) | (u16)rsp[7]; rds_data->rdsc = ((u16)rsp[8] << 8) | (u16)rsp[9]; rds_data->rdsd = ((u16)rsp[10] << 8) | (u16)rsp[11]; rds_data->blera = (rsp[12] & FM_RDS_STATUS_OUT_BLEA) >> FM_RDS_STATUS_OUT_BLEA_SHFT; rds_data->blerb = (rsp[12] & FM_RDS_STATUS_OUT_BLEB) >> FM_RDS_STATUS_OUT_BLEB_SHFT; rds_data->blerc = (rsp[12] & FM_RDS_STATUS_OUT_BLEC) >> FM_RDS_STATUS_OUT_BLEC_SHFT; rds_data->blerd = (rsp[12] & FM_RDS_STATUS_OUT_BLED) >> FM_RDS_STATUS_OUT_BLED_SHFT; }
static int fmTuneStatus(u8 cancel, u8 intack, struct tune_data_t *tune_data) { u8 cmd[8]; u8 rsp[13]; int ret; cmd[0] = FM_TUNE_STATUS; cmd[1] = 0; if (cancel) cmd[1] |= FM_TUNE_STATUS_IN_CANCEL; if (intack) cmd[1] |= FM_TUNE_STATUS_IN_INTACK; ret = si47xx_command(2, cmd, 8, rsp); tune_data->stc = !!(rsp[0] & STCINT); tune_data->bltf = !!(rsp[1] & FM_TUNE_STATUS_OUT_BTLF); tune_data->afcrl = !!(rsp[1] & FM_TUNE_STATUS_OUT_AFCRL); tune_data->valid = !!(rsp[1] & FM_TUNE_STATUS_OUT_VALID); tune_data->freq = ((u16)rsp[2] << 8) | (u16)rsp[3]; tune_data->rssi = rsp[4]; tune_data->asnr = rsp[5]; tune_data->antcap = rsp[7]; return ret; }
/*----------------------------------------------------------------------------- Helper function that sends the FM_TUNE_FREQ command to the part Inputs: frequency in 10kHz steps -----------------------------------------------------------------------------*/ static int fmTuneFreq(u16 frequency) { u8 cmd[8]; u8 rsp[13]; int ret; cmd[0] = FM_TUNE_FREQ; cmd[1] = 0; cmd[2] = (u8)(frequency >> 8); cmd[3] = (u8)(frequency & 0x00FF); cmd[4] = (u8)0; ret = si47xx_command(5, cmd, 1, rsp); return ret; }
/*----------------------------------------------------------------------------- Helper function that sends the GET_INT_STATUS command to the part Returns: The status byte from the part. -----------------------------------------------------------------------------*/ static s8 getIntStatus(void) { u8 cmd[8]; u8 rsp[13]; int ret = 0; cmd[0] = GET_INT_STATUS; ret = si47xx_command(1, cmd, 1, rsp); if (ret < 0) { dev_err(Si47xx_dev->dev, "%s getIntStatus failed %d\n", __func__, ret); return ret; } return rsp[0]; }
/*----------------------------------------------------------------------------- Helper function that sends the FM_SEEK_START command to the part Inputs: seekUp: If non-zero seek will increment otherwise decrement wrap: If non-zero seek will wrap around band limits when hitting the end of the band limit. -----------------------------------------------------------------------------*/ static int fmSeekStart(u8 seekUp, u8 wrap) { u8 cmd[8]; u8 rsp[13]; int ret; cmd[0] = FM_SEEK_START; cmd[1] = 0; if (seekUp) cmd[1] |= FM_SEEK_START_IN_SEEKUP; if (wrap) cmd[1] |= FM_SEEK_START_IN_WRAP; ret = si47xx_command(2, cmd, 1, rsp); return ret; }
/*----------------------------------------------------------------------------- Set the passed property number to the passed value. Inputs: propNumber: The number identifying the property to set propValue: The value of the property. -----------------------------------------------------------------------------*/ static void si47xx_set_property(u16 propNumber, u16 propValue) { u8 cmd[8]; int ret = 0; cmd[0] = SET_PROPERTY; cmd[1] = 0; cmd[2] = (u8)(propNumber >> 8); cmd[3] = (u8)(propNumber & 0x00FF); cmd[4] = (u8)(propValue >> 8); cmd[5] = (u8)(propValue & 0x00FF); ret = si47xx_command(6, cmd, 0, NULL); if (ret < 0) dev_err(Si47xx_dev->dev, "%s si47xx_set_property failed %d\n", __func__, ret); }
/* ----------------------------------------------------------------------------- Helper function that sends the FM_RSQ_STATUS command to the part Inputs: intack: If non-zero the interrupt for STCINT will be cleared. Outputs: Si47xx_status.Status: Contains bits about the status returned from the part. Si47xx_status.RsqInts: Contains bits about the interrupts that have fired related to RSQ. SMUTE: The soft mute function is currently enabled AFCRL: The AFC is railed if this is non-zero Valid: The station is valid if this is non-zero Pilot: A pilot tone is currently present Blend: Percentage of blend for stereo. (100 = full stereo) RSSI: The RSSI level read at tune. ASNR: The audio SNR level read at tune. FreqOff: The frequency offset in kHz of the current station from the tuned frequency. -----------------------------------------------------------------------------*/ static void fmRsqStatus(u8 intack, struct rsq_data_t *rsq_data) { u8 cmd[8]; u8 rsp[13]; cmd[0] = FM_RSQ_STATUS; cmd[1] = 0; if (intack) cmd[1] |= FM_RSQ_STATUS_IN_INTACK; si47xx_command(2, cmd, 8, rsp); rsq_data->rsqints = rsp[1]; rsq_data->smute = !!(rsp[2] & FM_RSQ_STATUS_OUT_SMUTE); rsq_data->afcrl = !!(rsp[2] & FM_RSQ_STATUS_OUT_AFCRL); rsq_data->valid = !!(rsp[2] & FM_RSQ_STATUS_OUT_VALID); rsq_data->pilot = !!(rsp[3] & FM_RSQ_STATUS_OUT_PILOT); rsq_data->blend = rsp[3] & FM_RSQ_STATUS_OUT_STBLEND; rsq_data->rssi = rsp[4]; rsq_data->snr = rsp[5]; rsq_data->freqoff = rsp[7]; }
static int powerdown(void) { int ret = 0; u8 cmd[8]; u8 rsp[13]; if (!(RADIO_POWERDOWN == Si47xx_dev->state.power_state)) { cmd[0] = POWER_DOWN; ret = si47xx_command(1, cmd, 1, rsp); if (ret < 0) dev_err(Si47xx_dev->dev, "%s failed %d\n", __func__, ret); else Si47xx_dev->state.power_state = RADIO_POWERDOWN; msleep(110); pSi47xxdata->power(0); } else debug("Device already Powered-OFF\n"); return ret; }
bit configSetStartupConfig() { byte commands = 0; byte index; word addr; wait_ms(5); i2cFlag = I2C_READ | I2C_START | I2C_STOP | I2C_WORD_ADDR_TYPE; SET_I2C(EEPROM_I2C_ADDR, TX_CONFIG_OFFSET+CONF_NUM_CMDS_OFFSEET, &commands, 1, i2cFlag); if(!devRomFunction(ROM_I2C_ACCESS)) return FALSE; if(!commands || commands > 62) return FALSE; wait_ms(5); for(index=1; index<=commands; index++) { addr = TX_CONFIG_OFFSET+(8*index); i2cFlag = I2C_READ | I2C_START | I2C_STOP | I2C_WORD_ADDR_TYPE; SET_I2C(EEPROM_I2C_ADDR, addr, &buff_request, 8, i2cFlag); if(!devRomFunction(ROM_I2C_ACCESS)) return FALSE; wait_ms(5); si47xx_command(8, buff_request, 8, buff_response); // if(buff_ret != SI4711_OK) // return FALSE; /* wait for tSTC and tCOMP */ switch(buff_request[0]) { case TX_TUNE_FREQ: wait_ms(100); break; case TX_TUNE_POWER: wait_ms(20); if(buff_request[3] >= 88) { TxPoweredUp = TRUE; } else { TXLed = LED_OFF; TxPoweredUp = FALSE; ASQLOWLed = LED_OFF; ASQHILed = LED_OFF; ASQOVRMLed = LED_OFF; } break; case SET_PROPERTY: wait_ms(10); if(buff_request[2] == 0x21 && buff_request[3] == 0x01) { DeviationValueThatSet = MAKE_WORD(buff_request[4], buff_request[5]); DeviationValueCounted = DeviationValueThatSet; } break; default: wait_ms(5); break; } } //set audio config after it! si47xxSetAudio(TRUE); // if(buff_ret != SI4711_OK) // return FALSE; return TRUE; }
void READ_ASQ_STATUS() { byte status=0; //bit old_val; if(!FePoweredUp) return; asq_delayed++; if(asq_delayed < 10000) return; asq_delayed=0; FELed = !FELed; buff_request[0] = GET_INT_STATUS; si47xx_command(1, buff_request, 1, &status); if(!(status & CTS) || (status & ERR)) { FELed = !FELed; return; } if(status & STCINT) { buff_request[0] = TX_TUNE_STATUS; buff_request[1] = TX_TUNE_STATUS_IN_INTACK; si47xx_command(2, buff_request, 7, buff_response); if(!(buff_response[0] & CTS) || (buff_response[0] & ERR)) { FELed = !FELed; return; } TxFreq = MAKE_WORD(buff_response[2],buff_response[3]); TxPower = buff_response[5]; TxAntCap = buff_response[6]; TxRnl = buff_response[7]; if(TxFreq && TxPower) TXLed = LED_ON; else TXLed = LED_OFF; } if(!TxPoweredUp) return; buff_request[0] = TX_ASQ_STATUS; /* if interrupt, then clean counters, * in other case, just read current level */ if(status & ASQINT) buff_request[1] = TX_ASQ_STATUS_IN_INTACK; else buff_request[1] = 0x00; si47xx_command(2, buff_request, 5, buff_response); if(!(buff_response[0] & CTS) || (buff_response[0] & ERR)) { FELed = !FELed; return; } asq_level = buff_response[4]; if(status & ASQINT) { asq_overmod = buff_response[1] & TX_ASQ_STATUS_OUT_OVERMOD; asq_iall = buff_response[1] & TX_ASQ_STATUS_OUT_IALL; asq_ialh = buff_response[1] & TX_ASQ_STATUS_OUT_IALH; ASQLOWLed = asq_iall ? LED_ON : LED_OFF; ASQHILed = asq_ialh ? LED_ON : LED_OFF; ASQOVRMLed = asq_overmod ? LED_ON : LED_OFF; } //old_val = ASQLOWLed; //ASQLOWLed = ASQHILed = ASQOVRMLed = !old_val; }
/*=================================================================== IEP3_HID(): Prepare Data to send from SI4711 to PC through IEP3 HID ===================================================================*/ void HID_ACCESS() { #ifdef _HID_ if ( (PCCommand == PCTransfer) && !(PCRequest&RequestDone) ) { switch (PCRequest) { case(RequestSi4711Reset): //bReportOut: // +-----------+-----------+ // | PCCommand | PCRequest | // +-----------+-----------+ si47xxReset(); break; case(RequestCpuId): // +-----------+-----------+--------------+----------+-------------+----------+---------------+ // | PCCommand | PCRequest | REV_MINOR[2] | STR_SIZE | REV_MAJOR[] | STR_SIZE | DEVICE_NAME[] | // +-----------+-----------+--------------+----------+-------------+----------+---------------+ Xdata.InEp3.HidReport.bReportItem[2] = (0xFF00 & REVISION_MAJOR) >> 8; Xdata.InEp3.HidReport.bReportItem[3] = 0x00FF & REVISION_MAJOR; Xdata.InEp3.HidReport.bReportItem[4] = sizeof(REVISION_MINOR); AppDevice.dummy.bData[0] = 0; for(AppDevice.dummy.bData[0] = 0; AppDevice.dummy.bData[0] < sizeof(REVISION_MINOR); AppDevice.dummy.bData[0]++) Xdata.InEp3.HidReport.bReportItem[5 + AppDevice.dummy.bData[0]] = REVISION_MINOR[AppDevice.dummy.bData[0]]; Xdata.InEp3.HidReport.bReportItem[5 + AppDevice.dummy.bData[0]] = sizeof(DEVICE_NAME); AppDevice.dummy.bData[1] = AppDevice.dummy.bData[0] + 5 + 1; for(AppDevice.dummy.bData[0] = 0; AppDevice.dummy.bData[0] < sizeof(DEVICE_NAME); AppDevice.dummy.bData[0]++) Xdata.InEp3.HidReport.bReportItem[AppDevice.dummy.bData[1] + AppDevice.dummy.bData[0]] = DEVICE_NAME[AppDevice.dummy.bData[0]]; break; case(RequestSi4711PowerStatus): // +-----------+-----------+-------------+----------------+ // | PCCommand | PCRequest | IsPoweredUp | IsTransmitting | // +-----------+-----------+-------------+----------------+ Xdata.InEp3.HidReport.bReportItem[2] = FePoweredUp; Xdata.InEp3.HidReport.bReportItem[3] = TxPoweredUp; break; case(RequestSi4711PowerUp): if(FePoweredUp) { PCCommand |= PCRequestError; break; } else { FePoweredUp=TRUE; } //bReportOut: // +-----------+-----------+---------+-----------+ // | PCCommand | PCRequest | IsError | ErrorCode | // +-----------+-----------+---------+-----------+ buff_ret = SI4711_COMM_ERR; Xdata.InEp3.HidReport.bReportItem[3] = 1; si47xxPowerUp(); if(!(buff_response[0] & CTS)) { Xdata.InEp3.HidReport.bReportItem[2] = buff_ret; break; } buff_ret = SI4711_COMM_ERR; Xdata.InEp3.HidReport.bReportItem[3] = 2; si47xxFMTX_hardware_cfg(); Xdata.InEp3.HidReport.bReportItem[2] = buff_ret; FELed = LED_ON; break; case(RequestSi4711PowerDown): if(!FePoweredUp) { PCCommand |= PCRequestError; break; } //bReportOut: // +-----------+-----------+---------+-----------+ // | PCCommand | PCRequest | IsError | ErrorCode | // +-----------+-----------+---------+-----------+ buff_ret = SI4711_COMM_ERR; si47xxPowerDown(); if(buff_ret != SI4711_OK || !(buff_response[0] & CTS)) { Xdata.InEp3.HidReport.bReportItem[2] = buff_ret; si47xxReset(); //force! } break; case(RequestSi4711AudioEnable): if(!FePoweredUp) { PCCommand |= PCRequestError; break; } buff_ret = SI4711_COMM_ERR; si47xxSetAudio(TRUE); Xdata.InEp3.HidReport.bReportItem[2] = buff_ret; break; case(RequestSi4711AudioDisable): if(!FePoweredUp) { PCCommand |= PCRequestError; break; } buff_ret = SI4711_COMM_ERR; si47xxSetAudio(FALSE); Xdata.InEp3.HidReport.bReportItem[2] = buff_ret; break; case(RequestEepromSectionRead): //bReportOut: // +-----------+-----------+---------+-------+ // | PCCommand | PCRequest | Offset | bytes | // +-----------+-----------+---------+-------+ if(Xdata.OutEp4.HidOReport.bReportOut[4] > 32) { PCCommand |= PCRequestError; break; } AppDevice.dummy.wData[0] = MAKE_WORD(Xdata.OutEp4.HidOReport.bReportOut[2], Xdata.OutEp4.HidOReport.bReportOut[3]); if(AppDevice.dummy.wData[0] + Xdata.OutEp4.HidOReport.bReportOut[4] > 0x2000) { PCCommand |= PCRequestError; break; } i2cFlag = I2C_READ | I2C_START | I2C_STOP | I2C_WORD_ADDR_TYPE; SET_I2C(EEPROM_I2C_ADDR, AppDevice.dummy.wData[0], &Xdata.InEp3.HidReport.bReportItem[3], Xdata.OutEp4.HidOReport.bReportOut[4], i2cFlag); Xdata.InEp3.HidReport.bReportItem[2] = devRomFunction(ROM_I2C_ACCESS); //bReportItem: // +-----------+-----------+--------+---------+- ... -+---------+ // | PCCommand | PCRequest | status | data[0] | ... | data[n] | // +-----------+-----------+--------+---------+- ... -+---------+ break; case(RequestEepromSectionWrite): //bReportOut: // +-----------+-----------+---------+-------+---------+- ... -+---------+ // | PCCommand | PCRequest | Offset | bytes | data[0] | ... | data[n] | // +-----------+-----------+---------+-------+---------+- ... -+---------+ if(Xdata.OutEp4.HidOReport.bReportOut[4] > 32) { PCCommand |= PCRequestError; break; } AppDevice.dummy.wData[0] = MAKE_WORD(Xdata.OutEp4.HidOReport.bReportOut[2], Xdata.OutEp4.HidOReport.bReportOut[3]); if(AppDevice.dummy.wData[0] + Xdata.OutEp4.HidOReport.bReportOut[4] > 0x2000) { PCCommand |= PCRequestError; break; } i2cFlag = I2C_WRITE | I2C_START | I2C_STOP | I2C_WORD_ADDR_TYPE; SET_I2C(EEPROM_I2C_ADDR, AppDevice.dummy.wData[0], &Xdata.OutEp4.HidOReport.bReportOut[5], Xdata.OutEp4.HidOReport.bReportOut[4], i2cFlag); Xdata.InEp3.HidReport.bReportItem[2] = devRomFunction(ROM_I2C_ACCESS); //bReportItem: // +-----------+-----------+--------+ // | PCCommand | PCRequest | status | // +-----------+-----------+--------+ break; case(RequestSi4711SetProp): if(!FePoweredUp) { PCCommand |= PCRequestError; break; } //bReportOut: // +-----------+-----------+---------+ // | PCCommand | PCRequest | IsError | // +-----------+-----------+---------+ //reversal order here AppDevice.dummy.wData[0] = MAKE_WORD(Xdata.OutEp4.HidOReport.bReportOut[2], Xdata.OutEp4.HidOReport.bReportOut[3]); //must set other way if(AppDevice.dummy.wData[0] == REFCLK_PRESCALE || AppDevice.dummy.wData[0] == REFCLK_FREQ || AppDevice.dummy.wData[0] == DIGITAL_INPUT_FORMAT || AppDevice.dummy.wData[0] == DIGITAL_INPUT_SAMPLE_RATE || AppDevice.dummy.wData[0] == GPO_IEN) { Xdata.InEp3.HidReport.bReportItem[2] = SI4711_BAD_ARG; PCCommand |= PCRequestError; break; } AppDevice.dummy.wData[1] = MAKE_WORD(Xdata.OutEp4.HidOReport.bReportOut[4], Xdata.OutEp4.HidOReport.bReportOut[5]); buff_ret = SI4711_COMM_ERR; Xdata.InEp3.HidReport.bReportItem[6] = si47xx_set_property(AppDevice.dummy.wData[0], AppDevice.dummy.wData[1]); Xdata.InEp3.HidReport.bReportItem[7] = buff_response[0]; Xdata.InEp3.HidReport.bReportItem[8] = buff_ret; Xdata.InEp3.HidReport.bReportItem[2] = Xdata.OutEp4.HidOReport.bReportOut[2]; Xdata.InEp3.HidReport.bReportItem[3] = Xdata.OutEp4.HidOReport.bReportOut[3]; Xdata.InEp3.HidReport.bReportItem[4] = Xdata.OutEp4.HidOReport.bReportOut[4]; Xdata.InEp3.HidReport.bReportItem[5] = Xdata.OutEp4.HidOReport.bReportOut[5]; // hack for set volume if(AppDevice.dummy.wData[0] == TX_AUDIO_DEVIATION) { DeviationValueThatSet = AppDevice.dummy.wData[1]; coSpkUpdate(); } //bReportOut: // +-----------+-----------+---------+------------+------+------+ // | PCCommand | PCRequest | IsError | IsErrorGet | ValH | ValL | // +-----------+-----------+---------+------------+------+------+ #ifndef _PROP_RECHECK_ //re-check out property! AppDevice.dummy.wData[1] = 0; break; #endif case(RequestSi4711GetProp): if(!FePoweredUp) { PCCommand |= PCRequestError; break; } //bReportOut: // +-----------+-----------+---------+ // | PCCommand | PCRequest | IsError | // +-----------+-----------+---------+ AppDevice.dummy.wData[0] = MAKE_WORD(Xdata.OutEp4.HidOReport.bReportOut[2], Xdata.OutEp4.HidOReport.bReportOut[3]); AppDevice.dummy.wData[1] = 0; buff_ret = SI4711_COMM_ERR; Xdata.InEp3.HidReport.bReportItem[6] = si47xx_get_property(AppDevice.dummy.wData[0], &AppDevice.dummy.wData[1]); Xdata.InEp3.HidReport.bReportItem[7] = buff_response[0]; Xdata.InEp3.HidReport.bReportItem[8] = buff_ret; Xdata.InEp3.HidReport.bReportItem[2] = Xdata.OutEp4.HidOReport.bReportOut[2]; Xdata.InEp3.HidReport.bReportItem[3] = Xdata.OutEp4.HidOReport.bReportOut[3]; Xdata.InEp3.HidReport.bReportItem[4] = MSB(AppDevice.dummy.wData[1]); Xdata.InEp3.HidReport.bReportItem[5] = LSB(AppDevice.dummy.wData[1]); break; case(RequestSi4711Access): if(!FePoweredUp) { PCCommand |= PCRequestError; break; } Xdata.InEp3.HidReport.bReportItem[2] = 0; Xdata.InEp3.HidReport.bReportItem[3] = 0; Xdata.InEp3.HidReport.bReportItem[4] = 0; if(Xdata.OutEp4.HidOReport.bReportOut[2] < 1) { PCCommand |= PCRequestError; Xdata.InEp3.HidReport.bReportItem[2] = FALSE; Xdata.InEp3.HidReport.bReportItem[3] = SI4711_BAD_ARG; break; } //bReportOut: // +-----------+-----------+---------+---------+--------+- ... -+--------+ // | PCCommand | PCRequest | ArgsLen | Command | Arg[1] | ... | Arg[7] | // +-----------+-----------+---------+---------+--------+- ... -+--------+ //bReportItem: // +-----------+-----------+-------------+------------+---------+---------+---------+ ... -+----------+ // | PCCommand | PCRequest | WriteStatus | ReadStatus | RespLen | Status | Resp[1] | ... | Resp[15] | // +-----------+-----------+-------------+------------+---------+---------+---------+ ... -+----------+ //do it other way! if(Xdata.OutEp4.HidOReport.bReportOut[3] == POWER_UP || Xdata.OutEp4.HidOReport.bReportOut[3] == POWER_DOWN || Xdata.OutEp4.HidOReport.bReportOut[3] == TX_ASQ_STATUS || Xdata.OutEp4.HidOReport.bReportOut[3] == TX_TUNE_STATUS || Xdata.OutEp4.HidOReport.bReportOut[3] == SET_PROPERTY || Xdata.OutEp4.HidOReport.bReportOut[3] == GET_PROPERTY ) { Xdata.InEp3.HidReport.bReportItem[2] = FALSE; Xdata.InEp3.HidReport.bReportItem[3] = SI4711_BAD_ARG; break; } /* Write command */ Xdata.InEp3.HidReport.bReportItem[4] = 16; // RespLen buff_ret = SI4711_COMM_ERR; Xdata.InEp3.HidReport.bReportItem[2] = si47xx_command(Xdata.OutEp4.HidOReport.bReportOut[2], &Xdata.OutEp4.HidOReport.bReportOut[3], Xdata.InEp3.HidReport.bReportItem[4], &Xdata.InEp3.HidReport.bReportItem[5]); Xdata.InEp3.HidReport.bReportItem[3] = buff_ret; /* Set specific delay, depends on what command sent. */ if(Xdata.OutEp4.HidOReport.bReportOut[3] == TX_TUNE_POWER) { if(Xdata.OutEp4.HidOReport.bReportOut[6] >= 88) { TxPoweredUp = TRUE; } else { // TXLed = LED_OFF; TxPoweredUp = FALSE; ASQLOWLed = LED_OFF; ASQHILed = LED_OFF; ASQOVRMLed = LED_OFF; } } Xdata.InEp3.HidReport.bReportItem[21] = AppDevice.spk.preVol[DEV_SPK_LEFT_CN]; Xdata.InEp3.HidReport.bReportItem[22] = AppDevice.spk.preVol[DEV_SPK_RIGHT_CN]; Xdata.InEp3.HidReport.bReportItem[23] = MSB(DeviationValueCounted); Xdata.InEp3.HidReport.bReportItem[24] = LSB(DeviationValueCounted); break; case(RequestSi4711AsqStatus): if(!FePoweredUp || !TxPoweredUp) { PCCommand |= PCRequestError; break; } //bReportOut: // +-----------+-----------+---------+---------+------+------+-------+ // | PCCommand | PCRequest | IsError | overmod | iall | ialh | level | // +-----------+-----------+---------+---------+------+------+-------+ Xdata.InEp3.HidReport.bReportItem[2] = 0x00; Xdata.InEp3.HidReport.bReportItem[3] = asq_overmod; Xdata.InEp3.HidReport.bReportItem[4] = asq_iall; Xdata.InEp3.HidReport.bReportItem[5] = asq_ialh; Xdata.InEp3.HidReport.bReportItem[6] = asq_level; break; case(RequestSi4711TuneStatus): if(!FePoweredUp) { PCCommand |= PCRequestError; break; } //bReportOut: // +-----------+-----------+---------+---------+---------+-------+--------+-----+ // | PCCommand | PCRequest | IsError | FREQ[m] | FREQ[l] | power | antcap | rnl | // +-----------+-----------+---------+---------+---------+-------+--------+-----+ Xdata.InEp3.HidReport.bReportItem[2] = 0x00; Xdata.InEp3.HidReport.bReportItem[3] = MSB(TxFreq); Xdata.InEp3.HidReport.bReportItem[4] = LSB(TxFreq); Xdata.InEp3.HidReport.bReportItem[5] = TxPower; Xdata.InEp3.HidReport.bReportItem[6] = TxAntCap; Xdata.InEp3.HidReport.bReportItem[7] = TxRnl; break; default: PCCommand |= PCRequestError; break; } // send data to PC through USP HID PCRequest |= RequestDone; Xdata.InEp3.HidReport.bReportItem[0] = PCCommand; Xdata.InEp3.HidReport.bReportItem[1] = PCRequest; while (!(IEPDCNTX3&0x80)); IEPDCNTX3 = sizeof(Xdata.InEp3.HidReport); } #endif }