Значит, наблюдения такие.
Опыт 1.
Настраиваю модуль на автоматический переход в IDLE после приема пакета, и опрашиваю его вот так. Сори за магические числа, пока нет времени все задефайнить нормально, ну я думаю для тех, кто работал с модулем, всё более-менее наглядно и так.
Код
while(1)
{
while(!(GDO_GPIO->IDR & GDO0_Pin));
cc1101_read_burst_fifo(dat, WIRELESS_DATA_BYTES_PER_PARCEL);
cc1101_command_strobe(CC1100_SFRX);
cc1101_command_strobe(CC1100_SRX);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D);
}
{
while(!(GDO_GPIO->IDR & GDO0_Pin));
cc1101_read_burst_fifo(dat, WIRELESS_DATA_BYTES_PER_PARCEL);
cc1101_command_strobe(CC1100_SFRX);
cc1101_command_strobe(CC1100_SRX);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D);
}
... и сталкиваюсь с тем, что если два передатчика синхронно шлют пакет, прием "зависает". Подключаюсь отладчиком, смотрю - висит в цикле опроса GDO0. Ломал два часа голову, пока не догадался посмотреть статус cc1101 в бесконечном цикле, а она - в IDLE. Какого-то черта после того, как она уже гарантированно переключилась в RX, в конце большого цикла, опять оказывается в IDLE, причем без дерганья GDO.
Опыт 2.
Ставлю костыль
Код
while(1)
{
while(!(GDO_GPIO->IDR & GDO0_Pin))
{
if((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D)
{
cc1101_command_strobe(CC1100_SRX);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D);
}
vTaskDelay(5);
}
cc1101_read_burst_fifo(dat, WIRELESS_DATA_BYTES_PER_PARCEL);
cc1101_command_strobe(CC1100_SFRX);
cc1101_command_strobe(CC1100_SRX);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D);
}
{
while(!(GDO_GPIO->IDR & GDO0_Pin))
{
if((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D)
{
cc1101_command_strobe(CC1100_SRX);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D);
}
vTaskDelay(5);
}
cc1101_read_burst_fifo(dat, WIRELESS_DATA_BYTES_PER_PARCEL);
cc1101_command_strobe(CC1100_SFRX);
cc1101_command_strobe(CC1100_SRX);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D);
}
... и "все работает", не считая того, что я чешу репу в недоумении, а по spi идет мусорный обмен каждые 5мс, плюс на 5мс уменьшилась отзывчивость.
Опыт 3.
Отключаю автоматический переход в idle после приема пакета, и делаю это ручками.
Код
while(1)
{
while(!(GDO_GPIO->IDR & GDO0_Pin));
cc1101_command_strobe(CC1100_SIDLE);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x01);
cc1101_read_burst_fifo(dat, WIRELESS_DATA_BYTES_PER_PARCEL);
cc1101_command_strobe(CC1100_SFRX);
cc1101_command_strobe(CC1100_SRX);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D);
}
{
while(!(GDO_GPIO->IDR & GDO0_Pin));
cc1101_command_strobe(CC1100_SIDLE);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x01);
cc1101_read_burst_fifo(dat, WIRELESS_DATA_BYTES_PER_PARCEL);
cc1101_command_strobe(CC1100_SFRX);
cc1101_command_strobe(CC1100_SRX);
while((cc1101_read_status_register(CC1100_MARCSTATE) & 0x1F) != 0x0D);
}
... и всё работает отлично.
Не пойму такое поведение сс1101, это баг или фича?