View previous topic :: View next topic |
Author |
Message |
piripic
Joined: 15 Jan 2008 Posts: 25
|
advice about data structure (ADF7021) |
Posted: Mon May 19, 2008 2:46 am |
|
|
Hi, I am working on firmware in which device ADF7021(Analog device) is used. Seen the relative complexity of subdivision of the bits of the many registries of the device (16), according to you what is the better way to manage this data ?
Constant data structure or what else ? Can I create structures with 'strange' (irregular) numbers of bits (example 10, 5, 18) and then send the whole structure in contiguous way (avoiding to send 'dead' bit between truncated data type) ? Every register has different groups of bits with different scopes and I do not understand how to subdivide that and send after in contiguous mode.
Thank in advance and sorry for my english
Claudio
Last edited by piripic on Mon May 19, 2008 6:02 am; edited 1 time in total |
|
|
piripic
Joined: 15 Jan 2008 Posts: 25
|
|
Posted: Mon May 19, 2008 3:23 am |
|
|
This is my "driver", I do not use SPI because it is used for radio data transfer.
Code: |
// **** Costant declaration (example only) *****
// ADF7021 Register value
// Number of bits , Scope
const int32 REG0 = 0xAABBCCD0; // 32 N_Register
const int32 REG1 = 0x03BB55C1; // 26 VCO/Oscillator Register
const int32 REG2 = 0x7ABBCCD2; // 31 Transmit Modulation Register
const int32 REG3 = 0xAABBCCD3; // 32 Transmit/Receive Clock Register
const int32 REG4 = 0xAABBCCD4; // 32 Demodulator Setup Register
const int32 REG5 = 0xAABBCCD5; // 32 IF Filter Setup Register
const int32 REG6 = 0x7FFFFFF6; // 31 IF Fine Cal Setup Register
//****** R E G 7 **************************************************
// const int32 REG7 = 0x000001F7; // 9 bits ; Readback Setup Register
const int32 READ_AFC = 0x00000107; // AFC Word
const int32 READ_FILCAL = 0x00000187; // Filter Cal
const int32 READ_SILREV = 0x000001C7; // Silicon Rev
const int32 READ_RSSI = 0x00000147; // RSSI
const int32 READ_BATT = 0x00000157; // Battery voltage
const int32 READ_TEMP = 0x00000167; // Temperature
const int32 READ_EXT = 0x00000177; // External PIN
//******************************************************************
const int32 REG8 = 0x00001238; // 16 Power-Down Test Register
const int32 REG9 = 0x1FFFFFF9; // 29 AGC Register
const int32 REG10 = 0xAABBCCDA; // 32 AFC Register
const int32 REG11 = 0xAABBCCDB; // 32 Sync Word Detect Register
const int32 REG12 = 0x0000123C; // 16 SWD/Threshold Setup Register
const int32 REG13 = 0x0355AACD; // 26 3FSK/4FSK Demod Register
const int32 REG14 = 0xAABBCCDE; // 32 Test DAC Register
const int32 REG15 = 0xAABBCCDF; // 32 Test Mode Register
// ***** Write and Read function ******
//------------------------------------------------------------------------------
// Write one register to the ADF7021
void ADF_Write(int32 value)
{ int8 lenght = 32;
output_low(sle);
output_low(sclk);
do {
#asm
BCF sdata_
BTFSC &(int8)value+3,7 // Skip if MSB (bit 31 of value) = 0
BSF sdata_
#endasm
output_high(sclk);
output_low(sclk);
value <<= 1;
}while(--lenght);
output_high(sle); // Data Latch
// output_low(sle); // This instruction must follow every ADF_Write function !
}
//------------------------------------------------------------------------------
// Read one register from the ADF7021
int16 ADF_Read(int32 value)
{ int16 result = 0; int8 temp = 16;
ADF_Write(value); // Send REG7 (readback option) to ADF7021
output_high(sclk);
output_low(sclk); // \__ The first read must be ignored
output_high(sclk); // /
do{
output_low(sclk);
result <<= 1;
if(input(sread) == 1) result |= 0x1;
output_high(sclk);
}while(--temp);
output_low(sle);
output_low(sclk);
return result;
}
// ********** Example of call (in main prog) **************
int16 rssi, temperature;
ADF_Write(REG0); // Write REG0 to ADF7021
output_low(sle); // Must be present after every Write function
rssi = ADF_Read(READ_RSSI);
temperature = ADF_Read(READ_TEMP);
|
My actual problem is understand how to subdivide bits concerning a specific function in one register and then send them contiguous (without misalignments).
Claudio |
|
|
piripic
Joined: 15 Jan 2008 Posts: 25
|
|
Posted: Wed May 21, 2008 12:07 am |
|
|
I know I have been unclear... but please... there is someone who could give a quick look at the ADF7021 datasheet (from page 47) and recommend how to manage the data of that sixteen registers in my PIC firmware ? Each register is 32 bits long and includes different values and flags. Many of these registers will be sent to adf7021 as fixed values while some, such as the divisor for the selection of operating frequencies, must change during the program (at run time). For each register is better to create as many as there are constant possible values (range for each data set) or it is better to create independent variables and then merge when sending to adf7021 respecting the alignment?
Thanks a lot
Claudio |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed May 21, 2008 12:41 am |
|
|
Look at the CCS CAN Bus drivers for an example. Look at the .h file
for an example of how to use bit fields in structures. This allows you
to organize the so it's in the same format as the hardware CAN registers
in the PIC. The .h file contains the structures:
Quote: |
c:\program files\picc\drivers\can-18xxx8.c
c:\program files\picc\drivers\can-18xxx8.h
|
|
|
|
piripic
Joined: 15 Jan 2008 Posts: 25
|
|
Posted: Wed May 21, 2008 7:08 am |
|
|
Thanks PCM programmer I tried but I do not think I can solve my problem that way; the compiler generates an error "Number of bits is out of range".
I can not use 8 bits (int8) variables because I have to send that bit contiguous. Its hard to manage that chip.
Code: |
#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock = 4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
union {
int32 all_bit;
/*
struct {
int32 address: 4;
int32 fractional_n: 15;
int32 integer_n: 8;
int32 tx_rx: 1;
int32 uart_mode: 1;
int32 mux_out: 3;
} reg0; */
struct {
int32 address: 4;
int32 r_counter: 3;
int32 ckout_div: 4;
int32 xtl_doubler: 1;
int32 osc_enab: 1;
int32 xtal_bias: 2;
int32 cp_current: 2;
int32 vco_enab: 1;
int32 rf_div_by2: 1;
int32 vco_bias: 4;
int32 vco_adj: 2;
int32 vco_induct: 1;
} reg1;
} myreg;
//======================================
void main()
{
/*
myreg.reg0.address = 0x0;
myreg.reg0.fractional_n = 0x7FFF;
myreg.reg0.integer_n = 0xFF;
myreg.reg0.tx_rx = 0x1;
myreg.reg0.uart_mode = 0x1;
myreg.reg0.mux_out = 0x7; */
myreg.reg1.address = 0x1;
myreg.reg1.r_counter = 0x7;
myreg.reg1.ckout_div = 0xF;
while(1);
}
|
Claudio |
|
|
piripic
Joined: 15 Jan 2008 Posts: 25
|
|
Posted: Thu May 22, 2008 12:16 am |
|
|
PCM programmer solution would seem the most logical but unfortunately in this case, the compiler does not handle non-aligned bit field (variables larger than 8 bits). Is really problematic as it seems to me or the solution is simple and I am not see ? How could I manage the various parameters including in the various 32 bits registers of ADF7021 ? Have I to use variables with dimension equal to every parameter and subsequently have I to use a function to merge, realign and send each register to ADF7021 ? Thanks for any information,
Claudio
P.S. my compiler version is 4.068 and I am working on PIC18F24K20 |
|
|
|