Все доброго времени суток!
Встала задача воспроизводить (заранее записанную на внешнюю МС памяти с SPI-интерфейсом) речь на МК XMEGA. Оцифровка 16 бит Х 16 кГц Х моно.
Решил воплотить задачу используя DMA. Накидал программку, прогнал в AVRStudio 4 - вроде все работает... Но, блин что то не очень нравится собственное решение. Опишу алгоритм.
1. В качестве последовательного интерфейса для DataFlash используется один из USART в режиме MASTER SPI. Перед началом воспроизведения программно пишется команда чтения со всеми нужными атрибутами.
2. Для чтения сэмпла использую таймер с частотой переполнения 32 кГц.
3. Для инициализации передачи по SPI использую канал DMA (назовем его A). Канал стартует по переполнению таймера в режиме SIngleShort. Т.е. одно переполнение - трансфер одного байта в DATA регистр USART.
В счетчик канала, перед началом воспроизведения, пишется количество байт воспроизводимого файла. В качестве источника данных используется байт в памяти данных, в который записано нулевое значение. Прерывание окончания передачи разрешено.
4. Для передачи байта из регистра DATA USART в регистр данных DAC использую второй канал DMA (Назовем его В). В счетчике данных канала всегда 2, включен режим повтора, счетчик повторов равен 0, т.е. неограниченное число повторов. Адрес источника - регистра DATA USART - фиксированый, Адрес приемника - регистр DATA канала DAC, адрес инкрементируется, обновляется после передачи блока данных (2 байт). Прерывание окончания передачи запрещено.
Прерывания:
1. По переполнению таймера - только для того, чтобы снять флаг прерывания. Если это прерывание не разрешить, то канал DMA А пуляет ноль в USART без остановки! Это и понятно - флаг прерывания по переполнению не обнуляется.
2. Прерывание по окончанию передачи по каналу DMA A - нужно, чтобы разрешить прерывание от последней передачи канала DMA B.
3. Прерывание по окончанию передачи канала DMA B. Останавливает таймер, запрещает работу обеих каналов DMA, вызывает CallBack-функцию, которая генерирует команду чтения следующего файла либо останавливает полностью воспроизведение.
Во всей этой схеме не нравится три прерывания, особенно первое - от таймера. Может есть более изящные способы, чем мой?
Рад любым высказываниям. Спасибо!