cancel
Showing results for 
Search instead for 
Did you mean: 

FSMC, getting confused...

GregMusic
Associate II
Posted on June 12, 2015 at 19:08

So I have an STM32 F103ZET. We use a UC1701 controller to drive a small LCD. 

It's attached to FSMC Bank1, 2nd section, using an 8bit wide bus. 

I've been able to write control data using the address 0x64000000 to directly write to memory, but I am unable to figure out how to get the register select pin to toggle so that I can write data out.

Mu understanding was that FSMC_BANK1_R_BASE (0xA0000000) is where I would write control data to, and that I would use the other address to send data. I've been trying various different combinations but haven't had any success yet. With a scope we've seen the C/D pin toggling.

My assumption was that the STM32 chip set the pin high or low depending on the address being written to. The documentation is a little thin on the ground.

Apologies if this sounds a little incoherent. I'm using STM32Cube v1.0 to set up my peripherals. 

This is how I am writing control data:

typedef struct

{

  volatile uint8_t LCD_REG;

  volatile uint8_t LCD_RAM;

} LCD_TypeDef;

void WriteReg(uint8_t reg, uint8_t byte = 0)

{

    LCD_TypeDef *lcd = (LCD_TypeDef *)(FSMC_BASE|0x04000000);

    lcd->LCD_REG = reg;

    lcd->LCD_RAM = byte;

}

#stm32 #fsmc
5 REPLIES 5
Posted on June 12, 2015 at 19:19

> but I am unable to figure out how to get the register select pin to toggle

Where is it connected?

JW

GregMusic
Associate II
Posted on June 12, 2015 at 19:30

PF0, (FSMC_A0)

The register select in cube is set to A0 too. 

From my hal_msp:

  /** FSMC GPIO Configuration  

  PF0   ------> FSMC_A0

  PE7   ------> FSMC_D4

  PE8   ------> FSMC_D5

  PE9   ------> FSMC_D6

  PE10   ------> FSMC_D7

  PD14   ------> FSMC_D0

  PD15   ------> FSMC_D1

  PD0   ------> FSMC_D2

  PD1   ------> FSMC_D3

  PD4   ------> FSMC_NOE

  PD5   ------> FSMC_NWE

  PG9   ------> FSMC_NE2

  */

and my FSMC_Init:

  hsram1.Instance = FSMC_NORSRAM_DEVICE;

  hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;

  /* hsram1.Init */

  hsram1.Init.NSBank = FSMC_NORSRAM_BANK2;

  hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;

  hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;

  hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_8;

  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;

  /* Timing */

  Timing.AddressSetupTime = 15;

  Timing.AddressHoldTime = 15;

  Timing.DataSetupTime = 255;

  Timing.BusTurnAroundDuration = 15;

  Timing.CLKDivision = 16;

  Timing.DataLatency = 17;

  Timing.AccessMode = FSMC_ACCESS_MODE_A;

  /* ExtTiming */

  HAL_SRAM_Init(&hsram1, &Timing, NULL);

Hamid.Wasti
Associate III
Posted on June 12, 2015 at 20:14

typedef struct

 

> {

 

>   volatile uint8_t LCD_REG;

 

>   volatile uint8_t LCD_RAM;

 

> } LCD_TypeDef;

 

Are you sure your compiler is setup to allow packed structures? In order to optimize perforormance, some compilers will place each element of a structure at 4 byte boundaries, regardless of the size of the element. In that case, LCD_REG will be located at 0 and LCD_RAM will be located at address 4.

> void WriteReg(uint8_t reg, uint8_t byte = 0)

 

> {

 

>     LCD_TypeDef *lcd = (LCD_TypeDef *)(FSMC_BASE|0x04000000);

 

>     lcd->LCD_REG = reg;

 

>     lcd->LCD_RAM = byte;

 

> }

 

Are you sure you want to write a byte to LCD_RAM every time you go to write a byte to LCD_REG?

A better approach may be to have a WriteREG() and a WriteRAM() function, each with a pointer to the correct address and each writing to the appropriate place.

Finally, many people here have absolutely no confidence in the Cube software.  If it starts looking like the problem is coming from the initialization, you will have much fewer individuals able to help.

GregMusic
Associate II
Posted on June 13, 2015 at 01:40

Yeah, you raise a good point actually. I'm using gcc with no optimisations enabled, so there's a good chance it's padding the struct.

I did play with it as the original example I saw that used this method had uint16_t's in there, but using larger data types results in slightly different behaviours.

It stil doesn't really explain how I am supposed to get the STM chip to switch the data pin to high, I'm still under the impression this should be done automatically. 

Also is  FSMC_BANK1_R_BASE used to change the internal FSMC settings, or is it intended to send control data? 

Interesting to hear about cube, I know there's the odd defect in it, I made the decision to move to a cube based configuration from an older version of the sdk which was a bit hacky. 

Hamid.Wasti
Associate III
Posted on June 14, 2015 at 19:15

> It stil doesn't really explain how I am supposed to get the STM chip to switch the data pin to high

If you connect A0 output to the command/data input and set up the FSMC in 8 bit mode, then writing to an even address in the FSMC range will result in a write with A0 low and writing to an odd address will result in a write with A0 high.