If you refuse to abstract or change
usart_error then consider using whitespace to take mercy on my eyes.
if ( usart_error.CRCError
This is reminiscent of Haskell style. It's best to avoid the need for this in the first place but this has the advantage of making the logical operation between each line noticeable at a glance, it's easy to confirm that
usart_error is used throughout, and each error property is presented in vertical list form.
Now sure, it eats up lines of code but I find fluffy code more digestible then compacted code. Sparse over dense, as the Agile Manifesto says.
This form is compatible with those living under the tyranny of tabs. There are other alignments.
If you were willing to abstract it (please do) behind a good descriptive name (please please do) the complexity is still likely to show up somewhere else, sticking you with nearly the same problem. In those cases I use something like this:
It is worth taking a moment to ask yourself if a design decision isn't forcing you to write code this complex. If this can be broken down or avoided in someway it's worth your time to find a simpler way to handle this problem. At first glance I wonder if there isn't a type hierarchy hiding in this code.
But if you're going to do it this way, please make it easy on the eyes.