• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

TLSR8253 SPI

aloika

Active member
Понадобился SPI на TLSR8253. И что-то я понять не могу: неужели невозможно одновременно читать и писать? Как так?

Попытался что-то такое изобразить:

C:
void spi_transfer(unsigned char *Data_in, unsigned char *Data_out, int DataLen, GPIO_PinTypeDef CSPin)
{
    gpio_write(CSPin,0); //CS level is low
    reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; ////0x09- bit2 enables spi data output
    reg_spi_ctrl |= FLD_SPI_RD; //enable read,0x09-bit3 : 0 for read ,1 for write

    /***transfer data***/
    for (int i = 0; i < DataLen; i++) {
        reg_spi_data = Data_out[i];
        Data_in[i] = reg_spi_data;
        while(reg_spi_ctrl& FLD_SPI_BUSY );//wait transfer finished

    }

    gpio_write(CSPin,1);//CS level is high
}
Не работает, конечно, на выходе то же, что и на входе. А как делать-то? В примерах отдельно чтение, отдельно - запись. Хотя написано в даташите: SPI is a high speed, full duplex and synchronous communication bus...
Неужели ногодрыгом SPI городить? Как-то совсем грустно.
 

A_D

Active member
А может быть чтение из регистра надо перенести после завершения транзакции? (поменять местами строки
Data_in = reg_spi_data; и
while(reg_spi_ctrl& FLD_SPI_BUSY );)
 

pvvx

Активный участник сообщества
Это по тому, что TLSR кроме duplex умеет работать по одной линии данных SPI - по выбору: DO и DI.

Адрес 0x09 бит[0] предназначен для управления линией CS: когда бит установлен в 1, уровень CS высокий; когда бит очищен, уровень CS низкий.
Адрес 0x09 бит[2] является битом отключения для вывода SPI Master. Когда бит очищен, MCU записывает данные в адрес 0x08, затем вывод SPI_DO выводит данные побитно в течение 8 тактов, генерируемых выводом SPI_CK. Когда бит установлен на 1b’1, выход SPI_DO отключен.
Адрес 0x09 бит[3] является разрешающим битом для функции чтения данных SPI Master. Когда бит установлен на 1b’1, MCU считывает данные с адреса 0x08, затем входные данные с вывода SPI_DI сдвигаются на адрес 0x08 в течение 8 тактов, генерируемых выводом SPI_CK. Когда бит сброшен, функция чтения SPI Master отключена.
Адрес 0x09[5] является разрешающим битом для режима совместного использования, то есть, используют ли SPI_DI и SPI_DO одну общую линию.
 

aloika

Active member
А может быть чтение из регистра надо перенести после завершения транзакции? (поменять местами строки
Data_in = reg_spi_data; и
while(reg_spi_ctrl& FLD_SPI_BUSY );)
Не, не работает. Я уж по-всякому пробовал. Если читать из регистра или писать в регистр - автоматически 8 кликов генерируется на SCK. Т.е. он сначала пишет, ждет, а потом, когда читает, снова генерирует 8 кликов.
 

aloika

Active member
Это по тому, что TLSR кроме duplex умеет работать по одной линии данных SPI - по выбору: DO и DI.

Адрес 0x09 бит[0] предназначен для управления линией CS: когда бит установлен в 1, уровень CS высокий; когда бит очищен, уровень CS низкий.
Адрес 0x09 бит[2] является битом отключения для вывода SPI Master. Когда бит очищен, MCU записывает данные в адрес 0x08, затем вывод SPI_DO выводит данные побитно в течение 8 тактов, генерируемых выводом SPI_CK. Когда бит установлен на 1b’1, выход SPI_DO отключен.
Адрес 0x09 бит[3] является разрешающим битом для функции чтения данных SPI Master. Когда бит установлен на 1b’1, MCU считывает данные с адреса 0x08, затем входные данные с вывода SPI_DI сдвигаются на адрес 0x08 в течение 8 тактов, генерируемых выводом SPI_CK. Когда бит сброшен, функция чтения SPI Master отключена.
Адрес 0x09[5] является разрешающим битом для режима совместного использования, то есть, используют ли SPI_DI и SPI_DO одну общую линию.
Это я всё читал. Но пока не могу сообразить, как читать и писать байт одновременно, за 8 кликов SCK. И можно ли так вообще.
 

pvvx

Активный участник сообщества
C:
void spi_transfer(unsigned char *Data_in, unsigned char *Data_out, int DataLen, GPIO_PinTypeDef CSPin)
{
    gpio_write(CSPin,0); //CS level is low
    reg_spi_ctrl &= ~FLD_SPI_DATA_OUT_DIS; ////0x09- bit2 enables spi data output
    reg_spi_ctrl &= ~FLD_SPI_RD; //enable write,0x09-bit3 : 0 for read ,1 for write

    /***transfer data***/
    for (int i = 0; i < DataLen; i++) {
        reg_spi_data = Data_out[i];
        while(reg_spi_ctrl& FLD_SPI_BUSY );//wait transfer finished
        Data_in[i] = reg_spi_data;
    }

    gpio_write(CSPin,1); //CS level is high
}
 

pvvx

Активный участник сообщества
Лучше подскажи, что нужно исправить в SDK, чтобы при connect в LowPower режимах не сбивалась связь, когда работает прерывание от GPIO с пробуждением:
C:
bls_pm_setSuspendMask(SUSPEND_ADV | DEEPSLEEP_RETENTION_ADV | SUSPEND_CONN| DEEPSLEEP_RETENTION_CONN);
cpu_set_gpio_wakeup(GPIO_RDS, get_rds_input()? Level_Low : Level_High, 1);  // pad wakeup deepsleep enable
bls_pm_setWakeupSource(PM_WAKEUP_PAD | PM_WAKEUP_TIMER);  // gpio pad wakeup suspend/deepsleep
В дровах RF через какое-то время нарушается тайминг или ещё что-то – TLSR825x просто тупит и ничего не делает, кроме пробуждений по GPIO и засыпаний. Не передает и не принимает RF. И так пока не кончатся на долгий период изменения на GPIO. А если уровень на GPIO меняетсяи вызывает просыпания-засыпания, к примеру, раз в пару сек, то так и будет RF часть тупить в молчаливом состоянии, не выдавая ни киках событий... Скорее всего счетчик таймера переполняется, но это уже после неизвестного сбоя.
 

aloika

Active member
Про SPI - кажется, работает, спасибо! Пока второго девайса нет, точно сказать сложно, но по крайней мере корректно реагирует на замыкание на GND - начинает выдавать 0x00 и на подтяжку к плюсу - выдает 0xFF.

В дровах RF через какое-то время нарушается тайминг или ещё что-то – TLSR825x просто тупит и ничего не делает, кроме пробуждений по GPIO и засыпаний. Не передает и не принимает RF. И так пока не кончатся на долгий период изменения на GPIO. А если уровень на GPIO меняетсяи вызывает просыпания-засыпания, к примеру, раз в пару сек, то так и будет RF часть тупить в молчаливом состоянии, не выдавая ни киках событий... Скорее всего счетчик таймера переполняется, но это уже после неизвестного сбоя.
С таким я не сталкивался, но у меня и нет частого просыпания/засыпания. По GPIO (нажатию на кнопку) девайс (пульт управления) просыпается на 10 сек, загорается подсветка экрана и т.д. Если не было нажатий в течение этого времени - пульт засыпает, подсветка гаснет, связь держится нормально, ничего плохого не замечал. Так что пока не могу подсказать...
 

pvvx

Активный участник сообщества
С таким я не сталкивался, но у меня и нет частого просыпания/засыпания. По GPIO (нажатию на кнопку) девайс (пульт управления) просыпается на 10 сек, загорается подсветка экрана и т.д. Если не было нажатий в течение этого времени - пульт засыпает, подсветка гаснет, связь держится нормально, ничего плохого не замечал. Так что пока не могу подсказать...
Это не кнопка, а геркон или контакт, к примеру от счетчика воды или чего другого.
Или датчик открытия двери-окна. Малая модификация термометров за 250 руб с CR2032 и типа - впаять геркон, а не покупать за более 1 тыс.руб спец. датчик открытия двери-окна.
Работает, считает импульсы и передает, и при более 50 импульсов в сек, но только в режиме рекламы, а при соединении пакостит.
 

pvvx

Активный участник сообщества
Пока второго девайса нет, точно сказать сложно, но по крайней мере корректно реагирует на замыкание на GND - начинает выдавать 0x00 и на подтяжку к плюсу - выдает 0xFF.
А при соединении DO-DI получает свои переданные данные.
 
Сверху Снизу