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
dds.cpp
- Committer:
- miguelcordero191
- Date:
- 2014-12-04
- Revision:
- 1:7c424a3e12ea
- Parent:
- 0:b444ea725ba7
File content as of revision 1:7c424a3e12ea:
#include "dds.h"
static char controlRegister[4];
static char read_spi_data[6];
static char* ko_msg = "KO";
static char* ok_msg = "OK";
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("\r\nData[%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){
bool success;
char* rd_spi_data;
this->__writeData(addr, ndata, wr_spi_data);
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;
}
}
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){
return this->__writeDataAndVerify(0x00, 2, phase);
}
int DDS::wrPhase2(char* phase){
return this->__writeDataAndVerify(0x01, 2, phase);
}
int DDS::wrFrequency1(char* freq){
return this->__writeDataAndVerify(0x02, 6, freq);
}
int DDS::wrFrequency2(char* freq){
return this->__writeDataAndVerify(0x03, 6, freq);
}
int DDS::wrAmplitudeI(char* amplitude){
amplitudeI[0] = amplitude[0];
amplitudeI[1] = amplitude[1];
return this->__writeDataAndVerify(0x08, 2, amplitude);
}
int DDS::wrAmplitudeQ(char* amplitude){
amplitudeQ[0] = amplitude[0];
amplitudeQ[1] = amplitude[1];
return this->__writeDataAndVerify(0x09, 2, amplitude);
}
int DDS::enableRF(){
this->rf_enabled = true;
this->wrAmplitudeI(this->amplitudeI);
return this->wrAmplitudeQ(this->amplitudeQ);
}
int DDS::disableRF(){
this->rf_enabled = false;
this->wrAmplitudeI("\x00\x00");
return this->wrAmplitudeQ("\x00\x00");
}
int DDS::defaultSettings(){
this->wrMultiplier(20, 200.0);
this->wrAmplitudeI("\x0F\xC0"); //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)
return this->wrMode(4); //BPSK mode
}
char* DDS::newCommand(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]);
switch ( cmd )
{
case 0x01:
success = this->init();
break;
case 0x02:
if (payload_len == 1){
if (payload[0] == 0)
success = this->disableRF();
else
success = this->enableRF();
}
break;
case 0x10:
if (payload_len == 3){
unsigned short clock = payload[1]*256 + payload[2];
success = this->wrMultiplier(payload[0], (float)clock);
}
break;
case 0x11:
if (payload_len == 1){
success = this->wrMode(payload[0]);
}
break;
case 0x12:
if (payload_len == 6){
success = this->wrFrequency1(payload);
}
break;
case 0x13:
if (payload_len == 6){
success = this->wrFrequency2(payload);
}
break;
case 0x14:
if (payload_len == 2){
success = this->wrPhase1(payload);
}
break;
case 0x15:
if (payload_len == 2){
success = this->wrPhase2(payload);
}
break;
case 0x16:
if (payload_len == 2){
success = this->wrAmplitudeI(payload);
}
break;
case 0x17:
if (payload_len == 2){
success = this->wrAmplitudeQ(payload);
}
break;
case 0x8002:
if (rf_enabled == 1)
tx_msg = "\x01";
else
tx_msg = "\x00";
tx_msg_len = 1;
break;
case 0x8010:
tx_msg = this->rdMultiplier();
tx_msg_len = 3;
break;
case 0x8011:
tx_msg = this->rdMode();
tx_msg_len = 1;
break;
case 0x8012:
tx_msg = this->rdFrequency1();
tx_msg_len = 6;
break;
case 0x8013:
tx_msg = this->rdFrequency2();
tx_msg_len = 6;
break;
case 0x8014:
tx_msg = this->rdPhase1();
tx_msg_len = 2;
break;
case 0x8015:
tx_msg = this->rdPhase2();
tx_msg_len = 2;
break;
case 0x8016:
tx_msg = this->rdAmplitudeI();
tx_msg_len = 2;
break;
case 0x8017:
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;
}
