Estoy usando arm gcc (CooCox) para programar un descubrimiento STM32F4, y he estado luchando con un problema endian
Estoy muestreando con un ADC de 24 bits a través de SPI. Como están llegando tres bytes, MSB primero tuve la idea de cargarlos en una unión para hacerlos (¡esperaba, de todos modos!) Un poco más fáciles de usar.
typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;
Cargo los datos usando lecturas spi en analogin0.spibytes [0] - [2], con [0] como MSB, luego los escupo a través de USART a megabaudios, 8 bits a la vez. No hay problemas.
Los problemas comenzaron cuando intenté pasar los datos a un DAC de 12 bits. Este SPI DAC quiere palabras de 16 bits, que consisten en un prefijo de 4 bits que comienza en el MSB, seguido de 12 bits de datos.
Los intentos iniciales consistieron en convertir los dos complementos que el ADC me dio para compensar el binario, al xoringar analogin0.spihalfwords [0] con 0x8000, desplazar el resultado a los 12 bits inferiores y luego agregar el prefijo en forma aritmética.
Increíblemente frustrante, hasta que me doy cuenta de que analogin0.spibytes [0] = 0xFF y analogin0.spibytes [1] = 0xB5, analogin0.halfwords [0] era igual a 0xB5FF y no 0xFFB5 !!!!!
Después de notar esto, dejé de usar operaciones aritméticas y la media palabra, y me quedé con la lógica bit a bit y los bytes
uint16_t temp=0;
.
.
.
// work on top 16 bits
temp= (uint16_t)(analogin0.spibytes[0])<<8|(uint16_t)(analogin0.spibytes[1]);
temp=temp^0x8000; // convert twos complement to offset binary
temp=(temp>>4) | 0x3000; // shift and prepend with bits to send top 12 bits to DAC A
SPI_I2S_SendData(SPI3,temp); //send to DACa (16 bit SPI words)
... y esto funcionó bien. Cuando miro la temperatura después de la primera línea de código, es 0xFFB5 y no 0xB5FF, así que todo está bien
Entonces, para preguntas ...
Cortex es nuevo para mí. No recuerdo el intercambio de bytes de PIC en int16, a pesar de que ambas plataformas son poco endian. ¿Es esto correcto?
¿Hay alguna forma más elegante de manejar esto? Sería genial si pudiera poner el ARM7 en modo big-endian. Veo muchas referencias de que Cortex M4 es bi-endian, pero todas las fuentes parecen detenerse antes de decirme cómo . Más específicamente, ¿cómo coloco el STM32f407 en modo big-endian , aún mejor si se puede hacer en gcc. ¿Es SOLO una cuestión de establecer el bit apropiado en el registro AIRCR? ¿Hay alguna ramificación, como tener que configurar el compilador para que coincida, o problemas matemáticos más tarde con bibliotecas inconsistentes?