Спасибо прибористу за тестирование.

Собственно, лучше не скажешь:
Цитата Сообщение от приборист
Поробовал, все заработало.
Скорость на ходу изменяет.
Вечером будет побольше времени потестировать.
Шах и мат?


Собственно, программа:

Код:
PROGRAM PRU_PULSE_GENERATOR 
  variables: 
    burst : PRU_GENER_BURST; 
    enable : BOOL; 
    cycleLength : WORD; 
    quantity : DWORD; 
    ready : BOOL; 
    qtyLeft : DWORD; 
    dataReady : BOOL; 
    controlRegisterAddress : DWORD; 
    currentCycles : WORD; 
   
  body: 
    (* безопасные значения *) 
    enable := FALSE; 
    cycleLength := 100; 
    quantity := 0; 
    WHILE TRUE DO 
      (* собственно полезная работа *) 
      burst(enable := enable, quantity := quantity); 
       
      controlRegisterAddress := 16#700C;
      (* Пока есть время, передаём-принимаем данные *)
      REPEAT 
        ASM 
          LBCO dataReady, 3, 0, 1 
        END_ASM 
         
        IF dataReady THEN 
          (* Приём *) 
          ASM 
            LBCO quantity, 3, 100, 4 
            LBCO cycleLength, 3, 104, 2 
            LBCO enable, 3, 108, 1 
          END_ASM 
           
          (* Передача *) 
          ready := burst.ready; 
          ASM 
            SBCO ready, 3, 112, 1 
          END_ASM 
          qtyLeft := burst.qtyLeft; 
          ASM 
            SBCO qtyLeft, 3, 116, 4 
          END_ASM 
           
          dataReady := FALSE; 
          ASM 
            SBCO dataReady, 3, 0, 1 
          END_ASM 
        END_IF; 
         
        ASM 
          LBBO currentCycles, controlRegisterAddress, 0, 2
        END_ASM 
        currentCycles := currentCycles + 40; 
      UNTIL currentCycles < cycleLength 
      END_REPEAT; 
      (* Остаток задержки ждём более точно, без приёма-передачи *)
      WAIT_TICK(pruCycleLength := cycleLength); 
       
      PRU_OUT1(Q := burst.out); 
    END_WHILE; 
END_PROGRAM
Код:
FUNCTION_BLOCK PRU_GENER_BURST 
  variables: 
    input enable : BOOL; 
    input quantity : DWORD; 
    output out : BOOL; 
    output ready : BOOL; 
    retain output qtyLeft : DWORD; 
   
  body: 
    IF enable THEN 
      IF qtyLeft > 0 THEN 
        (* Идёт генерация *) 
        qtyLeft := qtyLeft - 1; 
      ELSIF ready THEN 
        (* Всё сгенерировали, ждём пока передёрнут enable для следующего включения *) 
      ELSE 
        (* Поступила команда на включение *) 
        qtyLeft := SHL(quantity, 1); 
        qtyLeft := qtyLeft - 1; 
      END_IF; 
      ready := qtyLeft = 0; 
    ELSE 
      (* Выключаемся *) 
      qtyLeft := 0; 
      ready := FALSE; 
    END_IF; 
    (* Если всё сделали, то out выключится. Если пачка ещё генерируется, то младший бит и есть меандр *) 
    out := qtyLeft.0;
Код:
FUNCTION_BLOCK WAIT_TICK 
  variables: 
    input pruCycleLength : WORD; 
    cyclesLeft : WORD; 
    currentCycles : WORD; 
    controlRegisterAddress : DWORD; 
   
  body: 
    (* 0x00007000..0x00007FFF -- PRU0 Control Registers, 0xC -- cycle count register *) 
    controlRegisterAddress := 16#700C; 
    ASM 
      LBBO currentCycles, controlRegisterAddress, 0, 2 ; Load cycle count, 1+wdcnt*1==2 cycles 
    END_ASM 
    currentCycles := currentCycles + 8; 
    IF pruCycleLength > currentCycles THEN 
      cyclesLeft := pruCycleLength - currentCycles; 
      cyclesLeft := cyclesLeft XOR 0; 
      IF cyclesLeft.0 THEN 
        cyclesLeft := cyclesLeft XOR 1; 
      END_IF; 
      WHILE cyclesLeft <> 0 DO 
        cyclesLeft := cyclesLeft - 2; 
      END_WHILE; 
    ELSE 
      cyclesLeft := 0; 
    END_IF; 
    ASM 
      SBBO cyclesLeft, controlRegisterAddress, 0, 2 ; Load cycle count, 1+wdcnt*1==2 cycles 
    END_ASM