Endianess en STM32F4 salida FSMC

1

Actualmente estoy configurando un STM32F407 para evaluar un módulo de pantalla que utiliza un controlador de pantalla Renesas R61526A.

Pude configurar el proyecto utilizando CubeMX sin ningún problema, y el FSMC parece estar funcionando.

Sin embargo, noté que la palabra de datos de salida era big endian, pero estoy bastante seguro de que todos los STM32 son little endian (uint16_t 0x51ab como variable se convierte en 0xab51 cuando se monitorea la salida D0-16 con el alcance). No esperaba que la FSMC cambiara el orden de los bytes en la salida.

#define LCDADDRESS 0x63FFF00F
const LCDmemorymapping LCDRWregisteraccess = (uint16_t*) LCDADDRESS;
static void writetoLCD(uint16_t dataword)
{
    *LCDRWregisteraccess= (uint16_t) dataword;
}

static uint16_t readfromLCD(uint16_t unused)
{
    return  (uint16_t) *LCDRWregisteraccess;
}


/* FSMC initialization function */
static void MX_FSMC_Init(void)
{
  FSMC_NORSRAM_TimingTypeDef Timing;

  /** Perform the SRAM1 memory initialization sequence
  */
  hsram1.Instance = FSMC_NORSRAM_DEVICE;
  hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
  /* hsram1.Init */
  hsram1.Init.NSBank = FSMC_NORSRAM_BANK1;
  hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
  hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
  hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
  hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
  hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
  hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
  hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;
  hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;
  hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;
  hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;
  hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;
  hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
  hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE;
  /* Timing */
  Timing.AddressSetupTime = 3;
  Timing.AddressHoldTime = 15;
  Timing.DataSetupTime = 8;
  Timing.BusTurnAroundDuration = 3;
  Timing.CLKDivision = 16;
  Timing.DataLatency = 17;
  Timing.AccessMode = FSMC_ACCESS_MODE_A;
  /* ExtTiming */

  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

}

Me gustaría que la salida fuera también little-endian, ¿entonces estoy haciendo algo obviamente mal? La solución obvia sería leer / escribir los datos como

*LCDRWregisteraccess= (uint16_t)((0xff00&dataword)>>8)|(0x00ff&dataword<<8));

o simplemente para usar la instrucción REV16, pero me preguntaba si hay una configuración dentro del FSMC que falte o alguna otra cosa que esté haciendo mal.

También esta es mi primera pregunta de intercambio de pila, así que si no formulé la pregunta correctamente, no dude en señalarla :)

Muchas gracias de antemano!

    
pregunta user6796449

1 respuesta

2
  

Está escribiendo en una dirección impar (0x63FFF00F) utilizando 16 bits. Eso podría explicar el sorprendente resultado. - Codo

Codo estaba en lo correcto. El acceso a los bytes impares, mientras que el FSMC estaba configurado para las palabras de datos de 16 bits, hizo que tuviera doble acceso (2 operaciones de escritura) con los bytes exactamente en el orden incorrecto.

Mis direcciones son ahora:

#define LCD_CMD 0x60030000
#define LCD_DATA 0x60000000
    
respondido por el user6796449

Lea otras preguntas en las etiquetas