Actualmente estoy configurando un STM32F407 para evaluar un módulo de pantalla que utiliza un controlador de pantalla Renesas R61526A.
Pude configurar el proyecto usando CubeMX sin problemas, 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 osciloscopio). 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 también fuera 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 usar la instrucción REV16, pero me preguntaba si hay una configuración dentro del FSMC que me falta o si estoy haciendo algo mal.
Además, esta es mi primera pregunta de intercambio de pila, por lo que si no formulé la pregunta correctamente, no dude en señalarlo :)
¡Muchas gracias de antemano!
Está escribiendo en una dirección impar (0x63FFF00F) usando 16 bits. Eso podría explicar el sorprendente resultado. – Code
Codo estaba en lo cierto. Acceder a bytes impares mientras la FSMC estaba configurada para palabras de datos de 16 bits hizo que hiciera un doble acceso (2 operaciones de escritura) con los bytes exactamente en el orden incorrecto.
Mis direcciones ahora son:
#define LCD_CMD 0x60030000
#define LCD_DATA 0x60000000
pgvoorhees
usuario6796449
pgvoorhees
usuario6796449
codo
pgvoorhees