Перейти к содержанию
    

Не стартует DMA в LPC2148.

Передача организована в bulk режиме. Без использования DMA все передается нормально. При инициализации DMA ошибок не выдает, но переходит в IDLE MODE и ничего не отсылает. Использую кейловский стек, драйвер генерировал в DriverStudio 2.7.

 

Dd.BufAdr = (DWORD)DataBuf;

Dd.BufLen = 512;

Dd.MaxSize = USB_MAX_PACKET0; // 64 байта

Dd.Cfg.Val = 0;

USB_DMA_Setup (USB_ENDPOINT_IN(5), &Dd))

USB_DMA_Enable(USB_ENDPOINT_IN(5));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Без ДМА работает и прием и передача, а при настройке ДМА на передачу в хост, передача не стартует. Прием работает без изменений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как я понимаю даташитом ты вооружен. У меня была такая же проблема. Посмотри команду

Set Mode (Command: 0xF3, Data: write 1 byte)

Бит 5 INAK_BI Interrupt on NAK for Bulk IN endpoints:

0 Only successful transactions generate an interrupt.

1 Both successful and NAKed IN transactions generate interrupts.

 

Поставь этот бит в единицу и попробуй.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как я понимаю даташитом ты вооружен. У меня была такая же проблема. Посмотри команду

Set Mode (Command: 0xF3, Data: write 1 byte)

Бит 5 INAK_BI Interrupt on NAK for Bulk IN endpoints:

0 Only successful transactions generate an interrupt.

1 Both successful and NAKed IN transactions generate interrupts.

 

Поставь этот бит в единицу и попробуй.

 

Попробовал. Теперь контроллер выходит в прерывание по конечной точке с сообщением DMA IN EP - Error. В даташите сказано, что эта ошибка возникает в случаи неправильного дескриптора ДМА.

Скажите, правильно ли я его инициализировал?

 

Dd.BufAdr = (DWORD)DataBuf;

Dd.BufLen = 512;

Dd.MaxSize = USB_MAX_PACKET0; // 64 байта

Dd.Cfg.Val = 0;

USB_DMA_Setup (USB_ENDPOINT_IN(5), &Dd))

USB_DMA_Enable(USB_ENDPOINT_IN(5));

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так как я не знаю какое описание структуры у тебя, то я лучше покажу как у меня:

 

typedef __packed struct _USB_DMA_DESCRIPTOR

{

void* next_dd; // Указатель на следующий DMA дескриптор

__packed union

{ // DMA конфигурация

__packed struct

{

WORD atle : 1; // Включение режима ATLE (Auto Transfer Length Extract)

WORD reserved1 : 1; // Зарезервировано

WORD link : 1; // Указатель на следующий DMA дескриптор правильный

WORD reserved2 : 1; // Зарезервировано

WORD isochronous : 1; // Признак изохронной передачи

WORD max_packet_size : 11; // Максимальный размер пакета

} bit;

WORD value;

} dd_config;

WORD dma_buffer_length; // Размер DMA буфера

BYTE* dma_buffer; // Указатель на DMA буфер

__packed union

{ // Статус DMA дескриптора

__packed struct

{

WORD retired : 1; // Обработка дескриптора закончена

WORD status : 4; // Текущий статус обработки дескриптора

WORD packet_valid : 1; // Последний переданный пакет обработан без ошибок

WORD ls_byte_extracted : 1; // Младший байт из dma_buffer_length выбран (только для ATLE режима)

WORD ms_byte_extracted : 1; // Старший байт из dma_buffer_length выбран (только для ATLE режима)

WORD position : 6; // Позиция внутри пакета (только для ATLE режима)

WORD reserved : 2; // Зарезервировано

} bit;

WORD value;

} dd_status;

WORD present_count; // Текущее количество переданных байт

} USB_DMA_DESCRIPTOR, *PUSB_DMA_DESCRIPTOR;

 

void dd_init(PUSB_DMA_DESCRIPTOR _dd)

{

_dd->dd.next_dd=0;

_dd->dd.dd_config.value=0;

_dd->dd.dd_config.bit.max_packet_size=64;

_dd->dd.dma_buffer=buffer_pointer;

_dd->dd.dma_buffer_length=DMABUFFER_SIZE;

_dd->dd.dd_status.value=0;

_dd->dd.present_count=0;

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так как я не знаю какое описание структуры у тебя, то я лучше покажу как у меня:

 

void dd_init(PUSB_DMA_DESCRIPTOR _dd)

{

_dd->dd.next_dd=0;

_dd->dd.dd_config.value=0;

_dd->dd.dd_config.bit.max_packet_size=64;

_dd->dd.dma_buffer=buffer_pointer;

_dd->dd.dma_buffer_length=DMABUFFER_SIZE;

_dd->dd.dd_status.value=0;

_dd->dd.present_count=0;

}

 

у меня все так же.

Скажите, а чему у вас равен buffer_pointer. Т.е. передаваемый буфер должен находиться в какой-то определенной области памяти, или нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну конечно буфер должен располагаться в USB_RAM

 

// Определения для USB RAM

#define USB_RAM_ADDR 0x7FD00000 // Стартовый адрес USB RAM

#define USB_RAM_SIZE 0x00002000 // Размер USB RAM (8kB)

 

Собственно как и сам дескриптор тоже должен быть в этой области

Изменено пользователем 3m-soft

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну конечно буфер должен располагаться в USB_RAM

 

// Определения для USB RAM

#define USB_RAM_ADDR 0x7FD00000 // Стартовый адрес USB RAM

#define USB_RAM_SIZE 0x00002000 // Размер USB RAM (8kB)

 

Собственно как и сам дескриптор тоже должен быть в этой области

 

 

У меня буфер обявлен вот так:

#pragma arm section zidata = "USB_RAM"

//DWORD InfoBuf[P_C]; /* Packet Info Buffer */

unsigned char DataBuf[b_S]; /* Data Buffer */

#pragma arm section zidata

 

но DataBuf все равно лежит по адресу 0х40000000, я не нашел нигде ссылки на значение USB_RAM. Как указать линкеру нужный адрес?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Файл: Project.sct

 

; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************

 

LR_IROM1 0x00000000 0x00080000 { ; load region

ER_IROM1 0x00000000 { ; load address = execution address

*.o (RESET, +First)

* (+RO)

}

RW_IRAM1 0x40000000 0x00008000 { ; RW data

* (+RW +ZI)

}

RW_USBRAM 0x7FD00000 0x00002000 {

*.o (USB_RAM)

}

}

 

А это например в проге:

 

#pragma arm section zidata="USB_RAM"

PUSB_DMA_DESCRIPTOR UDCA[uSB_EP_COUNT]; // Массив указателей на DMA дескрипторы для всех (32) конечных точек

BYTE dma_buffer[DMABUFFER_SIZE];

USB_DMA_DESCRIPTOR in_dd;

#pragma arm section zidata

Изменено пользователем 3m-soft

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Файл: Project.sct

 

; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************

 

LR_IROM1 0x00000000 0x00080000 { ; load region

ER_IROM1 0x00000000 { ; load address = execution address

*.o (RESET, +First)

* (+RO)

}

RW_IRAM1 0x40000000 0x00008000 { ; RW data

* (+RW +ZI)

}

RW_USBRAM 0x7FD00000 0x00002000 {

*.o (USB_RAM)

}

}

 

А это например в проге:

 

#pragma arm section zidata="USB_RAM"

PUSB_DMA_DESCRIPTOR UDCA[uSB_EP_COUNT]; // Массив указателей на DMA дескрипторы для всех (32) конечных точек

BYTE dma_buffer[DMABUFFER_SIZE];

USB_DMA_DESCRIPTOR in_dd;

#pragma arm section zidata

 

Все заработало. Спасибо за ценные советы. :a14:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

После настройки и разрешения ДМА вылетает в прерывание со значением NDD_REQ_INT (запрос на новый дескриптор), хотя ни один байт не отправлен.

В ДШ что-то упоминалось про двойной буфер для Bulk режима (мой случай) но что-то не понятно там ка-то написано про него. Других причин я пока не нахожу. Если кто что знает, отпишите плз.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как я понимаю даташитом ты вооружен. У меня была такая же проблема. Посмотри команду

(Command: 0xF3, Data: write 1 byte)

Бит 5 INAK_BI Interrupt on NAK for Bulk IN endpoints:

0 Only successful transactions generate an interrupt.

1 Both successful and NAKed IN transactions generate interrupts.

 

Поставь этот бит в единицу и попробуй.

 

Добрый вечер! У меня та же проблема. Прописывал команду Set Mode в разных местах,

но прерывания на NAKed IN так и не получил. Подскажите, пожалуйста, как и где прописать эту Set Mode (Command: 0xF3, Data: write 1 byte)? В USB_Init(), USB_Connect() или где-то ещё?

Буду очень благодарен, если приведёте фрагмент кода. :help:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...