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

Когда нужна сотня UART’ов или примитивный драйвер для SC16IS740/SC16IS750/SC16IS760

Вот и наступил прекрасный момент, когда все доступные порты заняты, а битбэнгать как-то не сподручно. На сцену выходит микросхема-преобразователь UART в-из I2C/SPI

Есть аналоги подобных микросхем-преобразователей (MAX3107, MAX14830), которые скорей всего будут лучшим выбором, чем представленная выше. У них нет “магических” регистров доступа и FIFO длиннее. Так вышло, что под рукой была именно эта микросхема. Работа с доступом к определенным регистрам у нее очень специфичная.

Вот, например, сноски под описанием регистров из даташита:

Обратите внимание на п.п. 2, 7, 10 и 11. Такой выверт легко объяснить – под адресацию регистров микрухи разработчики заложили только 1 байт (16 адресов), а их понадобилось чуть больше.

Интересные дизайн-решения для этой микрухи были отмечены и разработчиками драйвера под Линукс:

Один неприятный момент заключается в том, что у микросхемы нет регистра с уникальным ID. Но зато у нее есть два регистра доступные для записи кастомных значений (Scratchpad Register (SPR)). Этот момент позволит нам определить – жива ли вообще микросхема на линии (если не доверять ASK по адресу)

А возможных адресов микросхемы целая коробка:

То есть, на один интерфейс I2C можно посадить до 16 UART’ов (если не брать в расчет расширители I2C). Да, достаточно низкоскоростных, но, вполне функциональных. При подключении по SPI, мы вообще ограничены только количеством ножек под CS (если не брать в расчет расширители портов)

Для работы с этой микрухой была написана примитивная, портируемая библиотека на голом Си.

Если FIFO не используется надо закомментить это в коллбэк-функции:

    	//fifo_len = SC16_read_register(SC16IS7XX_RXLVL);
    	//while (fifo_len--){
    		data = SC16_RX();
    		get_data(data);
    	//}

По-умолчанию, включен FIFO, прерывания на RX линии и классические 8 бит, без четности и 1 стоп-бит. Эти настройки можно изменить тут (или дописать свои функции):

SC16_write_register(SC16IS7XX_FCR,  0x01);   //enable fifo
SC16_write_register(SC16IS7XX_IER,  0x05);  //enable Rx data ready, lsi interrupt
SC16_write_register(SC16IS7XX_LCR, 0x03); // 8 data bit, no parity (add "| SC16_2STOPBITS" to 2-stopbits support)

Если не использовать прерывания, то можно бесконечно опрашивать этой функцией

uint8_t SC16_is_data_aval(void)

Если нужно опрашивать/писать_в много таких микрух (действительно нужна сотня) на одной линии с разными адресами, то стоит подумать над созданием структуры объекта микросхемы расширителя, указатель на который можно будет передавать как параметр каждой функции.

Comment

programel