Passing a variable to a function within another function
Casting a reference to an integer is like casting a pointer to an integer, which gives you the address and not the value inside casted, except it is not allowed and you need to go through a raw pointer explicitly. This doesn't require unsafe (led as *const LedRegister as u8), but this also doesn't do what you want.
The correct solution is to implement Copy for your enum. You should always implement Copy for simple enums, unless there is a strong reason not to. Taking references to the value is not in any way better than copying it: it is slower, requiring dereferences and storing in the stack instead of potentially in registers, and it complicates the source code for no reason.

I am learning Rust. I am working on an embedded Rust project to interface with an I2C LED driver.
I have defined a pub enum LedRegister that defines all of the I2C registers used to control each LED. These register definitions are always one byte, they set by the chip's datasheet, and they will never change. However, I like having them in an enum, because it allows me to create a function that will only accept LedRegisters as inputs.
pub enum LedRegister {
    // 0-255 PWM value. 255 = max LED brightness.
    CpuStatusR    = 0x03,
    CpuStatusG    = 0x02,
    CpuStatusB    = 0x01,
    Ch1Cor        = 0x04,
    Ch1Ptt        = 0x06,
    Ch1SpareR     = 0x05,
    Ch1StatusR    = 0x0C,
    Ch1StatusG    = 0x0B,
    Ch1StatusB    = 0x0A,
    Ch2Cor        = 0x07,
    Ch2Ptt        = 0x09,
    Ch2SpareR     = 0x08,
    Ch2StatusR    = 0x0E,
    Ch2StatusG    = 0x0D,
    Ch2StatusB    = 0x0F,
    SpareLedR     = 0x12,
    SpareLedG     = 0x11,
    SpareLedB     = 0x10,
}

In the same scope, I have a pub fn enable_led to toggle each LED on or off:
pub fn enable_led(i2c: &mut I2c, led: LedRegister, state: bool) -> Result<(), Box<dyn Error>> {
    if state {
        i2c.write(&[led as u8, 0xFF])?;
    } else {
        i2c.write(&[led as u8, 0x00])?;
    }

    i2c.write(&[ControlRegister::Update as u8, 0x00])?;

    Ok(())
}

From main, I can call this function and see that my LED turns on:
led_driver::enable_led(&mut i2c, led_driver::LedRegister::SpareLedG, true);
I would like to write another function that allows me to blink the LED by calling enable_led multiple times with a delay in between:
pub fn blink_led(i2c: &mut I2c, led: LedRegister, duration_ms: u64) -> Result<(), Box<dyn Error>> {
    enable_led(i2c, led, true);
    // add a delay
    enable_led(i2c, led, false);
    // add a delay

    Ok(())
}

Here, Rust complains because the value of 'led' has moved into the first call of enable_led. I understand that there can only be one owner of the value - so I get why Rust is complaining.
I have attempted to 'borrow' the value of LedRegister:
pub fn enable_led(i2c: &mut I2c, led: &LedRegister, state: bool) -> Result<(), Box<dyn Error>> {
    if state {
        i2c.write(&[led as u8, 0xFF])?;
    } else {
        i2c.write(&[led as u8, 0x00])?;
    }

    i2c.write(&[ControlRegister::Update as u8, 0x00])?;

    Ok(())
}

led_driver::enable_led(&mut i2c, &led_driver::LedRegister::SpareLedG, true);


This gives me E0606 and a suggestion to implement casting through a raw pointer and unsafe blocks, which seems needlessly complicated for this use case.
I have also considered implementing copy on my LedRegister, so I can make copies of the initial reference before calling led_enable() with the same LED. This compiles, but it also seems more difficult than it should be. I don't think I actually need multiple copies of my register definition byte in RAM. Is this actually necessary?
I get the feeling that I'm not using the right features of Rust for this task. I am not strongly tied to using an enum here if that is the wrong tool for the job. However, I do want to limit the inputs to enable_led and blink_led so they only accept valid LEDs.
What is the best approach to accomplish my objective here in Rust?
