Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Продукция MICROCHIP

Продукция MICROCHIP Технические вопросы по всей продукции Microchip

Ответ
 
Опции темы Опции просмотра
Старый 24.05.2007, 10:34   #1
Алексей
Senior Member
 
Регистрация: 25.02.2007
Сообщений: 465
Вес репутации: 578/59
Алексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to all
По умолчанию PIC24 и DMA, только пассивное чтение?

Можно ли заставить ДМА копировать блок данных с датафлешки (at45db161d)?

Судя по всему нет. Кто-то подтвердит/опровергнет?
Алексей вне форума   Ответить с цитированием
Старый 24.05.2007, 11:29   #2
Alex B.
Super Moderator
 
Аватар для Alex B.
 
Регистрация: 25.02.2007
Адрес: Russia, SPb
Сообщений: 1,674
Вес репутации: 1729/83
Alex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant futureAlex B. has a brilliant future
Отправить сообщение для Alex B. с помощью Skype™
По умолчанию Re: PIC24 и DMA, только пассивное чтение?

а почему нет-то???
ты ж по SPI-ю с ней общаешься, вот и использую один канал на чтение, другой на запись. После передачи команды на чтение, нужно толкнуть канал на запись, до кучи установив режим автоматической передачи нуля (так как по SPI можно прочитать, только передав). Это предусмотрено. Вот тебе код примера, правда это работа с SPI-ной eeprom

Код:
int main (void)
{
    // -----------------------------------------------------------------------------------------------------------------
    // КонфигурациЯ PLL
    // -----------------------------------------------------------------------------------------------------------------
    CLKDIV_bit.PLLPRE  = 2;             // 8 MHz   / 2  = 4   MHz
    PLLFBD_bit.PLLDIV  = 38;            // 4 MHz   * 40 = 160 MHz
    CLKDIV_bit.PLLPOST = 0;             // 160 MHz / 2  = 80  MHz  - Fosc

    while (!OSCCON_bit.LOCK);           // Ожидание стабилизации PLL
    
    // -----------------------------------------------------------------------------------------------------------------
    // Отключение АЦП
    // -----------------------------------------------------------------------------------------------------------------
    AD1PCFGL = 0xFFFF;                  // Все выводы - цифровые
    AD1PCFGH = 0xFFFF;
    AD2PCFGL = 0xFFFF;

    // -----------------------------------------------------------------------------------------------------------------
    // КонфигурациЯ модулЯ SPI
    // -----------------------------------------------------------------------------------------------------------------
    SPI2CON1_bit.DISSCK = 0;            // Отключение сигнала SCK  - нет
    SPI2CON1_bit.DISSDO = 0;            // Отключение сигнала SDO  - нет
    SPI2CON1_bit.MODE16 = 0;            // 16-битный режим         - нет
    SPI2CON1_bit.MSTEN  = 1;            // Режим работы            - мастер

    SPI2CON1_bit.SMP    = 0;
    SPI2CON1_bit.CKP    = 0;
    SPI2CON1_bit.CKE    = 1;

    // КонфигурациЯ тактовой частоты SCK = 10 МГц
    // ------------------------------------------
    SPI2CON1_bit.PPRE   = 3;
    SPI2CON1_bit.SPRE   = 6;

    SPI2STAT_bit.SPIEN  = ENABLE;       // Включение модулЯ SPI
    SPI2STAT_bit.SPIROV = 0;            // Сброс флага переполнениЯ

    SS_TR = 0;                          // КонфигурациЯ вывода SS
    SS_GL = !SS_ACT_LEV;

    // -----------------------------------------------------------------------------------------------------------------
    // КонфигурациЯ DMA
    // -----------------------------------------------------------------------------------------------------------------
    DMA0CON_bit.MODE   = 0;             // Режим работы           - последовательнаЯ пересылка, один буфер
    DMA0CON_bit.AMODE  = 0;             // Режим адресации        - регистроваЯ адресациЯ с постинкрементом
    DMA0CON_bit.NULLW  = 0;             // Запись при чтении      - нет

    DMA0CON_bit.HALF   = 0;             // Прерывание при
                                        // половинном заполнении/
                                        // передаче буфера        - нет

    DMA0CON_bit.DIR    = 1;             // Направление канала     - DMA RAM -> перифериЯ
    DMA0CON_bit.SIZE   = 1;             // РазрЯдность данных     - байт

    DMA0REQ_bit.IRQSEL = 33;            // Адрес вектора прерываниЯ периферийного модулЯ (SPI2)
    DMA0CNT            = 63;            // Размер буфера DMA (зависит от бита SIZE, значение равно физическому размеру
                                        //   буфера - 1)

	DMA0PAD = (volatile unsigned int) &SPI2BUF;     // Указатель на регистр периферии
    DMA0STA= __builtin_dmaoffset(SPI_TX) - 1;       // Указатель на буфер данных

    IFS0_bit.DMA0IF    = 0;             // Сброс флага прерываниЯ канала DMA0
    IEC0_bit.DMA0IE    = 1;             // Разрешение прерываниЯ от канала DMA0

    // -----------------------------------------------------------------------------------------------------------------
    // 
    // -----------------------------------------------------------------------------------------------------------------
    DMA1CON_bit.MODE   = 0;             // Режим работы           - последовательнаЯ пересылка, один буфер
    DMA1CON_bit.AMODE  = 0;             // Режим адресации        - регистроваЯ адресациЯ с постинкрементом
    DMA1CON_bit.NULLW  = 0;             // Запись нулЯ при чтении - нет

    DMA1CON_bit.HALF   = 0;             // Прерывание при
                                        // половинном заполнении/
                                        // передаче буфера        - нет

    DMA1CON_bit.DIR    = 0;             // Направление канала     - перифериЯ -> DMA
    DMA1CON_bit.SIZE   = 1;             // РазрЯдность данных     - байт

    DMA1REQ_bit.IRQSEL = 33;            // Адрес вектора прерываниЯ периферийного модулЯ (SPI2)
    DMA1CNT            = 63;            // Размер буфера DMA (зависит от бита SIZE, значение равно физическому размеру
                                        //   буфера - 1)

	DMA1PAD = (volatile unsigned int) &SPI2BUF;     // Указатель на регистр периферии
    DMA1STA= __builtin_dmaoffset(SPI_RX) - 1;       // Указатель на буфер данных

    IFS0_bit.DMA1IF    = 0;             // Сброс флага прерываниЯ канала DMA0
    IEC0_bit.DMA1IE    = 1;             // Разрешение прерываниЯ от канала DMA0
    
    // -----------------------------------------------------------------------------------------------------------------
    // Бесконечный цикл
    // -----------------------------------------------------------------------------------------------------------------
    while (1)
    {
        static U08 i, sc = 0;
        double (*func)(double);

        __delay32(DELAY_MS(250));

        // -------------------------------------------------------------------------------------------------------------
        // ИнициализациЯ данных длЯ записи в EEPROM - полупериод синуса или косинуса
        // -------------------------------------------------------------------------------------------------------------
        if (sc == 0) {func = sin; sc = 1;}
        else         {func = cos; sc = 0;}

        for (i = 0; i < SizeOfArr(SPI_TX); i++)
        {
            double arg;
            
            arg = PI * ((double)(i) / (double)(SizeOfArr(SPI_TX) - 1));
            SPI_TX[i] = (U16)(func(arg) * UINT_MAX);
        }

        // -------------------------------------------------------------------------------------------------------------
        // Запись данных в EEPROM
        // -------------------------------------------------------------------------------------------------------------
        DMA_end = 0;                    // Сброс флага окончаниЯ передачи
        SPI2BUF;                        // Сброс буфера SPI

        SS_EN();                        // ~SS -> 0
        SPI2_WR(F_WREN);                // Разрешение записи в 25LC256
        SS_DIS();                       // ~SS -> 1
        __delay32(DELAY_US(2));

        SS_EN();                        // ~SS -> 0
        SPI2_WR(F_WRITE);               // Команда на запись
        SPI2_WR(0x00);                  // Адрес
        SPI2_WR(0x00);

        DMA1CON_bit.NULLW  = 0;         // Запись нулЯ при чтении - нет		
		DMA0CON_bit.CHEN   = 1;         // Включение канала DMA0 - TX
		DMA1CON_bit.CHEN   = 1;         // Включение канала DMA1 - RX - обЯзательно, иначе при переполнении входного
		                                //   буфера модуль SPI выставит флаго ошибки и прекратит функционирование

        DMA0REQ_bit.FORCE  = 1;         // Начало передачи DMA0 -> перифериЯ

        //
        // Тут можно делать что-то полезное...
        //

        while (!DMA_end);               // Ожидание флага окончаниЯ передачи
        SS_DIS();                       // ~SS -> 1

        // -------------------------------------------------------------------------------------------------------------
        // Задержка длЯ записи данныз в EEPOM. Тут тоже можно делать что-то полезное, изредка проверЯЯ статусный бит
        //   записи EEPROM
        // -------------------------------------------------------------------------------------------------------------
        __delay32(DELAY_MS(7));

        // -------------------------------------------------------------------------------------------------------------
        // Чтение данных из EEPROM
        // -------------------------------------------------------------------------------------------------------------
    // ДлЯ BREAKPOINT
		Nop(); Nop(); Nop(); Nop();
    // ДлЯ BREAKPOINT

        DMA_end = 0;                    // Сброс флага окончаниЯ передачи

        SS_EN();                        // ~SS -> 0
        SPI2_WR(F_READ);                // Команда на чтение
        SPI2_WR(0x00);                  // Адрес
        SPI2_WR(0x00);

        DMA1CON_bit.NULLW  = 1;         // Так как длЯ считываниЯ данных по SPI необходимо записывать байт в регистр
                                        //   SPIBUF, нужно включить режим автоматической записи байта при чтении
                                        //   канала DMA. Этот режим специально предусмотрен длЯ работы SPI + DMA

		DMA1CON_bit.CHEN   = 1;         // Включение канала DMA1
        SPI2BUF = 0;                    // Передаем любой байт - инициируем начало обмена
        
        while (!DMA_end);               // Ожидание флага окончаниЯ приема
        SS_DIS();                       // ~SS -> 1

    // ДлЯ BREAKPOINT
        Nop(); Nop(); Nop(); Nop();
    // ДлЯ BREAKPOINT

    }

    // -----------------------------------------------------------------------------------------------------------------
    return 0;
}
названия регистров только поменяй на REGISTERbits.xxx
Alex B. вне форума   Ответить с цитированием
Старый 24.05.2007, 12:17   #3
Алексей
Senior Member
 
Регистрация: 25.02.2007
Сообщений: 465
Вес репутации: 578/59
Алексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to all
По умолчанию Re: PIC24 и DMA, только пассивное чтение?

Слона то я и не заметил(NULLW)...

Вчера полвечера экспериментировал, все время не получалось, типа первый байт копирует, а следующий не хочет.

Все функции (автомат подкачки данных в буфер) уже есть и работают, но они реализованы через машину состояний в прерывании, теперь хочу на ДМА перенести... и не заметил бит NULLW.

Спасибо за ответ и код. Сегодня вечером объявлю войну стэит-машинам в пользу DMA
Алексей вне форума   Ответить с цитированием
Старый 25.05.2007, 00:06   #4
Алексей
Senior Member
 
Регистрация: 25.02.2007
Сообщений: 465
Вес репутации: 578/59
Алексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to all
По умолчанию Re: PIC24 и DMA, только пассивное чтение?

Все-равно не получилось.
Инициализация:
Код:
        SPI1BUF;        // восстановили исходное состояние.
        _SPI1IE   = 0;
        //DMA0CON   = 0x4001;   // Chanel 0
        //DMA0CONbits.NULLW = 1;
        DMA1CONbits.SIZE  = 1;  // Byte mode
        DMA1CONbits.DIR   = 0;  // Read peripheral and write to DMA RAM
        DMA1CONbits.HALF  = 0;  // Interrupt when all data has been moved
        DMA1CONbits.NULLW = 1;  // Write 0x00 for read operation
        DMA1CONbits.AMODE = 0b00; // Registr indirect with postincriment
        DMA1CONbits.MODE  = 0b01; // One-shot, ping-pong disabled
        DMA1REQ   = 10;    
        DMA1STA   = __builtin_dmaoffset(CacheFile);
        //DMA0STB   = 0;
        DMA1PAD   = (volatile M_WORD)&SPI1BUF;
        DMA1CNT   = SizeDmaData - 1;
        _DMA1IF   = 0;
        _DMA1IP   = 4;
        _DMA1IE   = 1;
        DMA1CONbits.CHEN = 1;
        Nop();
        Nop();
        Nop();
        SPI1BUF = 0x00; // Запускаем чтение
        break;
Первый байт читает, а потом просто молчит и ничего не делает (как будто нуль не пишется автоматом в буфер СПИ1). Завтра вечером еще повоюю. _SPI1IF устанавливается, но модуль ДМА не реагирует.
Биты контролирую в режиме отладчика (ICD2) и они совпадают с инициализацией. И еще, когда прочитал первый байт, ДМА копирует его куда надо, но бит SPIRBF не сбрасывается.
Алексей вне форума   Ответить с цитированием
Старый 26.05.2007, 00:29   #5
Алексей
Senior Member
 
Регистрация: 25.02.2007
Сообщений: 465
Вес репутации: 578/59
Алексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to allАлексей is a name known to all
По умолчанию Re: PIC24 и DMA, только пассивное чтение?

Отбой. Заработало!!!
И вроде бы ничего не менял...
Алексей вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +3, время: 11:46.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot