Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of jro by
JroDDS.cpp
- Committer:
- miguelcordero191
- Date:
- 2015-02-05
- Revision:
- 3:f0e6c145b075
- Parent:
- 2:3d8d52e9751c
- Child:
- 4:de495ce256b8
File content as of revision 3:f0e6c145b075:
#include "JroDDS.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";
DDS::DDS(SPI *spi_dev, DigitalOut *mreset, DigitalOut *outramp, DigitalOut *spmode, DigitalOut *cs, DigitalOut *ioreset, DigitalInOut *updclk){
spi_device = spi_dev;
dds_mreset = mreset;
dds_outramp = outramp;
dds_sp_mode = spmode;
dds_cs = cs;
dds_io_reset = ioreset;
dds_updclk = updclk;
dds_updclk->input();
*dds_sp_mode = 0;
*dds_cs = 1;
*dds_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 DDS::__writeData(char addr, char ndata, const char* data){
// I/O reset
*dds_updclk = 0;
*dds_io_reset = 1;
wait_us(10);
*dds_io_reset = 0;
wait_us(10);
*dds_cs = 0;
//Sending serial address
//printf("\r\nWriting Addr = %d", addr);
spi_device->write(addr & 0x0F);
for(char i = 0; i < ndata; i++)
{
wait_us(150);
spi_device->write(data[i]);
}
*dds_cs = 1;
/*
for(char i = 0; i < ndata; i++)
{
printf("\tData[%d] = 0x%x", i, data[i]);
}
*/
wait_us(10);
*dds_updclk = 1;
wait_us(10);
*dds_updclk = 0;
wait_us(10);
return 1;
}
char* DDS::__readData(char addr, char ndata){
// I/O reset
*dds_io_reset = 1;
wait_us(10);
*dds_io_reset = 0;
wait_us(10);
*dds_cs = 0;
//Sending serial address
//printf("\r\nReading Addr = %d", addr);
spi_device->write((addr & 0x0F) | 0x80);
for(char i = 0; i < ndata; i++)
{
wait_us(150);
read_spi_data[i] = spi_device->write(0x00);
}
*dds_cs = 1;
/*
for(char i = 0; i < ndata; i++)
{
printf("\r\nData[%d] = 0x%x", i, read_spi_data[i]);
}
*/
wait_us(10);
return read_spi_data;
}
int DDS::__writeDataAndVerify(char addr, char ndata, const char* wr_spi_data, SerialDriver *screen){
bool success;
char* rd_spi_data;
this->__writeData(addr, ndata, wr_spi_data);
rd_spi_data = this->__readData(addr, ndata);
success = 1;
for(char i = 0; i < ndata; i++)
{
if (screen != NULL){
screen->putc(wr_spi_data[i]);
screen->putc(0x3D);
screen->putc(rd_spi_data[i]);
}
if (wr_spi_data[i] != rd_spi_data[i])
{
success = 0;
break;
}
}
//printf("\r\nSuccessful writting = %d\r\n", success);
return success;
}
char* DDS::__getControlRegister(){
bool pll_range = 0;
bool pll_bypass = 1;
if (cr_multiplier >= 4){
pll_bypass = 0;
}
if (frequency >= 200){
pll_range = 1;
}
controlRegister[0] = 0x10 + cr_qdac_pwdn*4;
controlRegister[1] = pll_range*64 + pll_bypass*32 + (cr_multiplier & 0x1F);
controlRegister[2] = (cr_mode & 0x07)*2 + cr_ioupdclk;
controlRegister[3] = cr_inv_sinc*64 + cr_osk_en*32 + cr_osk_int*16 + cr_msb_lsb*2 + cr_sdo;
return controlRegister;
}
int DDS::__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, ndata, wr_spi_data);
////printf("\r\nChanging UPD_CLK as an OUTPUT ...");
dds_updclk->output();
wait_us(100);
*dds_updclk = 1;
wait_us(10);
*dds_updclk = 0;
wait_us(10);
rd_spi_data = this->__readData(addr, ndata);
success = true;
for(char i = 0; i < ndata; i++)
{
if (wr_spi_data[i] != rd_spi_data[i])
{
success = false;
break;
}
}
return success;
}
int DDS::reset(){
// Master reset
//Set as a input, temporary
//printf("\r\nChange updclk direction as an INPUT ...\r\n");
dds_updclk->input();
dds_updclk->mode(PullDown);
//printf("\r\nReseting DDS ...\r\n");
*dds_mreset = 1;
wait_ms(1);
*dds_mreset = 0;
wait_ms(1);
return 0;
}
int DDS::scanIOUpdate(){
unsigned int cont = 0;
this->reset();
//printf("\r\nWaiting a upd_clk ...\r\n");
while(true){
if (*dds_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 DDS::find(){
/*
char phase[];
phase[0] = 0x0A;
phase[1] = 0x55;
this->__writeDataAndVerify(0x00, 5, phase);
*/
this->__readData(0x05, 4);
this->__readData(0x0A, 1);
return 1;
}
int DDS::init(){
//printf("\r\nSetting default parameters in CR ...\r\n");
//Serial mode enabled
this->frequency = 200.0; // Work frequency in MHz
this->cr_multiplier = 4; // Multiplier 4- 20
this->cr_mode = 0; // Single, FSK, Ramped FSK, Chirp, BPSK
this->cr_qdac_pwdn = 0; // QDAC power down enabled: 0 -> disable
this->cr_ioupdclk = 0; // IO Update clock direction: 0 -> input, 1 -> output
this->cr_inv_sinc = 0; // Sinc inverser filter enable: 0 -> enable
this->cr_osk_en = 1; // Enable Amplitude multiplier: 0 -> disabled
this->cr_osk_int = 0; // register/counter output shaped control: 0 -> register, 1 -> counter
this->cr_msb_lsb = 0; // msb/lsb bit first: 0 -> MSB, 1 -> LSB
this->cr_sdo = 1; // SDO pin active: 0 -> inactive
//printf("\r\nSetting in serial mode ...\r\n");
*dds_sp_mode = 0;
*dds_cs = 1;
this->reset();
//printf("\r\nWritting CR ...\r\n");
if (not this->__writeControlRegister()){
//printf("\r\nUnsuccessful DDS initialization");
this->isConfig = false;
return false;
}
//printf("\r\nSuccessfull DDS initialization");
this->isConfig = true;
return true;
}
char* DDS::rdMode(){
char* rd_data;
char mode;
rd_data = this->__readData(0x07, 4);
mode = (rd_data[2] & 0x0E) >> 1;
rd_data[0] = mode;
return rd_data;
}
char* DDS::rdMultiplier(){
char* rd_data;
char mult;
rd_data = this->__readData(0x07, 4);
mult = (rd_data[1] & 0x1F);
rd_data[0] = mult;
rd_data[1] = ((int)clock >> 8) & 0xff;
rd_data[2] = (int)clock & 0xff;
return rd_data;
}
char* DDS::rdPhase1(){
char* rd_data;
rd_data = this->__readData(0x00, 2);
return rd_data;
}
char* DDS::rdPhase2(){
char* rd_data;
rd_data = this->__readData(0x01, 2);
return rd_data;
}
char* DDS::rdFrequency1(){
char* rd_data;
rd_data = this->__readData(0x02, 6);
return rd_data;
}
char* DDS::rdFrequency2(){
char* rd_data;
rd_data = this->__readData(0x03, 6);
return rd_data;
}
char* DDS::rdAmplitudeI(){
char* rd_data;
rd_data = this->__readData(0x08, 2);
return rd_data;
}
char* DDS::rdAmplitudeQ(){
char* rd_data;
rd_data = this->__readData(0x09, 2);
return rd_data;
}
int DDS::wrMode(char mode){
this->cr_mode = mode & 0x07;
return this->__writeControlRegister();
}
int DDS::wrMultiplier(char multiplier, float clock){
this->cr_multiplier = multiplier & 0x1F;
this->frequency = clock;
//printf("\r\n mult = %d, clock = %f", multiplier, clock);
//printf("\r\n cr_mult = %d", cr_multiplier);
return this->__writeControlRegister();
}
int DDS::wrPhase1(char* phase, SerialDriver *screen){
return this->__writeDataAndVerify(0x00, 2, phase, screen);
}
int DDS::wrPhase2(char* phase, SerialDriver *screen){
return this->__writeDataAndVerify(0x01, 2, phase, screen);
}
int DDS::wrFrequency1(char* freq, SerialDriver *screen){
return this->__writeDataAndVerify(0x02, 6, freq, screen);
}
int DDS::wrFrequency2(char* freq, SerialDriver *screen){
return this->__writeDataAndVerify(0x03, 6, freq, screen);
}
int DDS::wrAmplitudeI(char* amplitude, SerialDriver *screen){
amplitudeI[0] = amplitude[0];
amplitudeI[1] = amplitude[1];
return this->__writeDataAndVerify(0x08, 2, amplitude, screen);
}
int DDS::wrAmplitudeQ(char* amplitude, SerialDriver *screen){
amplitudeQ[0] = amplitude[0];
amplitudeQ[1] = amplitude[1];
return this->__writeDataAndVerify(0x09, 2, amplitude, screen);
}
int DDS::enableRF(){
this->rf_enabled = true;
this->__writeDataAndVerify(0x08, 2, this->amplitudeI);
this->__writeDataAndVerify(0x09, 2, this->amplitudeQ);
return 1;
}
int DDS::disableRF(){
this->rf_enabled = false;
this->__writeDataAndVerify(0x08, 2, "\x00\x00");
this->__writeDataAndVerify(0x09, 2, "\x00\x00");
return 1;
}
int DDS::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)
if (!(screen == NULL)){
screen->putc(0x37);
screen->putc(0x31);
}
return this->wrMode(4); //BPSK mode
}
char* DDS::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 DDS 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 DDS_CMD_RESET:
success = this->init();
break;
case DDS_CMD_ENABLE_RF:
if (payload_len == 1){
if (payload[0] == 0)
success = this->disableRF();
else
success = this->enableRF();
}
break;
case DDS_CMD_MULTIPLIER:
if (payload_len == 3){
unsigned short clock = payload[1]*256 + payload[2];
success = this->wrMultiplier(payload[0], (float)clock);
}
break;
case DDS_CMD_MODE:
if (payload_len == 1){
success = this->wrMode(payload[0]);
}
break;
case DDS_CMD_FREQUENCY1:
if (payload_len == 6){
success = this->wrFrequency1(payload);
}
break;
case DDS_CMD_FREQUENCY2:
if (payload_len == 6){
success = this->wrFrequency2(payload);
}
break;
case DDS_CMD_PHASE1:
if (payload_len == 2){
success = this->wrPhase1(payload);
}
break;
case DDS_CMD_PHASE2:
if (payload_len == 2){
success = this->wrPhase2(payload);
}
break;
case DDS_CMD_AMPLITUDEI:
if (payload_len == 2){
success = this->wrAmplitudeI(payload);
}
break;
case DDS_CMD_AMPLITUDEQ:
if (payload_len == 2){
success = this->wrAmplitudeQ(payload);
}
break;
case DDS_CMD_READ | DDS_CMD_ENABLE_RF:
if (rf_enabled == 1)
tx_msg = "\x01";
else
tx_msg = "\x00";
tx_msg_len = 1;
break;
case DDS_CMD_READ | DDS_CMD_MULTIPLIER:
tx_msg = this->rdMultiplier();
tx_msg_len = 3;
break;
case DDS_CMD_READ | DDS_CMD_MODE:
tx_msg = this->rdMode();
tx_msg_len = 1;
break;
case DDS_CMD_READ | DDS_CMD_FREQUENCY1:
tx_msg = this->rdFrequency1();
tx_msg_len = 6;
break;
case DDS_CMD_READ | DDS_CMD_FREQUENCY2:
tx_msg = this->rdFrequency2();
tx_msg_len = 6;
break;
case DDS_CMD_READ | DDS_CMD_PHASE1:
tx_msg = this->rdPhase1();
tx_msg_len = 2;
break;
case DDS_CMD_READ | DDS_CMD_PHASE2:
tx_msg = this->rdPhase2();
tx_msg_len = 2;
break;
case DDS_CMD_READ | DDS_CMD_AMPLITUDEI:
tx_msg = this->rdAmplitudeI();
tx_msg_len = 2;
break;
case DDS_CMD_READ | DDS_CMD_AMPLITUDEQ:
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* DDS::getCmdAnswer(){
return this->cmd_answer;
}
unsigned long DDS::getCmdAnswerLen(){
return this->cmd_answer_len;
}
int DDS::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; //cr_ioupdclk always as an input = 0
control_reg[3] = control_reg[3] | 0x01; //cr_sdo enable = 1
this->wrPhase1(phase1);
this->wrPhase2(phase2);
this->wrFrequency1(freq1);
this->wrFrequency2(freq2);
this->__writeDataAndVerify(0x10, 6, delta_freq);
this->__writeDataAndVerify(0x16, 4, upd_rate_clk);
this->__writeDataAndVerify(0x1A, 3, ramp_rate_clk);
this->__writeDataAndVerify(0x1D, 4, control_reg);
this->wrAmplitudeI(amplitudeI);
this->wrAmplitudeQ(amplitudeQ);
this->__writeDataAndVerify(0x25, 1, ampl_ramp_rate);
sts = this->__writeDataAndVerify(0x26, 2, qdac, screen);
return sts;
}
