It is tricky, and not that simple. Here is how I understand it. You cannot just set the address the moment you receive it. The device needs to respond to the "set address" command using the same address used to send the message. This smells like a race, and the device always wins if the new address is sent as soon as the message is received.
The device needs to wait until the "Data IN" phase of the transaction. Here we are talking about the USB stuff we thought we didn't need to talk about. But ignore the terminology for now, the thing to do is as follows. Hold on to that address for a while. In fact, send a ZLP (zero length packet) and when you see the CTR packet for that transmission, then set the address!
What I see in my linux logs when I set the address immediately is:
device not accepting address 14, error -32If I just comment out the setting of the address in the DADDR register, this error goes away. Linux apparently gets the ACK and is convinced that you properly received the address.
Tom's Computer Info / tom@mmto.org