Vroobee Napisano Wrzesień 26, 2016 Udostępnij Napisano Wrzesień 26, 2016 Witam,mam pewien problem z wykonaniem wysyłania danych przez SPI z wykorzystaniem DMA. Mianowicie przy konfiguracji DMA (wycinek z biblioteki z konfiguracją DMA): #include "stm32f10x.h" #include "../src/DMA_Init/dma_init.h" uint32_t SPI_RxValue[rx_size]; uint32_t SPI_TxValue[tx_size] = {0x00}; void dma_init (void){ DMA_InitTypeDef dma; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); DMA_DeInit(DMA1_Channel2); DMA_StructInit(&dma); dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; //Address of peripheral the DMA must map to dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; dma.DMA_MemoryBaseAddr = (uint32_t)&SPI_RxValue[0]; //Variable to which received data will be stored dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; dma.DMA_DIR = DMA_DIR_PeripheralSRC; dma.DMA_BufferSize = rx_size; //Buffer size dma.DMA_Mode = DMA_Mode_Circular; dma.DMA_Priority = DMA_Priority_VeryHigh; dma.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel2, &dma); //Initialise the DMA DMA_Cmd(DMA1_Channel2, ENABLE); //Enable the DMA1 - Channel1 DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE); //==Configure DMA1 - Channel5== (memory -> SPI) DMA_DeInit(DMA1_Channel3); //Set DMA registers to default values DMA_StructInit(&dma); dma.DMA_PeripheralBaseAddr = (uint32_t)&SPI1->DR; //Address of peripheral the DMA must map to dma.DMA_PeripheralInc = DMA_PeripheralInc_Disable; dma.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; dma.DMA_MemoryBaseAddr = (uint32_t)&SPI_TxValue[0]; //Variable from which data will be transmitted dma.DMA_MemoryInc = DMA_MemoryInc_Enable; dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; dma.DMA_DIR = DMA_DIR_PeripheralDST; dma.DMA_BufferSize = tx_size; //Buffer size dma.DMA_Mode = DMA_Mode_Circular; dma.DMA_Priority = DMA_Priority_VeryHigh; dma.DMA_M2M = DMA_M2M_Disable; DMA_Init(DMA1_Channel3, &dma); //Initialise the DMA DMA_Cmd(DMA1_Channel3, ENABLE); //Enable the DMA1 - Channel5 SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, ENABLE); } i instrukcji wysyłania przez SPI: uint8_t spi_sendrec(uint8_t byte){ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, byte); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); } podczas debugowania pierwsze wysłanie wartości przez SPI przebiega ok, a przy następnej instrukcji wysyłania program się zawiesza. Wydaje mi się, że brakuje jakiejś flagi czyszczącej bit dotyczący wysyłania ale pewny nie jestem. Dodam jeszcze instrukcję obsługi przerwania odbioru przez SPI: void DMA1_Channel2_IRQHandler(void){ uint8_t i=0; if(DMA_GetITStatus(DMA1_IT_HT4)) { SPI_TxValue[0]=SPI_RxValue[0]; DMA_ClearITPendingBit(DMA1_IT_HT4); } if(DMA_GetITStatus(DMA1_IT_TC4)) { for (i=0;i<=7;i++){ SPI_TxValue[i]=SPI_RxValue[i]; } DMA_ClearITPendingBit(DMA1_IT_TC4); } } Gdyby ktoś był łaskaw sprawdzić i móc powiedzieć co mogło pójść nie tak to byłbym wdzięczny 🙂 [ Dodano: 27-09-2016, 20:35 ] Ktoś coś ? Cytuj Link do komentarza Share on other sites More sharing options...
Wojciech Wrzesień 28, 2016 Udostępnij Wrzesień 28, 2016 Hej, średnio znam się na STMach, ale spróbuję pomóc. Widzę pewne niezgodności w typach danych (według mnie tu tkwi problem): - Bufory SPI_RxValue i SPI_TxValue mają typ: uint32_t - W DMA1_Channel2 ustawiasz DataSize na: Byte - W DMA1_Channel3 ustawiasz DataSize na: HalfWord - Funkcja spi_sendrec przyjmuje i zwraca: uint8_t Poza tym możesz powiedzieć co oznaczają flagi: DMA1_IT_HT4 i DMA1_IT_TC4? Oraz ile wynosi rx_size i tx_size? Cytuj Link do komentarza Share on other sites More sharing options...
MirekCz Wrzesień 28, 2016 Udostępnij Wrzesień 28, 2016 1. Chcesz używać DMA, ale twój kod do wysyłania po SPI jest bez DMA 2. DMA masz ustawione w trybie circular. Jak dobrze pamiętam spowoduje to ciągłe wysyłanie, bo bufor się nigdy nie skończy... sprawdziłeś co pojawia się na wyjściu SPI? Umieść w buforze jakąś wartość typu 0x55 i powinieneś mieć na przemian 0/1/0/1/0/1/ na wyjściu SPI... no i oczywiście clock. Tryb powinien być Normal i jak chcesz zacząć wysyłać następną "ramkę" to ponownie ustawiasz wskaźnik na pamięć gdzie jest początek buforu, buforsize i odpalasz znowu DMA. Cytuj Link do komentarza Share on other sites More sharing options...
Vroobee Wrzesień 28, 2016 Autor tematu Udostępnij Wrzesień 28, 2016 Dzięki za odpowiedzi ! Do tej pory ogarniałem tylko przykłady z kursu STM32F1 na bibliotekach STL, teraz chciałem wykorzystać DMA w transmisji. MirekCz, czy mógłbyś jakoś mnie naprowadzić jak by to napisać, żeby transmisja odbywała się przy pomocy DMA ? Jak by wyglądała instrukcja wysyłania/odbierania z DMA ? Może jakiś przykład macie. Szukać szukałem ale znalazłem tylko inicjalizację, żadnych konkretnych instrukcji. Cytuj Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
MirekCz Wrzesień 28, 2016 Udostępnij Wrzesień 28, 2016 10sec z wujkiem google - http://electronics.stackexchange.com/questions/100685/full-duplex-slave-spi-dma-and-interrupts-on-stm32f103 Oczywiście patrz na odpowiedź z całym kodem... tam masz SPI2 użyte, ale to najmniejszy problem - wystarczy zmienić SPI na 1 i użyć odpowiednich kanałów DMA dla SPI1. Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!