Rasberry PI PICO (RP2040) продолжение темы

Получил RP2350, попробовал на ней пару своих проектов, написанных под 2040 - все компилируется и, даже, работает.
Вопрос - они что, абсолютно совместимы по коду? Разница только в частоте ядра?

Закралась мысль - может это просто перемаркировка, а прислали обычную 2040 ? :slight_smile:

Если ты выбрал rp2040, а залил в rp2350, то да, совместимы. Но я сильно подозреваю, что ты выбрал правильный чип, а дальше - дело за аддоном ))

я, конечно, выбрал 2350. И залил в 2350 :slight_smile: Но все равно удивительно :slight_smile:

Чего вдруг? Принцип Ардуино - переносимость кода ))

Ну да…
Хотя я в проекте активно использую PIO. а в нем никакого “ардуино-стайл” нет.

Может по PIO оно и совместимо, даташиты смотреть нужно )

опять самому? А форум тогда зачем? :slight_smile:

Хм, мысль пришла - а почему в СДК Пико никто не обернул объект PIO state_machine в класс? Ведь это же логично…

Было бы в разы удобнее отслеживать все эти офсеты, конфиги, делители частоты и назначенные пины… особенно когда в проекте этих машин становится много…

Или я все пропустил и такой класс давно есть?

видимо, накладные расходы. Использование PIO всё-же подразумевает максимальную скорость

Это никак не скажется. Сама машина работает на ассемблере. Она так и продолжит работать.
Я имею в виду начальную настройку, все эти бесконечные строчки типа

uint sm = pio_claim_unused_sm(pio, true);
uint offset = pio_add_dmd_lat_program(pio);
pio_sm_config c = dmd_mux_program_get_default_config(offset);
pio_sm_set_consecutive_pindirs(pio, sm, outBase, outCnt, true);  // 5 mux pins
    for (int i = outBase; i < outBase+outCnt; i++) {
        pio_gpio_init(pio, i);
    }
sm_config_set_out_pins(&c, outBase, outCnt);
sm_config_set_clkdiv(&c, 2);
sm_config_set_out_shift(&c, true, false, 32);
sm_config_set_in_shift(&c, false, false, 32);
pio_sm_init(pio, sm, offset, &c);
pio_sm_exec(pio, sm, offset );
pio_sm_set_enabled(pio, sm, true);

почти в каждой из которых повторяются параметры пио машины pio, sm, offset

Видимо были на то причины.

Коллеги, кто-нибудь может подтвердить или опровергнуть тот странный факт, что результат операции pio_sm_is_tx_fifo_empty() становится true уже при вычитывании из буфера предпоследнего слова, а не последнего?
Хотел использовать эту функцию для проверки, что машина завершила работу - и фигвам, сигнал подается раньше! И как с этим бороться?

Думаю выкатить issue на гитхабе Пико-Ардуино проекта Эрла Филхофера, но сначала решил спросить, может кто знает причину?

Какой код демонстрирующий ошибку будете прикладывать к issue?

ПС. Наверно вы знаете, но на всякий случай. Если машина завершила работу по пустоте TX, то для сообщения об этом есть флаг TXSTALL

так это тоже самое.
Насколько я знаю, pio_sm_is_tx_fifo_empty() эти флаги и проверяет

ЗЫ
Код, конечно, будет.
Если интересно, сюда тоже могу выложить.

В общем, разобрался. Бага нет, issue создавать незачем.
Оказалось, что я пытался применить pio_sm_is_tx_fifo_empty() не для того, для чего он предназначен.

Буквально, как написано в первом посте

и натурально, ничего не вышло. Сигнал-то подается в момент, когда программа только начинает обрабатывать последний блок данных из очереди.

картинка для иллюстрации


Красный треугольник сверху - предполагаемое появление сигнала. Черный - реальное.

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

Известная хрень. MODBUS глючит когда пытаешься поймать конец пакета. Решение было после прихода прерывания переключать с задержкой, что бы аппаратный порт успел всё выплюнуть.

Да, Вы правы. Огромное спасибо.

Действительно, флаг TXSTAIL это не то же самое, как TXEMPTY. Правда, готового метода для его отслеживания я в SDK не нашел, пришлось написать свой по аналогии с pio_sm_is_tx_fifo_empty() :slight_smile:

bool pio_sm_is_tx_fifo_stall(PIO pio, uint sm) {
    check_pio_param(pio);
    check_sm_param(sm);
    return (pio->fdebug & (1u << (PIO_FDEBUG_TXSTALL_LSB + sm))) != 0;
}

C этим флагом отрабатывает строго когда надо:

для MMM

вот тут, применительно к организации дополнительного Serial с помощью PIO, все что надо обернули во внешнюю удобную оболочку,

но немного слукавили - не указали явно важные параметры при вызове.

Поэтому, если вам, например, нужно создать три дополнительных Serial. то это будет выглядеть так -

SoftwareSerial SoftSerial1 = SoftwareSerial(10, 11,0,1,pio0); // 10-TX 11-RX

SoftwareSerial SoftSerial2 = SoftwareSerial(12, 13,2,3,pio0); // 12-TX 13-RX

SoftwareSerial SoftSerial3 = SoftwareSerial(14, 15,0,1,pio1); // 14-TX 15-RX

Другой пример про PIO - PicoEncoder - Arduino Libraries

Эта библиотека полагает что она одна такая волшебная и начинает ,

не спрашивая, последовательно размещать в PIO один энкодер за другим, и надо точно понять, какие

ресурсы она заняла.

Работу этих библиотек в RP2350 не проверял, они заявлены для RP2040

Спасибо за отклик, но толи вы не поняли, о чем я спрашивал, толи я не понял вашего ответа. На мой взгляд этот проект ни имеет ничего общего с моим вопросом.
В какую “удобную оболочку” тут что-то обернули? - стандартный код для ПИО

Опять не понял, о чем вы. С учетом того, что длина кода этой программы энкодера ровно 32 шага (размер памяти ПИО) , никаких “один за другим” тут быть не может.

Раз уж вылез

@Upper
К сожалению, радостный отчет из сообщения 717 оказался преждевременным…
Пришел домой, запустил тот же код, что днем, на свежей версии Pico_SDK - и не работает.
Такое впечатление, что флаг TXSTALL установлен всегда.
Версия аддона pico-arduino 5.4.3

Добавление - понизил версию аддона до 2.2.2 - все равно не работает! Какая-то чертовщина прям.

Ладно, видимо продолжать уже буду на свежую голову в новом году…