2015-06-12 10:08 AM
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 #fsmc2015-06-12 10:19 AM
> but I am unable to figure out how to get the register select pin to toggle
Where is it connected? JW2015-06-12 10:30 AM
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);2015-06-12 11:14 AM
>
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.
2015-06-12 04:40 PM
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.2015-06-14 10:15 AM
> 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.