Hello,
MCU Arduino DUE. A 16bits AD7606 converter is connected in parallel to DUE, which is connected to Port C on DUE. I am trying to read the ADC conversion value from the C port in one command as efficiently as possible due to the time reduction. The read conversion value from AD is (example) uint32_t X= 0b00000000 00000011 11110011 11111100; Bits with log1 are valid conversion bits of the HW connection AD to port C on DUE).
It is necessary to delete bits C11,C10,C1,C0 from the uint32_t number X.
Using direct bit operations, I converted the value X to a 16-bit conversion value, which I need for further processing.
If I do the conversion step by step, the result is OK. However, if I do the conversion with one command, the result is not correct.
void setup() {
Serial.begin(460800);
Serial.println("Program started"); delay(200);
}
void loop() {
uint32_t X= 0b00000000000011111111001111111100;
uint32_t A, B, C, D, E, F;
Serial.print(F("X= ")); Serial.println(X, BIN);
// This part is OK.
A= (X >> 2) ; Serial.print(F("A= ")); Serial.println(A, BIN);
B= A & 0x3FC00; Serial.print(F("B= ")); Serial.println(B, BIN);
C= B>>2; Serial.print(F("C= ")); Serial.println(C, BIN);
D= ( (X >> 2) & 0xFF); Serial.print(F("D= ")); Serial.println(D, BIN);
E= C | D; Serial.print(F("E= ")); Serial.println(E, BIN); // RESULT IS OK..16 bit value of ADC conversion
// This part is incorrect
F= ( ((((X >> 2)) & 0x3FC0))>>2 ) | ((X >> 2) & 0xFF); Serial.print(F("F= ")); Serial.println(F, BIN); // RESULT IS NOT OK
Serial.println(F("============================="));
while(1);
}
Please advice where I make mistake?
Can anyone advise how to convert the value X as efficiently as possible in terms of conversion time to a 16-bit value (32-bit value) in a single conversion instruction using bitwise operations?
Thanks everyone for the answer. I appreciate your quick response.
I tested your suggestion uint16_t value = ((X >> 4) & 0xFF00) | ( (X >> 2) & 0xFF); and it is OK.
On the Arduino DUE port C, in addition to the pins that are set as inputs for the AD7606 conversion, there are also pins that are set as outputs.
I plan to use your solution to load all 8 channels of the ADC7606:
uint16_t Data[8];
for (uint8_t i = 0; i < 8; i = i + 1) {
Data[i] = ((PIOC->PIO_PDSR >> 4) & 0xFF00) | ( PIOC->PIO_PDSR >> 2) & 0xFF);
}
My question is, can I safely read the PIOC->PIO_PDSR register, which also contains the 16-bit ADC conversion value, if some pins on port C are set as inputs (pins other than the inputs to which the ADC conversion is stored)?
Is it possible to read PIOC->PIO_PDSR when there is a combination of inputs and outputs on port C without the risk of destroying the DUE?