|
Внешние DMA запросы в STR91, Не могу запустить , HELP!!! |
|
|
|
Sep 18 2007, 05:21
|
Частый гость
 
Группа: Участник
Сообщений: 89
Регистрация: 18-09-07
Пользователь №: 30 613

|
Хочу организовать пересылку данных из памяти в SPI через DMA по приходу внешнего DMA запроса Ничего не выходит... Просветите, в чем косяк Данные для пересылки храняться в массиве SSP1_Buffer_Tx, запрос приходит на ногу P0.3 Код // Конфигурим ногу для внешнего DMA запроса
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Direction = GPIO_PinInput; //GPIO_InitStruct.GPIO_Type= GPIO_Type_PushPull; GPIO_InitStruct.GPIO_IPConnected = GPIO_IPConnected_Enable; GPIO_InitStruct.GPIO_Alternate= GPIO_InputAlt1; GPIO_Init (GPIO3, &GPIO_InitStruct); // Конфигурим DMA DMA_DeInit(); DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel_LLstItm= 0; DMA_InitStruct.DMA_Channel_SrcAdd= (u32)&SSP1_Buffer_Tx; DMA_InitStruct.DMA_Channel_DesAdd=(u32)(&SSP1->DR); DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesBstSize = DMA_DesBst_1Data; DMA_InitStruct.DMA_Channel_FlowCntrl= DMA_FlowCntrl1_DMA; DMA_InitStruct.DMA_Channel_Des = DMA_SRC_External_Req0; DMA_InitStruct.DMA_Channel_TrsfSize = 16; DMA_Init(DMA_Channel0,&DMA_InitStruct); DMA_ChannelSRCIncConfig (DMA_Channel0, ENABLE); DMA_ChannelDESIncConfig (DMA_Channel0, ENABLE); DMA_ITConfig(DMA_Channel0, ENABLE); DMA_ITMaskConfig(DMA_Channel0, DMA_ITMask_ITC, ENABLE); DMA_ChannelCmd (DMA_Channel0,ENABLE); DMA_Cmd(ENABLE);
|
|
|
|
|
 |
Ответов
(1 - 14)
|
Sep 18 2007, 09:37
|
Частый гость
 
Группа: Участник
Сообщений: 89
Регистрация: 18-09-07
Пользователь №: 30 613

|
У меня ситуация такая: 16 АЦП, соединенных в цепочку, таймер генерит сигнал преобразования, шириной 2мкс и периодом 800мкс, по спаду импульса должен запускаться DMA и опрашивать АЦП. Сделано так: с выхода таймера, через инвертор, импульс подается на вход внешнего запроса DMA. Пока пытаюсь выдавать произвольные данные, чтобы получить клок на считывание АЦП. Нифига DMA не запускается :-( Вариант с программным запуском SPI не катит, проц должен осуществлять опрос АЦП автоматически, не отвлекаясь на запуски SPI и тп геморрой. Неужели такое невозможно? Зачем тогда нужны входы внешнего запроса DMA?
Сообщение отредактировал Thunderbird - Sep 18 2007, 09:39
|
|
|
|
|
Sep 18 2007, 11:15
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
а вы не думали что DMA будет забирать данные с регистра SPI быстрее чем он их туда положит ? синхронизация толжна быть однозначно. Следовательно если есть синхронизация значит процессом копирования не DMA управляет а в вашем случае SPI. А внешний запуск DMA нужен для запуска копирования в режиме не требующего синхронизации, конечно можно еще много всяких левых вариантов придумать. В вашем случае невижу никаких проблем. Если таймер внешний, то выход заведите на внешнеее прерывание, можно даже FIQ. В прерывании запускаете SPI. Естественно DMA должен быть запрограммирован на нужный размер блока данных который вы желаеете получить, надеюсь вы не по 1 байту пересылаете  . Это в том случае если SPI работает в режиме MASTER. Если SPI работает в режиме SLAVE то тут вобще сказка, ничего запускать не надо, создаете на DMA кольцевой буфер, запускаете ПДП и SPI и все будет автоматом крутится, а по внешнему прерыванию начинаете вашу обработку, примерно так.
|
|
|
|
|
Sep 18 2007, 12:26
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Цитата Согласно даташиту условием запуска DMA является Half FIFO level reached. Это , что получается я должен забить половину FIFO для запуска DMA??? точно не помню нет мануала под рукой, все там должно настраиваться для начала, опишите детальнее схему, кто генерит сигналы, какие АЦП, в каком режиме работает SPI ?
|
|
|
|
|
Sep 19 2007, 21:04
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Хоть я и не пользуюсь этой кривой библиотекой от ST, но тут невооруженым глазом видно, что включен инкремент адреса назначения. Для SPI это как то не логично мягко говоря. Цитата(Thunderbird @ Sep 18 2007, 08:51)  Хочу организовать пересылку данных из памяти в SPI через DMA по приходу внешнего DMA запроса Ничего не выходит... Просветите, в чем косяк Данные для пересылки храняться в массиве SSP1_Buffer_Tx, запрос приходит на ногу P0.3 Код // Конфигурим ногу для внешнего DMA запроса
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Direction = GPIO_PinInput; //GPIO_InitStruct.GPIO_Type= GPIO_Type_PushPull; GPIO_InitStruct.GPIO_IPConnected = GPIO_IPConnected_Enable; GPIO_InitStruct.GPIO_Alternate= GPIO_InputAlt1; GPIO_Init (GPIO3, &GPIO_InitStruct); // Конфигурим DMA DMA_DeInit(); DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel_LLstItm= 0; DMA_InitStruct.DMA_Channel_SrcAdd= (u32)&SSP1_Buffer_Tx; DMA_InitStruct.DMA_Channel_DesAdd=(u32)(&SSP1->DR); DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesBstSize = DMA_DesBst_1Data; DMA_InitStruct.DMA_Channel_FlowCntrl= DMA_FlowCntrl1_DMA; DMA_InitStruct.DMA_Channel_Des = DMA_SRC_External_Req0; DMA_InitStruct.DMA_Channel_TrsfSize = 16; DMA_Init(DMA_Channel0,&DMA_InitStruct); DMA_ChannelSRCIncConfig (DMA_Channel0, ENABLE); DMA_ChannelDESIncConfig (DMA_Channel0, ENABLE); DMA_ITConfig(DMA_Channel0, ENABLE); DMA_ITMaskConfig(DMA_Channel0, DMA_ITMask_ITC, ENABLE); DMA_ChannelCmd (DMA_Channel0,ENABLE); DMA_Cmd(ENABLE);
|
|
|
|
|
Sep 20 2007, 09:34
|
Частый гость
 
Группа: Участник
Сообщений: 89
Регистрация: 18-09-07
Пользователь №: 30 613

|
Цитата(MALLOY2 @ Sep 20 2007, 12:46)  Вобщем выложи полностью код инициализации SPI, DMA, а также обслуживающие функции запуска остановки и т.д. Код /* Includes ------------------------------------------------------------------*/
//#include "includes.h" #include "91x_conf.h" #include "91x_lib.h" #include "cmath"
#define DMA_Tx DMA_Channel1 #define DMA_Tx_No 1 #define DMA_Tx_ENABLE DMA_Tx->CCNF |= 0x00000001 #define DMA_Tx_DISABLE DMA_Tx->CCNF &= ~0x00000001 #define DMA_Tx_ACTIVE (DMA_Tx->CCNF & 0x00020000)
#define DMA_Tx_End (DMA->TCRISR & (1<#define DMA_Tx_WaitEnd while (! DMA_Tx_End) #define DMA_Tx_ClrEnd (DMA->TCICR = (1<#define DMA_Tx_ClrErr (DMA->EICR = (1<
volatile u32 DlyCount;
signed short SSP0_Buffer_Tx[32] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20}; signed short SSP1_Buffer_Tx[16] = {0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60}; signed short SSP0_Buffer_Rx[32], SSP1_Buffer_Rx[32]; u8 Tx_Idx=0, Rx_Idx=0, k=0;
DMA_InitTypeDef DMA_InitStruct;
/******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None *******************************************************************************/ void InitClock (void) { // Clock SCU_MCLKSourceConfig(SCU_MCLK_OSC); // master clk - OSC clk // Flash controller init SCU_FMICLKDivisorConfig(SCU_FMICLK_Div1); FMI_Config(FMI_READ_WAIT_STATE_2,FMI_WRITE_WAIT_STATE_0, FMI_PWD_ENABLE,\ FMI_LVD_ENABLE,FMI_FREQ_HIGH); // Set clks dividers SCU_RCLKDivisorConfig(SCU_RCLK_Div1); SCU_HCLKDivisorConfig(SCU_HCLK_Div1); SCU_PCLKDivisorConfig(SCU_PCLK_Div2); // Init PLL = 96 MHz SCU_PLLFactorsConfig(192,25,2); // PLL Enabled SCU_PLLCmd(ENABLE); // Switch clk MCLK = PLL SCU_MCLKSourceConfig(SCU_MCLK_PLL); }
void SCU_Configuration(void) {
/* Enable the __SSP1 Clock */ SCU_APBPeriphClockConfig(__SSP1 ,ENABLE);
/* Enable the __GPIO5 for SSP0 Clock */ //SCU_APBPeriphClockConfig(__GPIO5 ,ENABLE);
/* Enable the __GPIO3 for SSP1 Clock */
SCU_APBPeriphClockConfig(__GPIO3 ,ENABLE); SCU_APBPeriphClockConfig(__TIM01 ,ENABLE); SCU_AHBPeriphClockConfig(__VIC, ENABLE); SCU_AHBPeriphClockConfig(__DMA, ENABLE);
}
void Start_SSP1_TX_DMA(signed short *Bu, u16 Count) { DMA_Tx_DISABLE; DMA_Tx->SRC=(u32)Bu; DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_TrsfSize = 16; DMA_Tx_ENABLE;
}
void Tim0Handler (void) { if (TIM_GetFlagStatus(TIM0,TIM_FLAG_OC1)) { TIM_ClearFlag(TIM0,TIM_FLAG_OC1); //SSP_SendData(SSP1, SSP1_Buffer_Tx[Tx_Idx++]); //SSP_SendData(SSP1, SSP1_Buffer_Tx[/*Tx_Idx++*/ 0]); Start_SSP1_TX_DMA(SSP1_Buffer_Tx,16); } if (TIM_GetFlagStatus(TIM0,TIM_FLAG_OC2)) { TIM_ClearFlag(TIM0,TIM_FLAG_OC2); TIM_CounterCmd(TIM0, TIM_CLEAR); GPIO_WriteBit(GPIO3, GPIO_Pin_0, Bit_SET); GPIO_WriteBit(GPIO3, GPIO_Pin_0, Bit_RESET); } }
int main() { #ifdef DEBUG debug(); #endif
InitClock (); SCU_AHBPeriphClockConfig(__VIC, ENABLE); // VIC Deinitialization VIC_DeInit(); // __disable_interrupt(); SCU_Configuration(); //Timer init TIM_DeInit(TIM0); TIM_InitTypeDef TimerInitStruct; TIM_StructInit (&TimerInitStruct); TimerInitStruct.TIM_Mode = TIM_OCM_CHANNEL_12; TimerInitStruct.TIM_OC1_Modes = TIM_TIMING; TimerInitStruct.TIM_OC2_Modes = TIM_TIMING; TimerInitStruct.TIM_Clock_Source = TIM_CLK_APB; TimerInitStruct.TIM_Prescaler = 2-1; TimerInitStruct.TIM_Pulse_Length_1=48; TimerInitStruct.TIM_Pulse_Length_2=20000; TIM_Init (TIM0, &TimerInitStruct); TIM_ITConfig (TIM0,TIM_IT_OC1|TIM_IT_OC2,ENABLE);
//GPIO init //-------------------------------------------------------------- GPIO_DeInit(GPIO3); GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; GPIO_InitStruct.GPIO_Direction = GPIO_PinOutput; GPIO_InitStruct.GPIO_Type= GPIO_Type_PushPull; GPIO_InitStruct.GPIO_IPConnected = GPIO_IPConnected_Disable; GPIO_InitStruct.GPIO_Alternate= GPIO_OutputAlt1; GPIO_Init (GPIO3, &GPIO_InitStruct);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; GPIO_InitStruct.GPIO_Direction = GPIO_PinInput; GPIO_InitStruct.GPIO_IPConnected = GPIO_IPConnected_Enable; GPIO_InitStruct.GPIO_Alternate= GPIO_InputAlt1; GPIO_Init (GPIO3, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_6; GPIO_InitStruct.GPIO_Direction = GPIO_PinOutput; GPIO_InitStruct.GPIO_Type= GPIO_Type_PushPull; GPIO_InitStruct.GPIO_IPConnected = GPIO_IPConnected_Enable; GPIO_InitStruct.GPIO_Alternate= GPIO_OutputAlt2; GPIO_Init (GPIO3, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1; GPIO_InitStruct.GPIO_Direction = GPIO_PinOutput; GPIO_InitStruct.GPIO_Type= GPIO_Type_PushPull; GPIO_InitStruct.GPIO_IPConnected = GPIO_IPConnected_Disable; GPIO_InitStruct.GPIO_Alternate= GPIO_OutputAlt1; GPIO_Init (GPIO3, &GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; GPIO_InitStruct.GPIO_Direction = GPIO_PinOutput; GPIO_InitStruct.GPIO_Type= GPIO_Type_PushPull; GPIO_InitStruct.GPIO_IPConnected = GPIO_IPConnected_Disable; GPIO_InitStruct.GPIO_Alternate= GPIO_OutputAlt1; GPIO_Init (GPIO3, &GPIO_InitStruct); //-------------------------------------------------------------------------- //Èíèöèàëèçàöèÿ SPI SSP_DeInit (SSP1); SSP_InitTypeDef SSP_InitStructure; SSP_InitStructure.SSP_FrameFormat= SSP_FrameFormat_Motorola; SSP_InitStructure.SSP_Mode= SSP_Mode_Master; SSP_InitStructure.SSP_CPOL= SSP_CPOL_High; SSP_InitStructure.SSP_CPHA= SSP_CPHA_2Edge; SSP_InitStructure.SSP_DataSize= SSP_DataSize_16b; SSP_InitStructure.SSP_SlaveOutput= SSP_SlaveOutput_Disable; SSP_InitStructure.SSP_ClockRate= 3; SSP_InitStructure.SSP_ClockPrescaler=12; SSP_Init(SSP1, &SSP_InitStructure); SSP_DMACmd(SSP1, SSP_DMA_Transmit, ENABLE); SSP_Cmd(SSP1, ENABLE); // Èíèöèàëèçàöèÿ DMA /* DMA_DeInit(); DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel_LLstItm= 0; DMA_InitStruct.DMA_Channel_SrcAdd= (u32)&SSP1_Buffer_Tx; DMA_InitStruct.DMA_Channel_DesAdd=(u32)(&SSP1->DR); DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesBstSize = DMA_DesBst_1Data; DMA_InitStruct.DMA_Channel_FlowCntrl= DMA_FlowCntrl1_DMA; DMA_InitStruct.DMA_Channel_Src = DMA_SRC_SSP1_TX; DMA_InitStruct.DMA_Channel_Des = DMA_DES_SSP1_TX; DMA_InitStruct.DMA_Channel_TrsfSize = 16; DMA_SyncConfig(DMA_SSP1_TX_Mask, ENABLE);
DMA_Init(DMA_Channel0,&DMA_InitStruct); DMA_ChannelSRCIncConfig (DMA_Channel0, ENABLE); // DMA_ChannelDESIncConfig (DMA_Channel0, ENABLE); DMA_ITConfig(DMA_Channel0, ENABLE); DMA_ITMaskConfig(DMA_Channel0, DMA_ITMask_ITC, ENABLE); DMA_ChannelCmd (DMA_Channel0,ENABLE); DMA_Cmd(ENABLE); */ // Èíèöèàëèçàöèÿ êîíòðîëëåðà ïðåðûâàíèé // VIC_DeInit(); // âêëþ÷àåì ïðåðûâàíèÿ ïî òàéìåðó TIM_CounterCmd(TIM0, TIM_START); VIC_Config (TIM0_ITLine , VIC_IRQ , 1); VIC_Config (DMA_ITLine, VIC_IRQ , 2); VIC_ITCmd(TIM0_ITLine, ENABLE); VIC_ITCmd(DMA_ITLine , ENABLE); // __enable_interrupt();
while(1) { // while(SSP_GetFlagStatus(SSP1, SSP_FLAG_RxFifoNotEmpty)==RESET){}; } }
|
|
|
|
|
Sep 20 2007, 15:35
|
Знающий
   
Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317

|
Код // Èíèöèàëèçàöèÿ DMA /* DMA_DeInit(); DMA_StructInit(&DMA_InitStruct); DMA_InitStruct.DMA_Channel_LLstItm= 0; DMA_InitStruct.DMA_Channel_SrcAdd= (u32)&SSP1_Buffer_Tx; DMA_InitStruct.DMA_Channel_DesAdd=(u32)(&SSP1->DR); DMA_InitStruct.DMA_Channel_SrcWidth= DMA_SrcWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesWidth= DMA_DesWidth_HalfWord; DMA_InitStruct.DMA_Channel_DesBstSize = DMA_DesBst_1Data; DMA_InitStruct.DMA_Channel_FlowCntrl= DMA_FlowCntrl1_DMA; <- ОШИБКА DMA_InitStruct.DMA_Channel_Src = DMA_SRC_SSP1_TX; DMA_InitStruct.DMA_Channel_Des = DMA_DES_SSP1_TX; DMA_InitStruct.DMA_Channel_TrsfSize = 16; DMA_SyncConfig(DMA_SSP1_TX_Mask, ENABLE); Не помню как зовется дефайн, но там должног быть указана свинхронизация к SPI
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|