Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading in 16 bits from a 32 bit register

I'm trying to read certain values from a particular register. The manual specifies that I must access the 16-bit LSB access first and 16-bit MSB access next. Do I just read in all 32 bits at once and then mask the remaining 16 msb/lsb respectively as needed? Or would there be a way to read only 16 bits fist.

Thanks, Neco

like image 252
Falcata Avatar asked Mar 27 '12 19:03

Falcata


People also ask

How could I get the high order 16 bits of a 32-bit register?

There isn't one. The upper 16-bit of a 32-bit register don't have a corresponding register. Shift to lower bits, modify, then return to higher. Lower bits are accessible as 16/8 bit value to have 16 and 8 bit registers, and higher part is only extension to 32 bits.

How do you read 16-bit register?

A 16-bit I/O read is normally done like this: Cycle 1: in r16, TCNT1L ;Reading low byte into r16,this triggers the high ; byte to be latched in the temporary shadow ; register. Cycle 2: in r17, TCNT1H ;Reading high byte from the temporary register. Note: 1.

Is it possible to access 32-bit data using 16-bit port?

Yes, this is possible if the processor and memory system support physical addresses larger than 32 bits.

How many bits is 16 registers?

A 16-bit register can store 216 different values. The range of integer values that can be stored in 16 bits depends on the integer representation used.


2 Answers

If the manual says to first access the 16-bit LSB and then the 16-bit MSB, do as the manual says.

For example (little endian):

#define REG (*(volatile uint32_t *) 0x1234)

uint16_t val_hi, val_lo;

val_lo = *((volatile uint16_t *) &REG);
val_hi = *((volatile uint16_t *) &REG + 1);

Note that compilers also sometimes provide HI and LO identifiers to access LSB or MSB, like in addition to REG in the example:

#define REGL (*(volatile uint16_t *) 0x1234)
#define REGH (*(volatile uint16_t *) 0x1236)
like image 146
ouah Avatar answered Nov 01 '22 04:11

ouah


It's unclear what language you are using to do this. I will assume you are using inline assembly in C.

I am most familiar with NASM. Using NASM syntax for i386:

mov eax, 0x12345678 ; load whatever value
mov bx, ax          ; put LSW in bx
shr eax, 16         ; shift MSW to ax
                    ; now ax = MSW, bx = LSW

I'm guessing the gas (C) code would be something like this:

movl $0x12345678, %eax # load whatever value
movw %ax, %bx          # put LSW in bx
shrl $16, %eax         # shift MSW to ax
                       # now ax = MSW, bx = LSW
like image 2
Kendall Frey Avatar answered Nov 01 '22 04:11

Kendall Frey