Click here to Skip to main content
15,887,861 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
I am looking to implement the prototype for read_and_write, but couldn't get it right. Any help is appreciated. I am able to extract bits.

In this below code for write_val1, my intent is to write only the first 9 bits of final_val into read_data. The rest 7 bits of read_data should remain untouched. Expected output for write_val1 = 0x0080

Similarly for write_val2, my intent is to write only next 8 bits from final_val into read_data. The rest 8 bits of read_data should remain untouched. Expected output for write_val2 = 0x2700

Similarly for write_val3, my intent is to write only next 3 bits(010) from final_val into a position[11:13] of read_data leaving rest of read_data untouched.

Expected output = 0x5448 ; For example: pick 010 extracted bit from write_val3; 0x3048 = 0111 0000 0100 1000; 0x5048 = 0101 0000 0100 1000

C++
#include <stdio.h>
#include <stdint.h>

 // Extracts n bits from a given position in LSB. 
int bitExtracted(uint16_t read_data, uint8_t n_bits, uint8_t pos) 
{ 
    return (((1 << n_bits) - 1) & (read_data >> (pos - 1))); 
} 

void read_and_write(uint32_t* final_val, uint16_t* write_val, uint8_t start_pos, uint8_t end_pos)
{
    uint32_t temp = *final_val;
    *write_val = (uint16_t) ((temp >> start_pos) & ((1 << end_pos) - 1)); // store the desired number of bits in write_val
    *final_val = (temp >> end_pos); //shift final_val by end_pos since those bits are already written
    printf("\n temp %x, write_val %x, final_val %x ", temp, *write_val, *final_val);
    
}

void main() 
{
    uint16_t read_data = 0x0; //assume some read value
    uint16_t ext_val1 = bitExtracted(read_data, 9, 1);  //Read BITS [8:0] from read_data
    uint8_t ext_val2 = bitExtracted(read_data, 8, 1);   //Read BITS [7:0] from read_data
    uint8_t ext_val3 = bitExtracted(read_data, 3, 5);   //Read BITS [7:4] from read_data
    uint32_t final_val = 0x0; //Stores 20 extracted bits from val1, val2 and val3 into final_val (LSB to MSB in order)
    uint16_t write_val1, write_val2, write_val3;
    uint8_t start_pos = 0, end_pos =8;
    ext_val1 = 0x80, ext_val2 = 0x0, ext_val3 = 0x2;
    final_val = (ext_val1 | (ext_val2 << 9) | (ext_val3 << 17));
    printf ("\n final_val %x", final_val);
    
    //Read first 9 bits of final_val and write only into [8:0] position of existing read_data
    read_and_write(&final_val, &write_val1, 0, 9); 
    read_data = 0x80;
    write_val1 = write_val1 | read_data;
    
    //Read next 8 bits of final_val and write only into [7:0] position of existing read_data
    start_pos = 0;
    end_pos = 7;
    read_data = 0x27b7;
    read_and_write(&final_val, &write_val2, start_pos, end_pos);
    write_val2 = write_val2 | read_data;

    //Read next 3 bits of final_val and write only into[13:11] position of existing read_data
    start_pos = 11;
    end_pos = 13;
    read_data = 0x3048;
    read_and_write(&final_val, &write_val3, start_pos, end_pos);
    write_val3 = write_val3 | read_data;
    printf ("\n val1 0x%x val2 0x%x val3 0x%x final_val 0x%x", write_val1, write_val2, ext_val3, final_val);
}


What I have tried:

I am able to extract bits, and combine into one final_val. I am unable to modify registers in that specific start_pos and end_pos.
Posted
Updated 19-Sep-20 7:14am

Comments in code is a good habit, continue.

Quote:
0x3048 = 0111 0000 0100 1000

Since 0x3048 is 0011 0000 0100 1000 and 0111 0000 0100 1000 is 0x7048
your example is rather confuse.
Rewrite what you want to do with following notation:
Take a part of v1 as xxxx aaaa xxxx xxxx.
Take a part of v2 as xxxx xxxx bbbb xxxx.
Take a part of v3 as xxxx xxxx xxxx cccc.
and result is 0000 bbbb cccc aaaa.
the x are bits that do not matter.
When result depend on combinations of value like xor, build each part of xor to show what you want.
 
Share this answer
 
v3
Your code is confusing by using offsets and not starting with zero as first index. I think you have a bug in your code.

In the case of perfomance problems: I would use some constants or macros and avoid an (expensive) function calls.

tip: Write some test code to verify your function
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900