RS-485 на AVR32

Как известно, в своих новых микроконтроллерных разработках КБ 13 отказалось от старой проверенной АтМеги в пользу гипернанотехнологичных процессоров AVR32.

В процессе работы с этими процессорами, мы столкнулись с различными багами. Что, в принципе, неудивительно при плотном общении с любой «новинкой»…

Один из багов был связан с usart в режиме rs-485.

Никак не хотел передаваться большой объем информации. Нормально уходило только примерно байт 50… Больше — начинался всякий мусор и глюки.

Функция передачи у нас была такая:

/* 'send_command' - отправка буфера по усарту
 *
 */
int ain16_send_command(unsigned char * string, int nbytes)
{
	int i=0;
	int c=0;
	int timeout = 0;

	while(i

При этом сам usart инициализировался так:

usart_options_t USART_OPTIONS =
{
    .baudrate     = 115200,
    .charlength   = 8,
    .paritytype   = USART_NO_PARITY,
    .stopbits     = USART_1_STOPBIT,
    .channelmode  = USART_NORMAL_CHMODE
};

gpio_map_t USART_GPIO_MAP =
{
	{ USART_RX_PIN, USART_RX_FUNCTION },
	{ USART_TX_PIN, USART_TX_FUNCTION },
	{ USART_RTS_PIN, USART_RTS_FUNCTION }
};

...
// main()
{
           gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0]));
	usart_init_rs485(&AVR32_USART1, &USART_OPTIONS, APPLI_PBA_SPEED);
}

Стали тыкать осциллографом по ножкам данных и RTS.
И увидели, странное весьма поведение RTSа - он падал раньше, чем надо. Не то что не выдерживал паузу после передачи последнего байта, но и, бывало, обрубал передачу вообще чуть ли не посередине.
Причем, зачастую вместо нормального резкого падения уровень RTSа падал долго и плавно - что приводило к подвисанию процессора.

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

Переписали инициализацию:

gpio_map_t USART_GPIO_MAP =
{
	{ USART_RX_PIN, USART_RX_FUNCTION },
	{ USART_TX_PIN, USART_TX_FUNCTION }
};

...
// main()
{
	AVR32_GPIO.port[0].ovrs  = 0x00000100;
	AVR32_GPIO.port[0].oders = 0x00000100;
	AVR32_GPIO.port[0].gpers = 0x00000100;

           gpio_enable_module(USART_GPIO_MAP, sizeof(USART_GPIO_MAP) / sizeof(USART_GPIO_MAP[0]));
	usart_init_rs232(&AVR32_USART1, &USART_OPTIONS, APPLI_PBA_SPEED);
}

И добавили кое-что в функцию отправки

/* 'send_command' - отправка буфера по усарту
 *
 */
int ain16_send_command(unsigned char * string, int nbytes)
{
	int i=0;
	int c=0;
	int timeout = 0;


	(&AVR32_USART1)->cr = AVR32_USART_CR_RXDIS_MASK;
	cpu_delay_cy(1000, APPLI_CPU_SPEED);
	PIN_ON(USART_RTS);
	cpu_delay_cy(1000, APPLI_CPU_SPEED);

	while(icr = AVR32_USART_CR_RXEN_MASK;
	cpu_delay_cy(1000, APPLI_CPU_SPEED);


	return (i+1);
}

На этом usart, инициализированный в режиме 232-го, превратился в нормально работающий rs-485.

Похожий бред:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Protected by WP Anti Spam