Контроллер внешней памяти

32-разрядные микроконтроллеры разработки ОАО "НИИЭТ"

Модераторы: pip, _sva_

Ответить
Аватара пользователя
atom
Сообщения: 4
Зарегистрирован: 26 фев 2016, 11:03
Предприятие: Алмаз-Фазотрон
Откуда: Саратов

Контроллер внешней памяти

Сообщение atom » 21 июн 2017, 09:43

Здравствуйте!
Я пытаюсь разобраться с работой контроллера внешней памяти в К1921ВК01Т. Использую первую альтернативную функцию портов. Разрядность шины устанавливаю 16 бит.

Код: Выделить всё

#include <stdint.h>
#include <stdbool.h>

#include <K1921VK01T.h>
#include <niietcm4.h>
#include <niietcm4_rcc.h>
#include <niietcm4_gpio.h>

#define MEM_ADDR_0    (*(volatile uint16_t *)0x40000000)
#define MEM_ADDR_1    (*(volatile uint16_t *)0x40000001)
#define MEM_ADDR_2    (*(volatile uint16_t *)0x40000002)
#define MEM_ADDR_3    (*(volatile uint16_t *)0x40000003)
#define MEM_ADDR_4    (*(volatile uint16_t *)0x40000004)
#define MEM_ADDR_8    (*(volatile uint16_t *)0x40000008)

void RCC_Initialization(void) {
  RCC_PLLAutoConfig(RCC_PLLRef_XI_OSC, 100000000);
  RCC_SysClkDiv2Out(DISABLE);
}

void EtxMem_Initialization(void) {
  GPIO_Init_TypeDef GPIO_InitStruct;

  GPIO_StructInit(&GPIO_InitStruct);
  GPIO_InitStruct.GPIO_AltFunc = GPIO_AltFunc_1;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AltFunc;
  GPIO_InitStruct.GPIO_Out = GPIO_Out_En;

  /** A[8-15] = ADDR[0-7] */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8_15;
  GPIO_Init(NT_GPIOA, &GPIO_InitStruct);

  /** B[4-14] = ADDR[8-18] */
  /** B[15]   = DATA[0] */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4_7 | GPIO_Pin_8_15;
  GPIO_Init(NT_GPIOB, &GPIO_InitStruct);

  /** C[6-15] = DATA[1-10] */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 |
                             GPIO_Pin_7 |
                             GPIO_Pin_8_15;
  GPIO_Init(NT_GPIOC, &GPIO_InitStruct);

  /** D[12-15] = DATA[11-14] */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12_15;
  GPIO_Init(NT_GPIOD, &GPIO_InitStruct);

  /** E[12]    = DATA[15] */
  /** E[13]    = MEM_WE */
  /** E[14]    = MEM_OE_0 */
  /** E[15]    = MEM_OE_1 */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12_15;
  GPIO_Init(NT_GPIOE, &GPIO_InitStruct);

  /** F[6]     = MEM_CE_0 */
  /** F[6]     = MEM_CE_1 */
  /** F[6]     = MEM_LB */
  /** F[6]     = MEM_UB */
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
  GPIO_Init(NT_GPIOF, &GPIO_InitStruct);

  /** инициализация контроллера внешней памяти */
  EXTMEM_Init_TypeDef EXTMEM_InitStruct;
  EXTMEM_StructInit(&EXTMEM_InitStruct);
  EXTMEM_InitStruct.CEMask = EXTMEM_CEMask_Addr_19;
  EXTMEM_InitStruct.EXTMEM_Width = EXTMEM_Width_16bit;
  EXTMEM_InitStruct.EXTMEM_RWWaitState = EXTMEM_RWWaitState_8;
  EXTMEM_InitStruct.EXTMEM_ReadWaitState = EXTMEM_ReadWaitState_8;
  EXTMEM_InitStruct.EXTMEM_WriteWaitState = EXTMEM_WriteWaitState_8;
  EXTMEM_Init(&EXTMEM_InitStruct);
}

int main(void) {
	uint16_t delay = 0;

	RCC_Initialization();
	EtxMem_Initialization();

	while (true) {
		MEM_ADDR_3 = 0x5555;
		for (delay = 0; delay < 10; delay++) ;
	}
}
Наблюдаю, что при записи по нечётным адресам в одном импульсе CE выдаются два импульса WE, при этом адрес выставляется только во время первого импульса WE. На приложенной диаграмме синяя линия - импульс CE, красная - импульс WE, зелёная - ADDR0 (ADDR1 ведёт себя точно также). При записи же по чётным адресам в одном импульса CE - один импульс WE.
Диаграмма работы | Показать
SCR01.PNG
Диаграмма работы
SCR01.PNG (29.69 КБ) 325 просмотров
Подскажите, пожалуйста, почему так происходит. Что я делаю неправильно?

Аватара пользователя
Лашкевич
Сообщения: 95
Зарегистрирован: 13 май 2015, 13:10
Предприятие: ООО "НПФ Вектор"
Откуда: Москва
Contact:

Re: Контроллер внешней памяти

Сообщение Лашкевич » 21 июн 2017, 11:10

Пока разработчики думаю над ответом, позвольте поинтересоваться, если не секрет - а для какой задачи в motorcontrol микроконтроллере потребовалось подключать внешнюю память? Для меня всегда было это не очень непонятно...
С уважением,
Лашкевич Максим.
Инженер-программист ООО "НПФ Вектор", Москва.
http://motorcontrol.ru/

hgost
Сообщения: 49
Зарегистрирован: 14 дек 2015, 12:07
Предприятие: АО НИИЭТ
Откуда: НИИЭТ
Contact:

Re: Контроллер внешней памяти

Сообщение hgost » 21 июн 2017, 13:51

atom писал(а):
21 июн 2017, 09:43
Здравствуйте!
Я пытаюсь разобраться с работой контроллера внешней памяти в К1921ВК01Т. Использую первую альтернативную функцию портов. Разрядность шины устанавливаю 16 бит.
Наблюдаю, что при записи по нечётным адресам в одном импульсе CE выдаются два импульса WE, при этом адрес выставляется только во время первого импульса WE. На приложенной диаграмме синяя линия - импульс CE, красная - импульс WE, зелёная - ADDR0 (ADDR1 ведёт себя точно также). При записи же по чётным адресам в одном импульса CE - один импульс WE.
Подскажите, пожалуйста, почему так происходит. Что я делаю неправильно?
Здравствуйте!
например когда Вы выполняете
(*(volatile uint16_t *)0x40000000)=0x2211;
контроллер через16-битный интерфейс записывает одновременно и младшую часть 0x11, и старшую 0х22 по адресам 0х40000000 и 0х40000001 соответственно. Это сопровождается одним импульсом WR, при совместно установленых линиях UBN и LBN (верхний и нижний байт).

когда Вы выполняете
(*(volatile uint16_t *)0x40000001)=0x4433;
контроллер через16-битный интерфейс записывает сначала младшую часть 0x33 по адресу 0х40000001 (с выставленным сигналом LBN), затем выставит адрес 0х40000002, и запишет старшую часть 0х44 (с выставленным сигналом UBN). Это собровождается двумя импульсами WR при одном установленном CE.

Вообще, если Вы пишете 16-разрядные данные, то рекомендуется писать их по адресам, выровненным по 2 байта.
Аналогично, если писать 32-разрядные данные, то выравнивание должно быть по 4 байта.
Запись данных по невыровненному адресу может привести к путанице или затереть уже имеющиеся данные, так что просто нужно быть внимательнее при выполнении таких операций. Либо пользоваться побайтовой записью в нечетный адрес, вида
(*(volatile uint8_t *)0x40000001)=0x55;

Аватара пользователя
atom
Сообщения: 4
Зарегистрирован: 26 фев 2016, 11:03
Предприятие: Алмаз-Фазотрон
Откуда: Саратов

Re: Контроллер внешней памяти

Сообщение atom » 21 июн 2017, 18:07

Лашкевич писал(а):
21 июн 2017, 11:10
для какой задачи в motorcontrol микроконтроллере потребовалось подключать внешнюю память?
Просто этот контроллер пожалуй лучшее, что есть из отечественных разработок, поэтому есть желание использовать его не только для управления двигателями, но и для других задач. А одновременно управлять двигателями и подключать внешнюю память не планировал.
hgost писал(а):
21 июн 2017, 13:51
Здравствуйте!
например когда Вы выполняете
(*(volatile uint16_t *)0x40000000)=0x2211;
контроллер через16-битный интерфейс записывает одновременно и младшую часть 0x11, и старшую 0х22 по адресам 0х40000000 и 0х40000001 соответственно. Это сопровождается одним импульсом WR, при совместно установленых линиях UBN и LBN (верхний и нижний байт).

когда Вы выполняете
(*(volatile uint16_t *)0x40000001)=0x4433;
контроллер через16-битный интерфейс записывает сначала младшую часть 0x33 по адресу 0х40000001 (с выставленным сигналом LBN), затем выставит адрес 0х40000002, и запишет старшую часть 0х44 (с выставленным сигналом UBN). Это собровождается двумя импульсами WR при одном установленном CE.

Вообще, если Вы пишете 16-разрядные данные, то рекомендуется писать их по адресам, выровненным по 2 байта.
Аналогично, если писать 32-разрядные данные, то выравнивание должно быть по 4 байта.
Запись данных по невыровненному адресу может привести к путанице или затереть уже имеющиеся данные, так что просто нужно быть внимательнее при выполнении таких операций. Либо пользоваться побайтовой записью в нечетный адрес, вида
(*(volatile uint8_t *)0x40000001)=0x55;
Правильно ли я понял, что вне зависимости от установленной настройки разрядности шины адресация всегда остаётся побайтовой?

hgost
Сообщения: 49
Зарегистрирован: 14 дек 2015, 12:07
Предприятие: АО НИИЭТ
Откуда: НИИЭТ
Contact:

Re: Контроллер внешней памяти

Сообщение hgost » 22 июн 2017, 09:58

atom писал(а):
21 июн 2017, 18:07
Правильно ли я понял, что вне зависимости от установленной настройки разрядности шины адресация всегда остаётся побайтовой?
Не совсем верно. Побайтово будет производиться только запись по невыровненным адресам. При записи по четным адресам оба байта пишутся одновременно. Вот рисунок, который это демонстрирует. На верхнем рисунке 2 байта пишутся одной записью по четному адресу, на нижнем - 2 побайтовыми записями, сопровождающимися сменой адреса
Работа внешней памяти при различных адресах | Показать
extmem.PNG
extmem.PNG (8.4 КБ) 286 просмотров

Ответить

Вернуться в «32-разрядные микроконтроллеры на ядре ARM Cortex»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость