• Система автоматизации с открытым исходным кодом на базе 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 получает свои переданные данные.
 
Сверху Снизу