2019-05-02 01:13 AM
Hello.
I have Init FMC, but when I try write on it, it doesn´t work.
And I have a problem, data is send double, and timing is wrong. I think I have problem with init. Can anybody help me with init this pheripheral?
And my test write function is here:
#define BANK_ADDR ((uint32_t)0x64000000)
#define FMCWRITE(uAdr,ucVal)\
*(__IO uint16_t *) (BANK_ADDR + (uAdr))=(ucVal)
Init function is here:
void initFMC(void)
{
FMC_pins();
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_FMC);
FMC_NORSRAM_InitTypeDef Init;
FMC_NORSRAM_TimingTypeDef Timing;
FMC_NORSRAM_TypeDef *Instance;
FMC_NORSRAM_EXTENDED_TypeDef *Extended;
Instance = FMC_NORSRAM_DEVICE;
Extended = FMC_NORSRAM_EXTENDED_DEVICE;
Init.NSBank = FMC_NORSRAM_BANK2;
Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_ENABLE;
Init.MemoryType = FMC_MEMORY_TYPE_PSRAM;
Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
Init.WrapMode = FMC_WRAP_MODE_DISABLE;
Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;
Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
/* Timing */
//Timint 168Mhz = 6ns
Timing.AddressSetupTime = 11;
Timing.AddressHoldTime = 2;
Timing.DataSetupTime = 16;
Timing.BusTurnAroundDuration = 6;
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FMC_ACCESS_MODE_A;
FMC_NORSRAM_Init(Instance, &Init);
FMC_NORSRAM_Timing_Init(Instance, &Timing, Init.NSBank);
FMC_NORSRAM_Extended_Timing_Init(Extended, NULL, Init.NSBank, Init.ExtendedMode);
__FMC_NORSRAM_ENABLE(Instance, Init.NSBank);
}
Other function:
ErrorStatus FMC_NORSRAM_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_InitTypeDef* Init) {
uint32_t tmpr = 0U;
/* Get the BTCR register value */
tmpr = Device->BTCR[Init->NSBank];
/* Clear MBKEN, MUXEN, MTYP, MWID, FACCEN, BURSTEN, WAITPOL, WRAPMOD, WAITCFG, WREN,
WAITEN, EXTMOD, ASYNCWAIT, CPSIZE, CBURSTRW and CCLKEN bits */
tmpr &= ((uint32_t)~(FMC_BCR1_MBKEN | FMC_BCR1_MUXEN | FMC_BCR1_MTYP | \
FMC_BCR1_MWID | FMC_BCR1_FACCEN | FMC_BCR1_BURSTEN | \
FMC_BCR1_WAITPOL | FMC_BCR1_WRAPMOD | FMC_BCR1_WAITCFG | \
FMC_BCR1_WREN | FMC_BCR1_WAITEN | FMC_BCR1_EXTMOD | \
FMC_BCR1_ASYNCWAIT | FMC_BCR1_CPSIZE | FMC_BCR1_CBURSTRW | \
FMC_BCR1_CCLKEN));
/* Set NORSRAM device control parameters */
tmpr |= (uint32_t)(Init->DataAddressMux |\
Init->MemoryType |\
Init->MemoryDataWidth |\
Init->BurstAccessMode |\
Init->WaitSignalPolarity |\
Init->WrapMode |\
Init->WaitSignalActive |\
Init->WriteOperation |\
Init->WaitSignal |\
Init->ExtendedMode |\
Init->AsynchronousWait |\
Init->PageSize |\
Init->WriteBurst |\
Init->ContinuousClock);
if (Init->MemoryType == FMC_MEMORY_TYPE_NOR) {
tmpr |= (uint32_t) FMC_NORSRAM_FLASH_ACCESS_ENABLE;
}
Device->BTCR[Init->NSBank] = tmpr;
/* Configure synchronous mode when Continuous clock is enabled for bank2..4 */
if ((Init->ContinuousClock == FMC_CONTINUOUS_CLOCK_SYNC_ASYNC) && (Init->NSBank != FMC_NORSRAM_BANK1)) {
Device->BTCR[FMC_NORSRAM_BANK1] |= (uint32_t) (Init->ContinuousClock);
}
return 0;
}
ErrorStatus FMC_NORSRAM_DeInit(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_EXTENDED_TypeDef *ExDevice, uint32_t Bank) {
/* Disable the FMC_NORSRAM device */
__FMC_NORSRAM_DISABLE(Device, Bank);
/* De-initialize the FMC_NORSRAM device */
/* FMC_NORSRAM_BANK1 */
if (Bank == FMC_NORSRAM_BANK1) {
Device->BTCR[Bank] = 0x000030DB;
}
/* FMC_NORSRAM_BANK2, FMC_NORSRAM_BANK3 or FMC_NORSRAM_BANK4 */
else {
Device->BTCR[Bank] = 0x000030D2;
}
Device->BTCR[Bank + 1] = 0x0FFFFFFF;
ExDevice->BWTR[Bank] = 0x0FFFFFFF;
return 0;
}
ErrorStatus FMC_NORSRAM_Timing_Init(FMC_NORSRAM_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank) {
uint32_t tmpr = 0U;
/* Get the BTCR register value */
tmpr = Device->BTCR[Bank + 1U];
/* Clear ADDSET, ADDHLD, DATAST, BUSTURN, CLKDIV, DATLAT and ACCMOD bits */
tmpr &= ((uint32_t) ~(FMC_BTR1_ADDSET | FMC_BTR1_ADDHLD | FMC_BTR1_DATAST |
FMC_BTR1_BUSTURN | FMC_BTR1_CLKDIV | FMC_BTR1_DATLAT |
FMC_BTR1_ACCMOD));
/* Set FMC_NORSRAM device timing parameters */
tmpr |= (uint32_t) (Timing->AddressSetupTime |\
((Timing->AddressHoldTime) << 4U) |\
((Timing->DataSetupTime) << 8U) |\
((Timing->BusTurnAroundDuration) << 16U) |\
(((Timing->CLKDivision) - 1U) << 20U) |\
(((Timing->DataLatency) - 2U) << 24U) |\
(Timing->AccessMode));
Device->BTCR[Bank + 1U] = tmpr;
/* Configure Clock division value (in NORSRAM bank 1) when continuous clock is enabled */
if (FMC_IS_BIT_SET(Device->BTCR[FMC_NORSRAM_BANK1], FMC_BCR1_CCLKEN)) {
tmpr = (uint32_t) (Device->BTCR[FMC_NORSRAM_BANK1 + 1U] & ~(0x0FU << 20U));
tmpr |= (uint32_t) (((Timing->CLKDivision) - 1U) << 20U);
Device->BTCR[FMC_NORSRAM_BANK1 + 1U] = tmpr;
}
return 0;
}
ErrorStatus FMC_NORSRAM_Extended_Timing_Init(FMC_NORSRAM_EXTENDED_TypeDef *Device, FMC_NORSRAM_TimingTypeDef *Timing, uint32_t Bank, uint32_t ExtendedMode)
{
uint32_t tmpr = 0U;
/* Set NORSRAM device timing register for write configuration, if extended mode is used */
if (ExtendedMode == FMC_EXTENDED_MODE_ENABLE) {
/* Get the BWTR register value */
tmpr = Device->BWTR[Bank];
/* Clear ADDSET, ADDHLD, DATAST, BUSTURN and ACCMOD bits */
tmpr &= ((uint32_t)~(FMC_BWTR1_ADDSET | FMC_BWTR1_ADDHLD | FMC_BWTR1_DATAST | FMC_BWTR1_BUSTURN | FMC_BWTR1_ACCMOD));
tmpr |= (uint32_t)(Timing->AddressSetupTime |\
((Timing->AddressHoldTime) << 4U) |\
((Timing->DataSetupTime) << 8U) |\
((Timing->BusTurnAroundDuration) << 16U) |\
(Timing->AccessMode));
Device->BWTR[Bank] = tmpr;
} else {
Device->BWTR[Bank] = 0x0FFFFFFFU;
}
return 0;
}
And FMC init:
/** FMC GPIO Configuration
PD14 ------> FMC_DA0
PD15 ------> FMC_DA1
PD0 ------> FMC_DA2
PD1 ------> FMC_DA3
PE7 ------> FMC_DA4
PE8 ------> FMC_DA5
PE9 ------> FMC_DA6
PE10 ------> FMC_DA7
PE11 ------> FMC_DA8
PE12 ------> FMC_DA9
PE13 ------> FMC_DA10
PE14 ------> FMC_DA11
PE15 ------> FMC_DA12
PD8 ------> FMC_DA13
PD9 ------> FMC_DA14
PD10 ------> FMC_DA15
PD4 ------> FMC_NOE
PD5 ------> FMC_NWE
PD7 ------> FMC_NE1
PG9 ------> FMC_NE2
PG10 ------> FMC_NE3
PB7 ------> FMC_NL
PG6 ------> FMC_RB1
*/
LL_GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = LL_GPIO_PIN_7 | LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_11 | LL_GPIO_PIN_12 | LL_GPIO_PIN_13 | LL_GPIO_PIN_14
| LL_GPIO_PIN_15;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
LL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_8 | LL_GPIO_PIN_9 | LL_GPIO_PIN_10 | LL_GPIO_PIN_14 | LL_GPIO_PIN_15 | LL_GPIO_PIN_0 | LL_GPIO_PIN_1;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_4 | LL_GPIO_PIN_5 | LL_GPIO_PIN_7;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
LL_GPIO_Init(GPIOD, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_7;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = LL_GPIO_PIN_9 | LL_GPIO_PIN_10;
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
GPIO_InitStruct.Pull = LL_GPIO_PULL_UP;
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = LL_GPIO_AF_12;
LL_GPIO_Init(GPIOG, &GPIO_InitStruct);
Solved! Go to Solution.
2019-05-02 05:17 AM
I solve it.
#define ADDR_SHIFT(Address) (Bank1_SRAM2_ADDR + (2 * (Address)))
#define FMCWRITE(Address, Data) (*(__IO uint16_t *)(Address) = (Data))
And now I send write data:
FMCWRITE(ADDR_SHIFT(FMCadress), FMCdata);
2019-05-02 05:17 AM
I solve it.
#define ADDR_SHIFT(Address) (Bank1_SRAM2_ADDR + (2 * (Address)))
#define FMCWRITE(Address, Data) (*(__IO uint16_t *)(Address) = (Data))
And now I send write data:
FMCWRITE(ADDR_SHIFT(FMCadress), FMCdata);
2019-05-06 12:32 AM
Write on fmc bus is working. But when I try read from bus sometimes the received value is wrong. And I don't know why... :face_with_steam_from_nose:
#define Bank1_SRAM2_ADDR ((uint32_t)0x64000000)
#define ADDR_SHIFT(Address) (Bank1_SRAM2_ADDR + (2 * (Address)))
#define FMCREAD(uAdr) *(__IO uint16_t *)(uAdr)
And I have two function.
void Echo(uint16_t FMCadress, uint16_t FMCdata) {
InfoPrint("Adress 0x%X ; Data 0x%X", FMCadress, FMCdata);
FMCWRITE(ADDR_SHIFT(adr), dat);
delay_msec(1);
if (FMCREAD(ADDR_SHIFT(adr)) == dat)
InfoPrint("TRUE");
else
InfoPrint("FALSE");
}
void readfmc(uint16_t FMCadress)
{
uint16_t receive = RdXBank(ADDR_SHIFT(FMCadress));
InfoPrint("receive from: 0x%X data: 0x%X", FMCadress, receive);
}
And sometimes, I receive data from address. But this data have wrong latest bit. Any idea why is my latest bit wrong?
2019-05-06 05:14 AM
I'm so stupid.... :D
I had disable push pull output.