lavrik 0 10 августа, 2015 Опубликовано 10 августа, 2015 (изменено) · Жалоба Форумчане, нужна помощь!!! Делаю по работе программатор на ATmega128 для той же самой ATmega. C одной стороны она подключена через SPI к программируемому чипу, с другой стороны к компьютеру по UART (FTDI VCP). Нужно наладить связь, грубо говоря, между программируемой ATmega и компом. В даташите раздел по ISP изучил, основные команды выписал. Сначала сделал программу, которая работает только с SPI и последовательно шлет нужные байты и в случае верного ответа программируемого чипа сообщает об этом. Работает. Но когда попытался прикрутить к этому всему комп через UART, то началась вакханалия. То ничего не приходит (истекает тайм-аут чтения com-порта), то приходит какой-то мусор, не поддающийся осмыслению. Например самая первая команда, после введения в режим ISP жертвы, это 10101100 01010011 11111111 11111111. В момент передачи третьего байта (11111111), должно придти в ответ 01010011, но в случае с участием компьютера, этот байт приходит почему-то после отсылки второго байта. :( Пишу в CVAVR. #include <mega128.h> #include <delay.h> #include <interrupt.h> char buffer_usb; char buffer_atmega; void uart1_init( void ) { // USART1 initialization // Communication Parameters: 8 Data, 1 Stop, No Parity // USART1 Receiver: On // USART1 Transmitter: On // USART1 Mode: Asynchronous // USART1 Baud Rate: 115200 UCSR1A=(0<<RXC1) | (0<<TXC1) | (0<<UDRE1) | (0<<FE1) | (0<<DOR1) | (0<<UPE1) | (1<<U2X1) | (0<<MPCM1); UCSR1B=(1<<RXCIE1) | (0<<TXCIE1) | (0<<UDRIE1) | (1<<RXEN1) | (1<<TXEN1) | (0<<UCSZ12) | (0<<RXB81) | (0<<TXB81); UCSR1C=(0<<UMSEL1) | (0<<UPM11) | (0<<UPM10) | (0<<USBS1) | (1<<UCSZ11) | (1<<UCSZ10) | (0<<UCPOL1); UBRR1H=0x00; //115200*2 UBRR1L=0x03; } void spi_init (void) { // SPI initialization // SPI Type: Master // SPI Clock Rate: 115,200 kHz *2 // SPI Clock Phase: Cycle Start // SPI Clock Polarity: Low // SPI Data Order: MSB First SPCR=(1<<SPIE) | (1<<SPE) | (0<<DORD) | (1<<MSTR) | (0<<CPOL) | (0<<CPHA) | (1<<SPR1) | (0<<SPR0); SPSR=(1<<SPI2X); } void uart_putc1( int c ) { //ждем окончания передачи предыдущего байта while( ( UCSR1A & ( 1 << UDRE1 ) ) == 0 ); UDR1 = c; } void spi_putc( char cData) { /* Start transmission */ SPDR = cData; /* Wait for transmission complete */ while(!(SPSR & (1<<SPIF))) ; } interrupt [sPI_STC] void spi_isr(void) { cli(); buffer_atmega = SPDR; sei(); } interrupt [uSART1_RXC] void usart1_rxc_isr(void) { cli(); buffer_usb=UDR1; sei(); } void main (void) { DDRE=0b01000000; //Установка PE6 "Out" - "Reset" DDRB=0b00000111; //Установка PB1 "Out" - "SCK", установка PB2 "Out" - "MOSI/PDO", PB0 - SS uart1_init(); spi_init(); /*SET ISP*/ PORTB.1=0; // Set SCK - '0' delay_ms(15); PORTE.6=1; // Set RESET delay_ms(15); PORTE.6=0; delay_ms(15); PORTB.1=1; // Set SCK - '1' sei(); while (1){ if (buffer_usb !=0) { //spi_putc(buffer_usb); SPDR = buffer_usb; buffer_usb=0; }; if (buffer_atmega != 0) {uart_putc1(buffer_atmega); buffer_atmega=0;} }; } Пытался читать SPDR в прерывании по окончании передачи - бесполезно. Если вручную это делать - выкидывает всякий мусор. Поэтому прошу помочь наладить этот самый мостик из SPI-UART, который будет вменяемо передавать данные в две стороны. P.S. вообще не думал, что будет столько проблем с этим самым мостиком, потому что перед этим делал его из двух UART, для программирования LPC2366, и там все получилось очень прилично и без косяков, а тут... Хотелось бы, чтобы результат был таким, как с двумя UART. Изменено 10 августа, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lavrik 0 11 августа, 2015 Опубликовано 11 августа, 2015 · Жалоба Очень нужна помощь Помогите кто чем может! :rolleyes: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RabidRabbit 0 11 августа, 2015 Опубликовано 11 августа, 2015 · Жалоба У Вас лишняя деталь - ATmega128. Для программирования AVR'ок по ISP вполне достаточно FTDI-чипа... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
lavrik 0 11 августа, 2015 Опубликовано 11 августа, 2015 · Жалоба У Вас лишняя деталь - ATmega128. Для программирования AVR'ок по ISP вполне достаточно FTDI-чипа... Контроллер нужен как промежуточное устройство для декодирования в будущем...Это в общем-то не имеет отношения к делу. То, что не получается реализовать - это мостик UART-SPI. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
RabidRabbit 0 11 августа, 2015 Опубликовано 11 августа, 2015 · Жалоба Я бы, в таком случае, сделал примерно так: очередь FIFO на приём из UART, в прерывании по приёму кладём туда байт в главном цикле: выбираем байт из приёмной очереди, кладём его в SPDR, ждём завершения передачи, кладём байт из SPDR в UDR и ждём появления бита UDRE. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Gorby 6 11 августа, 2015 Опубликовано 11 августа, 2015 · Жалоба Очень нужна помощь Помогите кто чем может! :rolleyes: Поэтому прошу помочь наладить этот самый мостик из SPI-UART, который будет вменяемо передавать данные в две стороны. УАРТ через ЮСБ - это не совсем УАРТ. ЮСБ - принципиально блочный интерфейс, а УАРТ - символьный. Вам нужно изменить архитектуру программирующего софта. ПК через ЮСБ->УАРТ передает Вспомогательному процессору блок данных (0.5 или 1 кБ) и команду, что с ними делать. Он отрабатывает команду, записывая блок в микросхему-таргет. Аппаратные подробности SPI никуда наверх не идут (только для индикации ошибок). Точно также и с чтением. Даем команду на чтение блока. Ждем. Потом блок вычитываем. На ПК детали SPI не видны. А если хочется прямо с ПК рулить SPI ножками, то Avreal Вам в руки. Удачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться