View previous topic :: View next topic |
Author |
Message |
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
function parameters & type checking & type definitio |
Posted: Tue Jun 09, 2009 1:42 pm |
|
|
I wanted to create a function that takes an int and a 4-bit-int but can't seem to do this.
My questions are:
Can I define a type that is 4 bits, say INT4, like the INT1 which is 1 bit?
Does the CCS compiler do size checking of types? ___ For example 0x1EF is too big for 4 bits.
Can this new type be used in a function?
Code: | //this works
int8 write_max(int8 fred, int1 f1)
{
fred++;
return fred;
}
|
Code: | //this doesn't work
int8 write_max(int8 fred, int4 f2)
{
fred++;
return fred;
}
|
Code: | //this doesn't work
int8 write_max(int8 fred, int f3:4)
{
fred++;
return fred;
}
|
Thanks in advance.
Leef_me |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 09, 2009 1:52 pm |
|
|
Quote: |
I wanted to create a function that takes an int and a 4-bit-int but can't
seem to do this. |
Tell us what your overall purpose is. Why do you believe you need
to do this ? |
|
|
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
|
Posted: Tue Jun 09, 2009 2:04 pm |
|
|
PCM programmer wrote: | Quote: |
I wanted to create a function that takes an int and a 4-bit-int but can't
seem to do this. |
Tell us what your overall purpose is. Why do you believe you need
to do this ? |
Maxim chip MAX5513 has SPI interface Quote: | http://datasheets.maxim-ic.com/en/ds/MAX5512-MAX5515.pdf |
The data format is 16 bits arranged as:
4 control bits, 8 data bits, 4 bits always 0.
I wanted one routine to send the command and regular code to specify the command and data to send.
I'm still working on options, I expect the command will end up being called based on flags in a timer interrupt.
Perhaps ENUM might be better: Update_chan1 or update_volume is better than 0x0e
Leef_me |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Tue Jun 09, 2009 2:43 pm |
|
|
I used that part before. I just send 2 bytes (16 bits total) by bringing chipselect low, calling the SPI_write() function twice and raise the chipselect line. Then you are done. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Jun 09, 2009 2:46 pm |
|
|
It would be easier to have function parameters (1 byte each) for the
data and control values. Then assemble the fields into the proper
bit locations with code in the function. Then transmit the bytes.
There is no 4-bit data type. You don't need one. Just use shifts,
AND'ing and OR'ing operations (as needed) to assemble the bits
in the proper positions. |
|
|
Ttelmah Guest
|
|
Posted: Tue Jun 09, 2009 2:52 pm |
|
|
You can generate an int4 field, with a typedef. However there is no saving over using an int8. If you want more than one, then a structure becomes worthwhile, and there can then be a space saving.
There is no basic type checking in the compiler. Instead there is automatic casting as types are transferred to types of different sizes. If (for instance), you generate an int4 type, and then put an int8 into it, the value will simply be truncated, with no complaint if it is too large.
Best Wishes |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Tue Jun 09, 2009 3:09 pm |
|
|
Here is a snippet of something I did a year ago with this part (actually I have the MAX5522 which is a two channel version but the code should be the same). It sort of shows what PCM Programmer was referring to:
Code: |
value_write_to_DAC = sensor_output; //sensor_output is the output of the PIC's 10 bit A/D so it is between 0 and 1023 inclusive.
dummy_var1 = value_write_to_DAC & 0b111111; //gets the LOWER 6 bits of value_write_to_DAC
dummy_var2 = ((0b1001) << 4); //0b1101 initializes the DAC and the left shift makes dummy_var2 part of first byte to be written to the DAC
upper_byte = (dummy_var2 | (value_write_to_DAC >>6 )); //upper byte to be written to DAC
lower_byte = (dummy_var1 << 2); //lower byte is lower 6 bits of value_write_to_DAC plus 2 extra zeros at the end
dummy_var3 = upper_byte << 8;
dig_value_to_DAC = (dummy_var3 | lower_byte);
output_low(MAX5522_CS);
spi_write(upper_byte);
spi_write(lower_byte);
output_high(MAX5522_CS);
|
|
|
|
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
|
Posted: Tue Jun 09, 2009 4:44 pm |
|
|
@PCM That's what I was trying to do, just with a 4 bit wide field
@mkuang thanks for the code, it helped me think things through.
I did notice something - - If the variable is 8 bits wide, I think something is wrong with the code
Code: | dummy_var3 = upper_byte << 8; |
@Ttelmah _ _ Thanks, definitely needed to know that.
Quote: | There is no basic type checking in the compiler........ |
Quote: | You can generate an int4 field, with a typedef. | Can you provide an example?
Leef_me |
|
|
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
|
Posted: Tue Jun 09, 2009 11:29 pm |
|
|
Thanks all. Here is my version. Hope this helps the next user.
Leef_me
Code: | enum DAC_cmd
{
none, load_vol, load_freq, update_both_DAC=8, load_vol_DAC,
load_freq_DAC, standby=0x0c, wakeup=0x0d, shutdown=0x0e
};
//==================================================================
// write to MAX5513 DAC
//==================================================================
// DAC 'A' connects to a signal controlling volume
// DAC 'B' connects to a signal controlling frequency
//==================================================================
void write_DACv2( DAC_cmd cmd, int8 data)
{
int8 buffer[2];
buffer[0]=data;
buffer[1]=cmd; // together the two bytes have 00CCDDDD
// 00 is value 0, CC is command, DDDD is 8 bit data
shift_left (buffer, 2, 0);
shift_left (buffer, 2, 0);
shift_left (buffer, 2, 0);
shift_left (buffer, 2, 0);
// together the two bytes now have CCDDDD00
output_low (SPI_CS); // register loading begins
delay_ms(10); // adjust delays as needed
spi_read(buffer[1]); // send 8 bit data to SPI, read data ignored
delay_ms(10);
spi_read(buffer[0]); // send 2nd 8 bit data to SPI, read data ignored
delay_ms(10);
output_high (SPI_CS); // command executed by DACs on rising edge
}
|
Last edited by Leef_me on Tue Jun 09, 2009 11:38 pm; edited 1 time in total |
|
|
Leef_me
Joined: 14 Mar 2006 Posts: 45
|
|
Posted: Tue Jun 09, 2009 11:31 pm |
|
|
@Ttelmah
Quote: | You can generate an int4 field, with a typedef. |
Can you provide an example?
Leef_me |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Wed Jun 10, 2009 9:18 am |
|
|
Leef_me wrote: | @PCM That's what I was trying to do, just with a 4 bit wide field
@mkuang thanks for the code, it helped me think things through.
I did notice something - - If the variable is 8 bits wide, I think something is wrong with the code
Code: | dummy_var3 = upper_byte << 8; |
|
Hi,
dummy_var3 is not being written to the DAC and has no relevance here. I call spi_write() twice writing first the upper_byte and then the lower_byte. Dummy_var3 was actually declared as an int16 (not shown in the code) and I was using it for some debug purposes later on. Sorry for the confusion. |
|
|
mkuang
Joined: 14 Dec 2007 Posts: 257
|
|
Posted: Wed Jun 10, 2009 9:22 am |
|
|
Leef_me wrote: | Thanks all. Here is my version. Hope this helps the next user.
Leef_me
Code: | enum DAC_cmd
{
none, load_vol, load_freq, update_both_DAC=8, load_vol_DAC,
load_freq_DAC, standby=0x0c, wakeup=0x0d, shutdown=0x0e
};
//==================================================================
// write to MAX5513 DAC
//==================================================================
// DAC 'A' connects to a signal controlling volume
// DAC 'B' connects to a signal controlling frequency
//==================================================================
void write_DACv2( DAC_cmd cmd, int8 data)
{
int8 buffer[2];
buffer[0]=data;
buffer[1]=cmd; // together the two bytes have 00CCDDDD
// 00 is value 0, CC is command, DDDD is 8 bit data
shift_left (buffer, 2, 0);
shift_left (buffer, 2, 0);
shift_left (buffer, 2, 0);
shift_left (buffer, 2, 0);
// together the two bytes now have CCDDDD00
output_low (SPI_CS); // register loading begins
delay_ms(10); // adjust delays as needed
spi_read(buffer[1]); // send 8 bit data to SPI, read data ignored
delay_ms(10);
spi_read(buffer[0]); // send 2nd 8 bit data to SPI, read data ignored
delay_ms(10);
output_high (SPI_CS); // command executed by DACs on rising edge
}
|
|
You don't need the delay_ms(10). I think the time between instructions is enough for the DAC. |
|
|
Ttelmah Guest
|
|
Posted: Wed Jun 10, 2009 2:47 pm |
|
|
As I said, there is no gain for a single 4bit value. However:
Code: |
struct nibbles {
int lsn:4;
int msn:4;
};
typedef struct nibbles int4;
//Then declare variable with:
int4 val;
//Access low int4 value with:
val.lsn = 8;
//or high with msn.
|
The compiler will automatically clip values fed into the nibbles, masking them as required.
Best Wishes |
|
|
|