Думаю будет больно слышать тем, кто их регулярно использует и любит данное семейство, но тем не менее есть объективная реальность на мой взгляд.
Кто-то захочет начать, я скажу что совсем недоволен результатом. Некоторые хомуты не укладываются у меня в голове. И при этом я работаю с 6 семейством! Просто диву даюсь с ребят TI.
Перечислю вещи которые на меня произвели неизгладимое впечатление.
1. Если по какой-то причине не сброшен флаг в прерывании, то МК зацикливается на данном прерывании. При чём зацикливается накоротко. То есть при этом он вообще не выполняет ни одной команды головы. Учитывая, что способ сброса флага абсолютно не расписан - вызвало у меня головную боль. В частности есть IV регистр. Было бы логичным сбрасывать флаг там и где-то именно так и происходит, но для SD24B надо прочитать регистр данных. (
2. В таймере при захвате не сбрасывается регистр счёта. Но ведь сброс вручную приводит к очевидной ошибке.
3. При останове процессора родным отладчиком может с периферией может происходить что угодно. Например по первому прерыванию USART вижу последний байт пакета или таймер показывает полную чушь и самое главное при продолжении работает не так, как положено. И так далее.
4. Значительные несоответствия в разных документах. Например в UM на семейство, для таймера обозначаются входы как CCIxA и CCIxB. И ссылаются на документ на конкретный камень. В нём же эти входы обозначены как TAx.0/ TAx.1. В UM описано 4 типа таймеров. В UM на камень с трудом докапываешься какой именно применён. Отличаются объявления в хидерах и документации. Ошибки в целом незначительные и мне сразу понятные, но начинающему, я уверен будет непросто.
5. В целом уровень периферии на порядок слабее аналогичных у других производителей, таких как ST, NXP.
===
Теперь по существу вопроса.
Приём заработал сразу и без вопросов.
Передачу хотел реализовать по DMA.
Инициализирую так.
Код
// Передать буфер
void vUSARTTransmit(void)
{
LTX_ON; // светодиод TX зажечь
USART_WR; // Перейти на передачу
DMACTL0 = DMA0TSEL__USCIA0TX; // UCA0TXIFG на канал 0
DMA0CTL = DMADT2 | DMASRCINCR0 | DMASRCINCR1 |
DMADSTBYTE | DMASRCBYTE | DMAIE; // +1 на источнике, побайтно, прерывание
DMA0SZ = mbcom.len; // длина
DMA0SA = mbcom.buf; // Источник
DMA0DA = (void*)&UCA0TXBUF; // Получатель
//DMAIV; // Сбросить флаги
DMA0CTL |= DMAEN; // Начать
}
void vUSARTTransmit(void)
{
LTX_ON; // светодиод TX зажечь
USART_WR; // Перейти на передачу
DMACTL0 = DMA0TSEL__USCIA0TX; // UCA0TXIFG на канал 0
DMA0CTL = DMADT2 | DMASRCINCR0 | DMASRCINCR1 |
DMADSTBYTE | DMASRCBYTE | DMAIE; // +1 на источнике, побайтно, прерывание
DMA0SZ = mbcom.len; // длина
DMA0SA = mbcom.buf; // Источник
DMA0DA = (void*)&UCA0TXBUF; // Получатель
//DMAIV; // Сбросить флаги
DMA0CTL |= DMAEN; // Начать
}
Что-то передача не начинается. (
ЗЫ: Похоже догадался, исходя из "When selecting the trigger, the trigger must not have already occurred, or the transfer does not take place".
Подтвердилось.
Соответственно процедура должна выглядеть примерно так:
Код
// Передать буфер
void vUSARTTransmit(void)
{
LTX_ON; // светодиод TX зажечь
USART_WR; // Перейти на передачу
DMACTL0 = DMA0TSEL__USCIA0TX; // UCA0TXIFG на канал 0
DMA0CTL = DMADT2 | DMASRCINCR0 | DMASRCINCR1 |
DMADSTBYTE | DMASRCBYTE | DMAIE; // +1 на источнике, побайтно, прерывание
DMA0SZ = mbcom.len-1; // длина
DMA0SA = &mbcom.buf[1]; // Источник
DMA0DA = (void*)&UCA0TXBUF; // Получатель
//DMAIV; // Сбросить флаги
DMA0CTL |= DMAEN; // Начать
UCA0TXBUF = mbcom.buf[0];
}
void vUSARTTransmit(void)
{
LTX_ON; // светодиод TX зажечь
USART_WR; // Перейти на передачу
DMACTL0 = DMA0TSEL__USCIA0TX; // UCA0TXIFG на канал 0
DMA0CTL = DMADT2 | DMASRCINCR0 | DMASRCINCR1 |
DMADSTBYTE | DMASRCBYTE | DMAIE; // +1 на источнике, побайтно, прерывание
DMA0SZ = mbcom.len-1; // длина
DMA0SA = &mbcom.buf[1]; // Источник
DMA0DA = (void*)&UCA0TXBUF; // Получатель
//DMAIV; // Сбросить флаги
DMA0CTL |= DMAEN; // Начать
UCA0TXBUF = mbcom.buf[0];
}