miiInterrupt exception

Technical questions regarding the XTC tools and programming with XMOS.
peter
XCore Addict
Posts: 230
Joined: Wed Mar 10, 2010 12:46 pm

Post by peter »

Hi goodfeather,

Sorry for the delay, I've been rather busy. I have finally managed to create an example program. Hopefully you are able to take this and adapt it for your own needs. Basically, I have written a custom handler which gets installed and on trap then resets the chip. Note this is designed for XS2 architectures:

Code: Select all

int main(void) {
    par {
        on tile[0]: {
          // Install the custom trap handler
          unsigned tile_id = get_local_tile_id();
          install_handler(tile_id);

          // Wait
          delay_seconds(5);

          // Cause trap
          unsafe {
            int *x = 0;
            // Cause trap
            *x = 0;
          }
        }
    }
    return 0;
}
The trap handler is written in assembler. It reads the value from the Switch PLL register, and then writes it with bit 31 clear and this causes the device to reset. Please ask if you have any questions:

Code: Select all

// Custom trap handler.
// It reads the SSWITCH PLL control register, clears bit 31 and writes it back
// to cause a reset
#include <xs1.h>

.align 4
tile_id:
.word 0

.align 4
.globl install_handler
.globl install_handler.nstackwords
.linkset install_handler.nstackwords, 0
install_handler:
  nop                           // Need a NOP to align the ENTSP to the right lane
  entsp 0
  ldap r11, trap_handler
  set kep, r11
  ldap r11, tile_id
  stw r0, r11[0]
  retsp 0

.align XS1_KEP_ALIGNMENT
.globl trap_handler
.globl trap_handler.nstackwords
.linkset trap_handler.nstackwords, 0
trap_handler:
  ldc r1, 0x6                   // XS1_L_SSWITCH_PLL_CTL_NUM
  ldc r2, 0x0                   // Get a default value in r2

  // Read the tile id from memory
  ldap r11, tile_id
  ldw r0, r11[0]
  shl r0, r0, XS1_CHAN_ID_PROCESSOR_SHIFT

  getr r3, XS1_RES_TYPE_CHANEND
  
  // Set destination
  ldc r11, XS1_RES_TYPE_CONFIG | (XS1_CT_SSCTRL << XS1_CHAN_ID_CHANNUM_SHIFT)
  or r11, r11, r0
  setd res[r3], r11

  // Send read packet
  ldc r11, XS1_CT_READC         // Too big for outct immediate
  outct res[r3], r11
  shr r0, r3, 8
  shl r0, r0, 8
  shr r11, r1, 8
  or r0, r0, r11
  out res[r3], r0               // (c & 0xffffff00) | (reg >> 8)
  outt res[r3], r1              // reg & 0xff
  outct res[r3], XS1_CT_END

  // Receive response
  inct r11, res[r3]              // receive ACK/NACK
  eq r11, r11, XS1_CT_ACK
  bf r11, got_nack
  in r2, res[r3]                // for ACK put response into r2

got_nack:
  chkct res[r3], XS1_CT_END     // consume END

  // Send write packet
  ldc r11, XS1_CT_WRITEC        // Too big for outct immediate
  outct res[r3], r11
  out res[r3], r0               // (c & 0xffffff00) | (reg >> 8)
  outt res[r3], r1              // reg & 0xff

  // Clear bit 31 to request reset
  ldc r11, 1
  ldc r10, 31
  shl r11, r11, r10
  andnot r2, r11

  out res[r3], r2               // Send value to write
  outct res[r3], XS1_CT_END

  // Consume response
  inct r0, res[r3]
  chkct res[r3], XS1_CT_END
  freer res[r3]

  // Wait for reset
  waiteu
Regards,

Peter