Estou usando arm gcc (CooCox) para programar uma descoberta STM32F4, e estou lutando com um problema endian
Estou amostrando com um ADC de 24 bits via SPI. Como três bytes estão chegando, primeiro o MSB teve a idéia de carregá-los em uma união para torná-los (eu esperava!) Um pouco mais fácil de usar.
typedef union
{
int32_t spilong;
uint8_t spibytes [4];
uint16_t spihalfwords [2];} spidata;
spidata analogin0;
Carrego os dados usando leituras spi em analogin0.spibytes [0] - [2], com [0] como MSB, depois os cuspo via USART em um megabaud, 8 bits por vez. Sem problemas.
Os problemas começaram quando tentei passar os dados para um DAC de 12 bits. Esse DAC SPI deseja palavras de 16 bits, que consistem em um prefixo de 4 bits começando no MSB, seguido por 12 bits de dados.
As tentativas iniciais foram converter o complemento duplo que o ADC me deu para compensar o binário, xor-analogog0.spihalfwords [0] com 0x8000, deslocando o resultado para os 12 bits inferiores e adicionando o prefixo aritmeticamente.
Incrivelmente frustrante, até eu notar que para analogin0.spibytes [0] = 0xFF e analogin0.spibytes [1] = 0xB5, analogin0.halfwords [0] era igual a 0xB5FF e não 0xFFB5 !!!!!
Depois de perceber isso, parei de usar operações aritméticas e a meia palavra e permaneci na lógica bit a bit e nos 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)
... e isso funcionou bem. Quando eu espio temp após a primeira linha do código, é 0xFFB5, e não 0xB5FF, então tudo está bem
Então, para perguntas ...
O córtex é novo para mim. Não me lembro da PIC de troca de bytes em int16, embora ambas as plataformas sejam pouco endian. Isso está correto?
Existe uma maneira mais elegante de lidar com isso? Seria ótimo se eu pudesse colocar o ARM7 no modo big endian. Estou vendo muitas referências ao Cortex M4 sendo bi-endiano, mas todas as fontes parecem não me dizer como . Mais especificamente, como coloco o STM32f407 no modo big-endian , ainda melhor se isso puder ser feito no gcc. É APENAS uma questão de definir o bit apropriado no registro do AIRCR? Existem ramificações, como a necessidade de definir o compilador para corresponder ou erros matemáticos mais tarde com bibliotecas inconsistentes?