3

To configure UART tx, water mark (0 to 7) has to be written on memory mapped tx control register on bit position [18:16].

My RISC-V assembly function first reads the present control register value, perform a bitwise AND with mask to clear bits [18:16] and then OR with the shifted input value and write back.

Code below:

uart_set_txwmark:

    slli a0, 15;  /* shift input value by 15 */
    li t0, UART1_BASE;
    lw t1, UART_TXCTRL_OFFSET(t0); /* Read present value */

.equiv UART_MASK_WMARK, 0x0xFFF8FFFF /* [18:16] zero mask */

    li t2, UART_MASK_WMARK;   
    and t1, t1, t2;      /* clear/zero bits 18:16 */ 
    or t1, t1, a0;       /* OR with input value */
    sw t1, UART_TXCTRL_OFFSET(t0); /* Write back */

I am curious to know if there is any other better way of setting few bits in a memory mapped register in RISC-V.

RRON
  • 1,037
  • 3
  • 12
  • 32

1 Answers1

4

I am curious to know if there is any other better way of setting few bits in a memory mapped register in RISC-V.

Not really, I think you have the gist of it.


If you can use halfword reads/writes instead, that will happen to position the bits of interest at the low bit positions, so you can maybe do:

la t0, UART1_BASE
lhu t1, UART_TXCTRL_OFFSET+2(t0)  // fetch high order at offset +2
andi t1, t1, -8
or t1, t1, a0
sh t1, UART_TXCTRL_OFFSET+2(t0)
Erik Eidt
  • 23,049
  • 2
  • 29
  • 53