Library for the JRO Radar Controller
CR2.cpp
- Committer:
- joaquinbvw
- Date:
- 2016-03-14
- Revision:
- 0:e3f3fe2e689b
File content as of revision 0:e3f3fe2e689b:
#include "CR2.h" static char controlRegister[4]; static char read_spi_data[6]; static char* KO_MSG = "KO"; static char* OK_MSG = "OK"; static char* NI_MSG = "NI"; static char* ZERO_MSG = "\x00"; static char* ONE_MSG = "\x01"; static char *MODULATION[6] = {"None ", "FSK ", "Ramped FSK ", "Chirp ", "BPSK ", "Not Allowed "}; CR2::CR2(SPI *spi_dev, DigitalOut *mreset, DigitalOut *outramp, DigitalOut *spmode, DigitalOut *cs, DigitalOut *ioreset, DigitalInOut *updclk){ spi_device = spi_dev; cr2_mreset = mreset; cr2_outramp = outramp; cr2_sp_mode = spmode; cr2_cs = cs; cr2_io_reset = ioreset; cr2_updclk = updclk; cr2_updclk->input(); *cr2_sp_mode = 0; *cr2_cs = 1; *cr2_outramp = 0; cmd_answer = NULL; cmd_answer_len = 0; spi_device->format(SPI_BITS, SPI_MODE); spi_device->frequency(SPI_FREQ); this->isConfig = false; } int CR2::__writeData(char addr, char data){ // I/O reset *cr2_updclk = 0; *cr2_io_reset = 1; wait_us(10); *cr2_io_reset = 0; wait_us(10); *cr2_cs = 0; //Sending serial address //printf("\r\nWriting Addr = %d", addr); spi_device->write(addr | 0x80); wait_us(150); spi_device->write(data); *cr2_cs = 1; /* for(char i = 0; i < ndata; i++) { printf("\tData[%d] = 0x%x", i, data[i]); } */ wait_us(10); *cr2_updclk = 1; wait_us(10); *cr2_updclk = 0; wait_us(10); return 1; } int CR2::writeBlock(char ndata, const char* data){ // I/O reset *cr2_updclk = 0; *cr2_io_reset = 1; wait_us(10); *cr2_io_reset = 0; wait_us(10); *cr2_cs = 0; for(char i = 0; i < (ndata/2); i++) { wait_us(150); char addr = data[2*i]; char dat = data[2*i+1]; this->__writeData(addr,dat); } *cr2_cs = 1; /* for(char i = 0; i < ndata; i++) { printf("\tData[%d] = 0x%x", i, data[i]); } */ wait_us(10); *cr2_updclk = 1; wait_us(10); *cr2_updclk = 0; wait_us(10); if (ndata%2) { return 0; } else { return 1; } } char CR2::__readData(char addr){ char spi_data = 0; // I/O reset *cr2_io_reset = 1; wait_us(10); *cr2_io_reset = 0; wait_us(10); *cr2_cs = 0; //Sending serial address //printf("\r\nReading Addr = %d", addr); spi_device->write(addr & 0x7F); wait_us(150); spi_data = spi_device->write(0x00); *cr2_cs = 1; /* for(char i = 0; i < ndata; i++) { printf("\r\nData[%d] = 0x%x", i, read_spi_data[i]); } */ wait_us(10); return spi_data; } int CR2::__writeDataAndVerify(char addr, char wr_spi_data, SerialDriver *screen){ int success; char rd_spi_data; this->__writeData(addr, wr_spi_data); rd_spi_data = this->__readData(addr); success = 1; screen->putc(wr_spi_data); screen->putc(0x3D); screen->putc(rd_spi_data); if (wr_spi_data != rd_spi_data) { success = 0; } //Update Control Register /* if ((success == 1) && (addr==0x07)){ cr2_multiplier = rd_spi_data[1] & 0x1F; cr2_mode = (rd_spi_data[2] & 0x0E) >> 1; } */ //printf("\r\nSuccessful writting = %d\r\n", success); return success; } /* char* CR2::__getControlRegister(){ bool pll_range = 0; bool pll_bypass = 1; if (cr2_multiplier >= 4){ pll_bypass = 0; } if (clock >= 200){ pll_range = 1; } controlRegister[0] = 0x10 + cr2_qdac_pwdn*4; controlRegister[1] = pll_range*64 + pll_bypass*32 + (cr2_multiplier & 0x1F); controlRegister[2] = (cr2_mode & 0x07)*2 + cr2_ioupdclk; controlRegister[3] = cr2_inv_sinc*64 + cr2_osk_en*32 + cr2_osk_int*16 + cr2_msb_lsb*2 + cr2_sdo; return controlRegister; } int CR2::__writeControlRegister(){ bool success; char wr_spi_data; char* rd_spi_data; char addr = 0x07, ndata = 4; wr_spi_data = this->__getControlRegister(); success = this->__writeData(addr, wr_spi_data); ////printf("\r\nChanging UPD_CLK as an OUTPUT ..."); cr2_updclk->output(); wait_us(100); *cr2_updclk = 1; wait_us(10); *cr2_updclk = 0; wait_us(10); rd_spi_data = this->__readData(addr); success = true; for(char i = 0; i < ndata; i++) { if (wr_spi_data[i] != rd_spi_data[i]) { success = false; break; } } return success; } */ int CR2::reset(){ // Master reset //Set as a input, temporary //printf("\r\nChange updclk direction as an INPUT ...\r\n"); cr2_updclk->input(); cr2_updclk->mode(PullDown); //printf("\r\nReseting CR2 ...\r\n"); *cr2_mreset = 1; wait_ms(1); *cr2_mreset = 0; wait_ms(1); this->rf_enabled = false; return 0; } int CR2::scanIOUpdate(){ unsigned int cont = 0; this->reset(); //printf("\r\nWaiting a upd_clk ...\r\n"); while(true){ if (*cr2_updclk == 1) break; cont += 1; if (cont > 10000) break; wait_us(1); } if (cont > 10000){ //printf("\r\nA upd_clk was not found\r\n"); return 0; } //printf("\r\nA upd_clk was found ...\r\n"); return 1; } int CR2::find(){ /* char phase[]; phase[0] = 0x0A; phase[1] = 0x55; this->__writeDataAndVerify(0x00, 5, phase); */ this->__readData(0x05); this->__readData(0x0A); return 1; } int CR2::init(){ //printf("\r\nSetting default parameters in CR ...\r\n"); //Serial mode enabled this->clock = 200.0; // Work clock in MHz this->cr2_multiplier = 4; // Multiplier 4- 20 this->cr2_mode = 0; // Single, FSK, Ramped FSK, Chirp, BPSK this->cr2_qdac_pwdn = 0; // QDAC power down enabled: 0 -> disable this->cr2_ioupdclk = 0; // IO Update clock direction: 0 -> input, 1 -> output this->cr2_inv_sinc = 0; // Sinc inverser filter enable: 0 -> enable this->cr2_osk_en = 1; // Enable Amplitude multiplier: 0 -> disabled this->cr2_osk_int = 0; // register/counter output shaped control: 0 -> register, 1 -> counter this->cr2_msb_lsb = 0; // msb/lsb bit first: 0 -> MSB, 1 -> LSB this->cr2_sdo = 1; // SDO pin active: 0 -> inactive //printf("\r\nSetting in serial mode ...\r\n"); *cr2_sp_mode = 0; *cr2_cs = 1; this->reset(); //printf("\r\nWritting CR ...\r\n"); /* if (not this->__writeControlRegister()){ //printf("\r\nUnsuccessful CR2 initialization"); this->isConfig = false; return false; } */ //printf("\r\nSuccessfull CR2 initialization"); this->isConfig = true; return true; } /* char* CR2::rdMode(){ char* rd_data; char mode; rd_data = this->__readData(0x07); mode = (rd_data[2] & 0x0E) >> 1; this->cr2_mode = mode; rd_data[0] = mode; return rd_data; } char* CR2::rdMultiplier(){ char* rd_data; char mult; rd_data = this->__readData(0x07); mult = (rd_data[1] & 0x1F); this->cr2_multiplier = mult; //Reaconditioning data to return rd_data[0] = mult; rd_data[1] = ((int)clock >> 8) & 0xff; rd_data[2] = (int)clock & 0xff; return rd_data; } char* CR2::rdPhase1(){ char* rd_data; rd_data = this->__readData(0x00); return rd_data; } char* CR2::rdPhase2(){ char* rd_data; rd_data = this->__readData(0x01); return rd_data; } char* CR2::rdFrequency1(){ char* rd_data; rd_data = this->__readData(0x02); for (int i=0; i<6; i++) frequency1[i] = rd_data[i]; return rd_data; } char* CR2::rdFrequency2(){ char* rd_data; rd_data = this->__readData(0x03); for (int i=0; i<6; i++) frequency2[i] = rd_data[i]; return rd_data; } char* CR2::rdAmplitudeI(){ char* rd_data; rd_data = this->__readData(0x08); return rd_data; } char* CR2::rdAmplitudeQ(){ char* rd_data; rd_data = this->__readData(0x09); return rd_data; } int CR2::isRFEnabled(){ if (this->rf_enabled) return 1; return 0; } int CR2::wrMode(char mode){ this->cr2_mode = mode & 0x07; return this->__writeControlRegister(); } int CR2::wrMultiplier(char multiplier, float clock){ this->cr2_multiplier = multiplier & 0x1F; this->clock = clock; //printf("\r\n mult = %d, clock = %f", multiplier, clock); //printf("\r\n cr2_mult = %d", cr2_multiplier); return this->__writeControlRegister(); } int CR2::wrPhase1(char* phase, SerialDriver *screen){ return this->__writeDataAndVerify(0x00, phase, screen); } int CR2::wrPhase2(char* phase, SerialDriver *screen){ return this->__writeDataAndVerify(0x01, phase, screen); } int CR2::wrFrequency1(char* freq, SerialDriver *screen){ int sts; sts = this->__writeDataAndVerify(0x02, freq, screen); if (sts){ for (int i=0; i<6; i++) frequency1[i] = freq[i]; } return sts; } int CR2::wrFrequency2(char* freq, SerialDriver *screen){ int sts; sts = this->__writeDataAndVerify(0x03, freq, screen); if (sts){ for (int i=0; i<6; i++) frequency2[i] = freq[i]; } return sts; } int CR2::wrAmplitudeI(char* amplitude, SerialDriver *screen){ amplitudeI[0] = amplitude[0]; amplitudeI[1] = amplitude[1]; this->rf_enabled = true; return this->__writeDataAndVerify(0x08, amplitude, screen); } int CR2::wrAmplitudeQ(char* amplitude, SerialDriver *screen){ amplitudeQ[0] = amplitude[0]; amplitudeQ[1] = amplitude[1]; this->rf_enabled = true; return this->__writeDataAndVerify(0x09, amplitude, screen); } int CR2::enableRF(){ this->rf_enabled = true; this->__writeDataAndVerify(0x08, this->amplitudeI); return this->__writeDataAndVerify(0x09, this->amplitudeQ); } int CR2::disableRF(){ this->rf_enabled = false; this->__writeDataAndVerify(0x08, "\x00\x00"); return this->__writeDataAndVerify(0x09, "\x00\x00"); } int CR2::defaultSettings(SerialDriver *screen){ if (!(screen == NULL)){ screen->putc(0x37); screen->putc(0x30); } this->wrMultiplier(1, 0.0); this->wrAmplitudeI("\x0F\xC0", screen); //0xFC0 produces best SFDR than 0xFFF this->wrAmplitudeQ("\x0F\xC0"); //0xFC0 produces best SFDR than 0xFFF this->wrFrequency1("\x00\x00\x00\x00\x00\x00"); // 49.92 <> 0x3f 0xe5 0xc9 0x1d 0x14 0xe3 <> 49.92/clock*(2**48) \x3f\xe5\xc9\x1d\x14\xe3 this->wrFrequency2("\x00\x00\x00\x00\x00\x00"); this->wrPhase1("\x00\x00"); //0 grados this->wrPhase2("\x20\x00"); //180 grados <> 0x20 0x00 <> 180/360*(2**14) this->disableRF(); if (!(screen == NULL)){ screen->putc(0x37); screen->putc(0x31); } return this->wrMode(4); //BPSK mode } */ char* CR2::setCommand(unsigned short cmd, char* payload, unsigned long payload_len){ bool success = false; char* tx_msg; unsigned long tx_msg_len; tx_msg = KO_MSG; tx_msg_len = 2; //printf("cmd = %d, payload_len = %d", cmd, payload_len); //printf("\r\nPayload = "); //for(unsigned long i=0; i< payload_len; i++) //printf("0x%x ", payload[i]); //Si el CR2 no esta inicializado siempre retornar NI_MSG if (not this->isConfig){ this->cmd_answer = NI_MSG; this->cmd_answer_len = 2; return this->cmd_answer; } switch ( cmd ) { case CR2_CMD_RESET: success = this->init(); break; case CR2_CMD_ENABLE_RF: if (payload_len == 1){ //if (payload[0] == 0) //success = this->disableRF(); //else //success = this->enableRF(); } break; case CR2_CMD_MULTIPLIER: if (payload_len == 1){ //success = this->wrMultiplier(payload[0]); } if (payload_len == 3){ unsigned short clock = payload[1]*256 + payload[2]; //success = this->wrMultiplier(payload[0], (float)clock); } break; case CR2_CMD_MODE: if (payload_len == 1){ //success = this->wrMode(payload[0]); } break; case CR2_CMD_FREQUENCYA: if (payload_len == 6){ //success = this->wrFrequency1(payload); } break; case CR2_CMD_FREQUENCYB: if (payload_len == 6){ //success = this->wrFrequency2(payload); } break; case CR2_CMD_PHASEA: if (payload_len == 2){ //success = this->wrPhase1(payload); } break; case CR2_CMD_PHASEB: if (payload_len == 2){ //success = this->wrPhase2(payload); } break; case CR2_CMD_AMPLITUDE1: if (payload_len == 2){ //success = this->wrAmplitudeI(payload); } break; case CR2_CMD_AMPLITUDE2: if (payload_len == 2){ //success = this->wrAmplitudeQ(payload); } break; case CR2_CMD_READ | CR2_CMD_ENABLE_RF: //if (this->isRFEnabled() == 1) // tx_msg = ONE_MSG; //else // tx_msg = ZERO_MSG; tx_msg_len = 1; break; case CR2_CMD_READ | CR2_CMD_MULTIPLIER: //tx_msg = this->rdMultiplier(); tx_msg_len = 1; break; case CR2_CMD_READ | CR2_CMD_MODE: //tx_msg = this->rdMode(); tx_msg_len = 1; break; case CR2_CMD_READ | CR2_CMD_FREQUENCYA: //tx_msg = this->rdFrequency1(); tx_msg_len = 6; break; case CR2_CMD_READ | CR2_CMD_FREQUENCYB: //tx_msg = this->rdFrequency2(); tx_msg_len = 6; break; case CR2_CMD_READ | CR2_CMD_PHASEA: //tx_msg = this->rdPhase1(); tx_msg_len = 2; break; case CR2_CMD_READ | CR2_CMD_PHASEB: //tx_msg = this->rdPhase2(); tx_msg_len = 2; break; case CR2_CMD_READ | CR2_CMD_AMPLITUDE1: //tx_msg = this->rdAmplitudeI(); tx_msg_len = 2; break; case CR2_CMD_READ | CR2_CMD_AMPLITUDE2: //tx_msg = this->rdAmplitudeQ(); tx_msg_len = 2; break; default: success = false; } if (success){ tx_msg = OK_MSG; tx_msg_len = 2; } this->cmd_answer = tx_msg; this->cmd_answer_len = tx_msg_len; return tx_msg; } char* CR2::getCmdAnswer(){ return this->cmd_answer; } unsigned long CR2::getCmdAnswerLen(){ return this->cmd_answer_len; } /* int CR2::setAllDevice(char* payload, SerialDriver *screen){ int sts; char* phase1, *phase2; char* freq1, *freq2; char* delta_freq, *upd_rate_clk, *ramp_rate_clk; char* control_reg; char* amplitudeI, *amplitudeQ, *ampl_ramp_rate; char* qdac; phase1 = &payload[0x00]; phase2 = &payload[0x02]; freq1 = &payload[0x04]; freq2 = &payload[0x0A]; delta_freq = &payload[0x10]; upd_rate_clk = &payload[0x16]; ramp_rate_clk = &payload[0x1A]; control_reg = &payload[0x1D]; amplitudeI = &payload[0x21]; amplitudeQ = &payload[0x23]; ampl_ramp_rate = &payload[0x25]; qdac = &payload[0x26]; control_reg[2] = control_reg[2] & 0xFE; //cr2_ioupdclk always as an input = 0 control_reg[3] = control_reg[3] & 0xFD; //LSB first = 0, MSB first enabled control_reg[3] = control_reg[3] | 0x01; //cr2_sdo enable = 1 this->__writeDataAndVerify(0x04, delta_freq); this->__writeDataAndVerify(0x05, upd_rate_clk); this->__writeDataAndVerify(0x06, ramp_rate_clk); this->__writeDataAndVerify(0x07, control_reg); this->__writeDataAndVerify(0x0A, ampl_ramp_rate); this->__writeDataAndVerify(0x0B, qdac, screen); this->wrPhase1(phase1); this->wrPhase2(phase2); this->wrFrequency1(freq1); this->wrFrequency2(freq2); this->wrAmplitudeI(amplitudeI); this->wrAmplitudeQ(amplitudeQ); //Enabling RF sts = this->enableRF(); return sts; } */ bool CR2::wasInitialized(){ return this->isConfig; } char CR2::getMultiplier(){ return this->cr2_multiplier; } double CR2::getFreqFactor1(){ factor_freq1 = ((double)frequency1[0])/256.0 + ((double)frequency1[1])/65536.0 + ((double)frequency1[2])/16777216.0 + ((double)frequency1[3])/4294967296.0; factor_freq1 *= ((double)this->cr2_multiplier); return factor_freq1; } double CR2::getFreqFactor2(){ factor_freq2 = ((double)frequency2[0])/256.0 + ((double)frequency2[1])/65536.0 + ((double)frequency2[2])/16777216.0 + ((double)frequency2[3])/4294967296.0; factor_freq2 *= ((double)this->cr2_multiplier); return factor_freq2; } char CR2::getMode(){ return this->cr2_mode; } char* CR2::getModeStr(){ if (this->cr2_mode > 4) return MODULATION[5]; return MODULATION[this->cr2_mode]; }