реклама на сайте
подробности

 
 
> Непонятки с SPI в sam7, PDC...
Terminator
сообщение Oct 22 2007, 02:38
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 209
Регистрация: 7-12-04
Из: Томск
Пользователь №: 1 382



Написал "драйвер" SPI master для FreeRTOS с использованием PDC (at91sam7x256).
Передача работает замечательно, а приём частенько "виснет".
Обработчик прерывания
Код
static void __attribute__((naked)) SPI0_ISR( void )
{
    portENTER_SWITCHING_ISR();
        
        tSPI *spi = &all_spi[spi_num];

    unsigned int stat = spi->spi->SPI_SR;
    unsigned int imr = spi->spi->SPI_IMR;
    stat &= imr;
        
    portBASE_TYPE res = pdFALSE;
    if (stat & (AT91C_SPI_ENDRX | AT91C_SPI_ENDTX))
    {
        // сигналим задаче
        res = xSemaphoreGiveFromISR( spi->sem, res);
    }
    
    // запрещаем прерывания
    //spi->spi->SPI_IDR = SPI_INT;
    spi->spi->SPI_IDR = 0xFFFFFFFF;
    
    /* Clear the interrupt. */
    AT91C_BASE_AIC->AIC_EOICR = 0;
    
        portEXIT_SWITCHING_ISR( res );
}


Функция чтения.
Код
// читает из SPI буфер buf размером count
// @param spi_num - номер SPI
// @param buf - куда писать
// @param count - сколько писать
void SPI_Read(unsigned char spi_num, void *buf, unsigned int count)
{
    tSPI *spi = &all_spi[spi_num];

    // чтобы сбросить флаг приёма байта, возможно оставленный прошлой
    // передачей
    spi_num = spi->spi->SPI_RDR;
    
    // готовим PDC
    AT91PS_PDC pPDC = ((AT91PS_PDC) &(spi->spi->SPI_RPR));
    AT91F_PDC_SetRx(pPDC, (char *) buf, count);
    AT91F_PDC_SetTx(pPDC, (char *) buf, count);
    
    // включаем PDC
    AT91F_PDC_EnableTx(pPDC);
    AT91F_PDC_EnableRx(pPDC);

    // разрешаем прерывание
    spi->spi->SPI_IER = AT91C_SPI_ENDRX;
    
    // ждём семафор
    xSemaphoreTake(spi->sem, MAX_BlockTime);
    
    // выключаем PDC
    AT91F_PDC_DisableTx(pPDC);
    AT91F_PDC_DisableRx(pPDC);
}


Вставлял отладочные printf в разных местах, выяснилось, что иногда прерывание не срабатывает. Почему так происходит для меня остаётся загадкой sad.gif

Этот код в основном используется для чтения из флешки, нормально работает пока не попытаюсь прочитать сразу много, под 500кб.
В случайном месте падает. Чтение производится порциями по 530 байт.

Реализация без PDC нормально работает.

Может есть какие-то тонкие моменты при использовании PDC, которые я упустил? help.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Alexey V.
сообщение Oct 22 2007, 03:28
Сообщение #2


Участник
*

Группа: Новичок
Сообщений: 24
Регистрация: 10-05-06
Из: Russia, Tomsk
Пользователь №: 16 936



тоже были проблемы с SPI+PDC - в даташите в эррате обнаружил, что лучше ножкой чипселекта управлять вручную (иначе чипселект будет подниматься сразу же после передачи последнего байта, независимо от настроек)
Go to the top of the page
 
+Quote Post
Terminator
сообщение Oct 22 2007, 03:45
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 209
Регистрация: 7-12-04
Из: Томск
Пользователь №: 1 382



Цитата(Alexey V. @ Oct 22 2007, 10:28) *
тоже были проблемы с SPI+PDC - в даташите в эррате обнаружил, что лучше ножкой чипселекта управлять вручную (иначе чипселект будет подниматься сразу же после передачи последнего байта, независимо от настроек)

Это я тоже читал. Выставляю чипселекты "руками". Так что отпадает.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 13th August 2025 - 16:46
Рейтинг@Mail.ru


Страница сгенерированна за 0.01377 секунд с 7
ELECTRONIX ©2004-2016