Hi!
I am using an SPI (Serial Peripheral Interface)protocol.
The package is 32 bit length. For send data I have to write to a 16 bit register for two time.
So I write consequentially the same register for two time.
I am driving a DAC (Digital-to-analog converter), the format of the package is:
'xxxxxxxxxxxxYYYYYYYYYYYYYYYYxxxx'
So this package is splitted in two, the 16 bit registers format are:
'xxxxxxxxxxxxYYYY' 'YYYYYYYYYYYYxxxx'
where the 'x' mean command/control bit and the 'Y' mean the output value of the DAC: all 0 mean 0V and all 1 mean 5V.
I would like a smart way to change the 'Y' bit only, for change directly the output voltage. Do you have something in mind?
To make sure I unserstand well, you want for example doing things like change this number:
%10010011000100000000000000001010 into %10010011000111111111111111111010 ?
If so, you want in fact to set contiguous bits to 0 or 1. These function do it:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
int bitrange(size_t start, size_t len)
{
return ((1 << len) - 1) << start;
}
int set0(int val, size_t start, size_t len)
{
return val & ~bitrange(start, len);
}
int set1(int val, size_t start, size_t len)
{
return val | bitrange(start, len);
}
start and len delilmit the range so set0(%101110101, 2, 4) => %101000001 and set1(%101110101, 2, 4) => %101111101.
Choose start and len as needed for your problem
Hi! I will explain better, I have to send 2 package of 16 bits to the SPI send register.
these two register format are:
'xxxxxxxxZZZZYYYY' ----> 1st package
'YYYYYYYYYYYYxxxx' ----> 2nd package
The Y bits are the 16 bit of the voltage value of the DAC.
The Z bits are the 16 bit of the channel value of the DAC.
The x bits are bit that I don't have to change.
I have written a function that changes only the Y and Z bits:
Uint16 voltage = 0xFFFF; // value of voltage to the DAC
Uint16 voltage_high; // value splitted and shifted to send in the first part of the SPI package
Uint16 voltage_low; // value splitted and shifted to send in the second part of the SPI package
Uint16 channel = 0x0; // value of channel to the DAC
Uint16 channel_shifted; // value splitted to send in the first part of the SPI package
Uint16 send_high; // first part of the SPI package
Uint16 send_low; // second part of the SPI package
Uint16 mask_voltage_high= 0xFFF0; // mask voltage high
Uint16 mask_voltage_low = 0x000F; // mask voltage low
Uint16 mask_channel = 0xFF0F; // mask channel
void send_DAC_SPI(Uint16 voltage, Uint16 channel){
// update voltage to send to DAC with SPI
voltage_high = voltage >> 12;
voltage_low = voltage << 4;
send_high = send_high & mask_voltage_high;
send_high = send_high | voltage_high;
send_low = send_low & mask_voltage_low;
send_low = send_low | voltage_low;
// update channel to send to DAC with SPI
channel_shifted = channel << 4;
send_high = send_high & mask_channel;
send_high = send_high | channel_shifted;
}
I hope that this use of mask could be useful for you!