# Endianess on STM32F4 FSMC output

I'm currently setting up a STM32F407 to evaluate a display module which utilizes a Renesas R61526A Displaycontroller.

I was able to set up the project using CubeMX no problem, and the FSMC seems to be working.

However I noticed that the output data word was big endian, yet im pretty sure all STM32 are little endian (uint16_t 0x51ab as variable becomes 0xab51 when monitoring D0-16 output with the scope). I did not expect the FSMC to change the byte order on the output.

#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.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.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__);
}

}


I would like the output to be little-endian as well, so am I doing something obviously wrong ? The obvious solution would be to read/write the data as

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


or to just use the REV16 instruction but I was wondering whether there is a configuration within the FSMC that I'm missing or something else I'm doing wrong.

Also this is my first stack exchange question, so if I didn't formulate the question correctly, please feel free to point it out :)

Many thanks in advance!

• It is unclear what you are asking here. What did you expect to have happen and how is the actual behavior deviating from that expectation? For example, did the MSB of the data show up on the D15 line, or D0 line? – pgvoorhees Nov 7 '17 at 16:29
• I expected the output to have the same bit & byte endianess as the variable ( due to the STM32 being little-endian I expected the output to be same). In regards to your question the MSB was represented on the D7 line. The LSB on the D8 an so forth. The simple fix would be to use the REV16 instruction but I was curious why the system behaves that way. I will try to clarify the question, Thanks. – user6796449 Nov 7 '17 at 16:45
• So, to be perfectly clear, you are seeing the MSB on the D0 line. – pgvoorhees Nov 7 '17 at 17:00
• No, the MSB can be seen on the D7 line. If the data to be put out of the bus would be 0xC000 it is visible as 0x00C0 on the bus. The upper and the lower byte are switched. Bit order within the actual bytes is not affected. – user6796449 Nov 7 '17 at 17:11
• You are writing to an odd address (0x63FFF00F) using 16 bits. That might explain the surprising result. – Codo Nov 7 '17 at 18:47

You are writing to an odd address (0x63FFF00F) using 16 bits. That might explain the surprising result. – Codo

Codo was correct. Accessing odd bytes while the FSMC was configured for 16bit datawords made it do a double access ( 2 write operations) with the bytes in exactly the wrong order.

My adresses are now:

#define LCD_CMD 0x60030000
#define LCD_DATA 0x60000000