Миландр

Ключевым подразделением нашей компании
является Центр Проектирования интегральных микросхем
Текущее время: 2019-дек-12 05:50

Часовой пояс: UTC+03:00




Начать новую тему  Ответить на тему  [ 3 сообщения ] 
Автор Сообщение
 Заголовок сообщения: 1986ве1т 4 ревизия ssp
СообщениеДобавлено: 2018-фев-26 10:02 
Не в сети

Зарегистрирован: 2017-сен-21 09:22
Сообщения: 12
Организация: частное лицо
Здравствуйте. Прошу помощи с настройкой ssp2 через dma. Проблема состоит в том что не правильно отсылается адрес на датчик. На первом рисунке как есть в данный момент , на втором как должно быть. При прямой посылке через функцию senddata работает. Код ниже.
#include "MDR32F9Qx_config.h"

#include "MDR32F9Qx_rst_clk.h"
#include "MDR32F9Qx_port.h"
#include "MDR32F9Qx_ssp.h"
#include "MDR32F9Qx_eeprom.h"
#include "MDR32F9Qx_dma.h"

#define MPUREG_PRODUCT_ID 0x0C
#define READ_FLAG   0x80
#define MPUREG_WHOAMI 0x75
#define MPUREG_ACCEL_XOUT_H 0x3B
#define MPUREG_ACCEL_XOUT_L 0x3C
SSP_InitTypeDef sSSP;
static PORT_InitTypeDef PORT_InitStructure;
DMA_ChannelInitTypeDef DMA_InitStr;//для ssp2 tx
DMA_ChannelInitTypeDef DMA_InitStr1;//для ssp2 rx
DMA_ChannelInitTypeDef DMA_InitStrADC;// для adc
DMA_CtrlDataInitTypeDef DMA_PriCtrlStr;//первичная сруктура для ssp2_tx
DMA_CtrlDataInitTypeDef DMA_AltCtrlStr;//альтернативная --|--

uint32_t address[2] = {MPUREG_WHOAMI|READ_FLAG,0};//) - WHO_AM_I - READ
uint8_t WHOIAM,nop;
uint32_t DMA_Completed = 0;//флаг для прерывания
uint32_t TX_Started = 0;//флаг для прерывания

uint16_t DstBuf1[2];

int main ( void )
{
	RST_CLK_DeInit();

	// Включить генератор на внешнем кварце
	RST_CLK_HSEconfig (RST_CLK_HSE_ON);
	while (RST_CLK_HSEstatus() != SUCCESS);

	/* Sets the code latency value */
	EEPROM_SetLatency(EEPROM_Latency_2);

	// Настроить источник и КУ PLL (CPU_C1_SEL = HSE)
	RST_CLK_CPU_PLLconfig(RST_CLK_CPU_PLLsrcHSEdiv1, RST_CLK_CPU_PLLmul8); //120MHz

	// Включить PLL, но еще не подключать к кристаллу
	RST_CLK_CPU_PLLcmd(ENABLE);
	while (RST_CLK_CPU_PLLstatus() != SUCCESS);

	// Делитель С3( CPU_C3_SEL = CPU_C2_SEL )
	RST_CLK_CPUclkPrescaler(RST_CLK_CPUclkDIV1);

	// На С2 идет с PLL, а не напрямую с С1 (CPU_C2_SEL = PLL)
	RST_CLK_CPU_PLLuse(ENABLE);

	// CPU берет с выхода С3 (а может с выхода HSI,LSI,LSE) (HCLK_SEL = CPU_C3_SEL )
	RST_CLK_CPUclkSelection(RST_CLK_CPUclkCPU_C3);

	RST_CLK_PCLKcmd(RST_CLK_PCLK_RST_CLK, ENABLE);
	RST_CLK_PCLKcmd(RST_CLK_PCLK_SSP1|RST_CLK_PCLK_SSP2|RST_CLK_PCLK_SSP3|RST_CLK_PCLK_DMA, ENABLE);
	RST_CLK_PCLKcmd(RST_CLK_PCLK_PORTC, ENABLE);



	/* Reset PORTD settings */
	PORT_DeInit(MDR_PORTC );
	PORT_InitStructure.PORT_PD 	  = PORT_PD_DRIVER;
	PORT_InitStructure.PORT_MODE  = PORT_MODE_DIGITAL;
	PORT_InitStructure.PORT_SPEED = PORT_SPEED_FAST;
	PORT_InitStructure.PORT_FUNC  = PORT_FUNC_MAIN;
	PORT_InitStructure.PORT_Pin   = PORT_Pin_10 ;
	PORT_InitStructure.PORT_OE    = PORT_OE_IN;
	PORT_Init(MDR_PORTC, &PORT_InitStructure);
	PORT_InitStructure.PORT_Pin   =  PORT_Pin_9| PORT_Pin_11| PORT_Pin_12;
	PORT_InitStructure.PORT_OE    = PORT_OE_OUT;
	PORT_Init(MDR_PORTC, &PORT_InitStructure);

	/* Reset all SSP settings */
	SSP_DeInit(MDR_SSP2);
	SSP_BRGInit(MDR_SSP2,SSP_HCLKdiv8);
	/* SSP2 MASTER configuration ------------------------------------------------*/
	SSP_StructInit (&sSSP);
	sSSP.SSP_SCR  = 0;
	sSSP.SSP_CPSDVSR = 2;
	sSSP.SSP_Mode = SSP_ModeMaster;
	sSSP.SSP_WordLength = SSP_WordLength8b;
	sSSP.SSP_SPH = SSP_SPH_1Edge;
	sSSP.SSP_SPO = SSP_SPO_Low;
	sSSP.SSP_FRF = SSP_FRF_SPI_Motorola;
	sSSP.SSP_HardwareFlowControl = SSP_HardwareFlowControl_SSE;
	SSP_Init (MDR_SSP2,&sSSP);
	SSP_Cmd(MDR_SSP2,ENABLE);

	/* DMA Configuration */

	DMA_StructInit(&DMA_InitStr);
	/* Set Primary Control Data */
	DMA_PriCtrlStr.DMA_SourceBaseAddr = (uint32_t)address;//настраиваем tx структуру
	DMA_PriCtrlStr.DMA_DestBaseAddr = (uint32_t)(&(MDR_SSP2->DR));
	DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncHalfword;
	DMA_PriCtrlStr.DMA_DestIncSize = DMA_DestIncNo;
	DMA_PriCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_PriCtrlStr.DMA_Mode = DMA_Mode_PingPong;
	DMA_PriCtrlStr.DMA_CycleSize = 2;
	DMA_PriCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
	DMA_PriCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
	DMA_PriCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;

	/* Set Alternate Control Data */
	DMA_AltCtrlStr.DMA_SourceBaseAddr = (uint32_t)(&(MDR_SSP2->DR)); //настраиваем rx структуру
	DMA_AltCtrlStr.DMA_DestBaseAddr   = (uint32_t)&DstBuf1[0];
	DMA_AltCtrlStr.DMA_SourceIncSize = DMA_SourceIncNo;
	DMA_AltCtrlStr.DMA_DestIncSize = DMA_DestIncHalfword;
	DMA_AltCtrlStr.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	DMA_AltCtrlStr.DMA_Mode = DMA_Mode_PingPong;
	DMA_AltCtrlStr.DMA_CycleSize = 2;
	DMA_AltCtrlStr.DMA_NumContinuous = DMA_Transfers_1;
	DMA_AltCtrlStr.DMA_SourceProtCtrl = DMA_SourcePrivileged;
	DMA_AltCtrlStr.DMA_DestProtCtrl = DMA_DestPrivileged;

	/* Set Channel Structure */
	DMA_InitStr.DMA_PriCtrlData = &DMA_PriCtrlStr;//так было в примере с github
	DMA_InitStr.DMA_AltCtrlData = &DMA_PriCtrlStr;
	DMA_InitStr.DMA_Priority = DMA_Priority_Default;
	DMA_InitStr.DMA_UseBurst = DMA_BurstClear;
	DMA_InitStr.DMA_SelectDataStructure = DMA_CTRL_DATA_PRIMARY;

	/* Init DMA channel */
	DMA_Init(DMA_Channel_REQ_SSP2_TX, &DMA_InitStr);
	DMA_InitStr1.DMA_PriCtrlData = &DMA_AltCtrlStr;//так было в примере с github
	DMA_InitStr1.DMA_AltCtrlData = &DMA_AltCtrlStr;
	/* Init DMA channel */
	DMA_Init(DMA_Channel_REQ_SSP2_RX, &DMA_InitStr1);



	/* Enable SSP1 DMA Rx and Tx request */
	SSP_DMACmd(MDR_SSP2,(SSP_DMA_RXE | SSP_DMA_TXE), ENABLE);

	SSP_Cmd(MDR_SSP2,ENABLE);

	TX_Started = 1;
	DMA_Completed = 0;

	/* Enable DMA IRQ */
	NVIC_EnableIRQ(DMA_IRQn);


	while (1)
	{
	    
//		флаги для прерывания
		TX_Started = 1;
		DMA_Completed = 0;
		DMA_Init(DMA_Channel_REQ_SSP2_TX, &DMA_InitStr);
		DMA_Init(DMA_Channel_REQ_SSP2_RX, &DMA_InitStr1);

		DMA_Cmd(DMA_Channel_REQ_SSP2_TX, ENABLE);
		DMA_Cmd(DMA_Channel_REQ_SSP2_RX, ENABLE);
		SSP_DMACmd(MDR_SSP2,(SSP_DMA_RXE | SSP_DMA_TXE), ENABLE);

	}
}


Вложения:
Комментарий к файлу: рисунок 2
[ attachment ]
IMG_20180226_105703_BURST1.jpg [ 934.13 КБ | 1477 просмотров ]
[ attachment ]
IMG_20180226_091501_HDR.jpg [ 4.47 МБ | 1477 просмотров ]
Вынести предупреждение
Вернуться к началу
 Заголовок сообщения: Re: 1986ве1т 4 ревизия ssp
СообщениеДобавлено: 2018-фев-26 17:11 
Не в сети

Зарегистрирован: 2014-июн-25 09:29
Сообщения: 121
На первый взгляд, ошибка кроется в строке:
uint32_t address[2] = {MPUREG_WHOAMI|READ_FLAG,0};//) - WHO_AM_I - READ
и (или) описании констант MPUREG_WHOAMI и READ_FLAG:
#define READ_FLAG 0x80
#define MPUREG_WHOAMI 0x75

Выражение MPUREG_WHOAMI|READ_FLAG даст значение 0x000000F5, которое мы и видим на первом рисунке.

То, что показано на втором рисунке получится, если сделать так:
address[0] = 0x000A0008;

Также следует отметить, что элемент address[1] в вашем примере никогда не будет передан и вот почему:
1. Массив address состоит из двух 32-битных слов (uint32_t address[2]).
2. В настройке DMA вы указываете увеличение адреса источника на 16 бит ( DMA_PriCtrlStr.DMA_SourceIncSize = DMA_SourceIncHalfword;).
3. Размер передаваемого по SPI фрейма 8бит ( sSSP.SSP_WordLength = SSP_WordLength8b;).
В результате, DMA читает младшие 16 бит из address[0], кладет их в регистр SSP2-DR. SSP2 берет из DR биты 7..0 (фрейм 8-ми битный!) и передает их. Биты 15..8 этого полуслова просто теряются. Далее адрес DMA-источника увеличивается на 2 (DMA_SourceIncHalfword).
При следующей передачи через DMA будут переданы биты 23..16 из address[0], которые пустые. До передачи address[1] дело вообще не дойдет.
Думаю, правильней сделать так. Массив address сделать 16-битным:
uint16_t address[2]).
Полезные данные положить в младшие байты каждого из элементов массива:
address[0] = 0x08;
address[1] = 0x0A;


Вынести предупреждение
Вернуться к началу
 Заголовок сообщения: Re: 1986ве1т 4 ревизия ssp
СообщениеДобавлено: 2018-фев-27 13:19 
Не в сети

Зарегистрирован: 2017-сен-21 09:22
Сообщения: 12
Организация: частное лицо
спасибо. всё дело было в выравнивании памяти чем то типа такого (
uint16_t address[2] __attribute__((section(".ramfunc"), aligned(DATA_ALIGN)));
)


Вынести предупреждение
Вернуться к началу
Показать сообщения за:  Поле сортировки  
Начать новую тему  Ответить на тему  [ 3 сообщения ] 

Часовой пояс: UTC+03:00


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

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


Быстрые действия:
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти: 

Создано на основе phpBB® Forum Software © phpBB Limited
Русская поддержка phpBB