wokwi/rp2040js

PIO doesn't raise TXNFULL/RXNEMPTY interrupts

urish opened this issue · 0 comments

urish commented

The PIO peripheral does not raise an interrupt when the TXNFULL (TX FIFO not full) / RXNEMPTY (RX FIFO not empty) flags are set in the IRQ0_INTS / IRQ1_INTS registers.

Failing test cases (that pass on the silicone):

  const NVIC_ISPR = 0xe000e200;
  const NVIC_ICPR = 0xe000e280;
  const SM0_RXNEMPTY = 1 << 0;
  const IRQ0_INTE = 0x5020012c;
  const PIO_IRQ0 = 1 << 7;
  const SM0_TXNFULL = 1 << 4;

  it('should update TXNFULL flag in INTR according to the level of the TX FIFO', async () => {
    await resetStateMachines();
    await cpu.writeUint32(IRQ0_INTE, SM0_TXNFULL);
    expect((await cpu.readUint32(INTR)) & SM0_TXNFULL).toEqual(SM0_TXNFULL);
    expect((await cpu.readUint32(NVIC_ISPR)) & PIO_IRQ0).toEqual(PIO_IRQ0);
    await cpu.writeUint32(TXF0, 1);
    await cpu.writeUint32(TXF0, 2);
    await cpu.writeUint32(TXF0, 3);
    await cpu.writeUint32(NVIC_ICPR, PIO_IRQ0);
    expect((await cpu.readUint32(INTR)) & SM0_TXNFULL).toEqual(SM0_TXNFULL);
    await cpu.writeUint32(TXF0, 3);
    await cpu.writeUint32(NVIC_ICPR, PIO_IRQ0);

    // At this point, TX FIFO should be full and the flag/interrupt will be cleared
    expect((await cpu.readUint32(INTR)) & SM0_TXNFULL).toEqual(0);
    expect((await cpu.readUint32(NVIC_ISPR)) & PIO_IRQ0).toEqual(0);

    // Pull an item, so TX FIFO should be "not empty" again
    await cpu.writeUint32(SM0_INSTR, pioPULL(false, false));
    expect((await cpu.readUint32(INTR)) & SM0_TXNFULL).toEqual(SM0_TXNFULL);
    expect((await cpu.readUint32(NVIC_ISPR)) & PIO_IRQ0).toEqual(PIO_IRQ0);
  });

  it('should update RXFNEMPTY flag in INTR according to the level of the RX FIFO', async () => {
    await resetStateMachines();
    await cpu.writeUint32(IRQ0_INTE, SM0_RXNEMPTY);
    await cpu.writeUint32(NVIC_ICPR, PIO_IRQ0);
    
    // RX FIFO starts empty
    expect((await cpu.readUint32(INTR)) & SM0_RXNEMPTY).toEqual(0);
    expect((await cpu.readUint32(NVIC_ISPR)) & PIO_IRQ0).toEqual(0);

    // Push an item so it's no longer empty...
    await cpu.writeUint32(SM0_INSTR, pioPUSH(false, false));
    expect((await cpu.readUint32(INTR)) & SM0_RXNEMPTY).toEqual(SM0_RXNEMPTY);
    expect((await cpu.readUint32(NVIC_ISPR)) & PIO_IRQ0).toEqual(PIO_IRQ0);

    // Read the item and it should be empty again
    await cpu.readUint32(RXF0);
    await cpu.writeUint32(NVIC_ICPR, PIO_IRQ0);
    expect((await cpu.readUint32(INTR)) & SM0_RXNEMPTY).toEqual(0);
    expect((await cpu.readUint32(NVIC_ISPR)) & PIO_IRQ0).toEqual(0);
  });