Миландр

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

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 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
IMG_20180226_105703_BURST1.jpg
IMG_20180226_105703_BURST1.jpg [ 934.13 КБ | Просмотров: 574 ]
IMG_20180226_091501_HDR.jpg
IMG_20180226_091501_HDR.jpg [ 4.47 МБ | Просмотров: 574 ]
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: 1986ве1т 4 ревизия ssp
СообщениеДобавлено: 2018-фев-26 17:11 
Не в сети

Зарегистрирован: 2014-июн-25 09:29
Сообщения: 73
На первый взгляд, ошибка кроется в строке:
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 + 3 часа


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

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


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

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB