Hardware and firmware are encapsulated to the programmer. OK, you could think that this is not TRUE programming, but remember digital circuits: you are not seeing all those C-MOS transistors that make all those gates that make all those latches and flip-flops.
The world is full of encapsulation.
Firmware should be written in C of course. Assembly might be used to, but in small bits. Not because I don´t like Assembly, because it is not readable, it is not easy to handle and maintain. Truth to be told, I mostly read the comments when I need to check out Assembly code rather than the code it self.
Suppose you write a program that reads temperature, pressure, and needs to generate an output for a electronic injection systems. In this case, using C is much better because all the code rely on low level.