def write_mem (self, start_addr, type, data):
        """
        Uploads data to a target SpiNNaker node at a specific memory location.

        :param int start_addr: base address for the uploaded data
        :param int type:       one of ``TYPE_BYTE``, ``TYPE_HALF``, or
                               ``TYPE_WORD`` to indicate element type
        :param str data:       string of data to upload
        :raises:               SCPError

        """

        msg = SCPMessage (cmd_rc=scamp.CMD_WRITE, arg3=type)

        # confirm the data length is aligned to the appropriate boundary
        self._check_size_alignment(type, len (data))

        # upload the data in maximum-sized chunks
        addr = start_addr
        for chunk in self.gen_slice(data, scamp.SDP_DATA_SIZE):
            # build up the packet as follows:
            #   arg1 = start address
            #   arg2 = chunk length
            #   arg3 = element size
            msg.arg1    = addr
            msg.arg2    = len (chunk)
            msg.payload = chunk
            self.transceiver.conn.send_scp_msg(msg)

            # increment the address pointer
            addr += len (chunk)
Exemple #2
0
    def exec_app_start(self, start_addr, cpu_mask):
        """
        Simultaneously executes APLX images on several processors in the target
        SpiNNaker node.

        :param int start_addr: memory address of the APLX image
        :param int cpu_mask: bit-mask of processors on which to execute the image
        :raises: SCPError

        ``cpu_mask`` is an integer *mask* where each bit corresponds to a
        processor on the target SpiNNaker node, i.e. bit N implies that the
        program should be executed on processor N.

        .. warning::

            The monitor processor **is** included in the ``cpu_mask`` which can
            lead to errors if the APLX image was not designed to run on the
            monitor pacman.

        """

        # simple packet:
        #   arg1 = address of program in memory
        #   arg2 = cpu mask - each bit corresponds to a pacman in the chip
        #   arg3 = unused
        msg = SCPMessage()
        msg.cmd_rc = scamp.CMD_AS
        msg.arg1 = start_addr
        msg.arg2 = cpu_mask
        self.transceiver.conn.send_scp_msg(msg)
    def exec_app_start(self, start_addr, cpu_mask):
        """
        Simultaneously executes APLX images on several processors in the target
        SpiNNaker node.

        :param int start_addr: memory address of the APLX image
        :param int cpu_mask: bit-mask of processors on which to execute the image
        :raises: SCPError

        ``cpu_mask`` is an integer *mask* where each bit corresponds to a
        processor on the target SpiNNaker node, i.e. bit N implies that the
        program should be executed on processor N.

        .. warning::

            The monitor processor **is** included in the ``cpu_mask`` which can
            lead to errors if the APLX image was not designed to run on the
            monitor pacman.

        """

        # simple packet:
        #   arg1 = address of program in memory
        #   arg2 = cpu mask - each bit corresponds to a pacman in the chip
        #   arg3 = unused
        msg        = SCPMessage()
        msg.cmd_rc = scamp.CMD_AS
        msg.arg1   = start_addr
        msg.arg2   = cpu_mask
        self.transceiver.conn.send_scp_msg(msg)
 def nnp(self, key, data, sfr):
     msg = SCPMessage(cmd_rc=scamp.CMD_NNP)
     #initlise values
     msg._arg1 = key
     msg._arg2 = data
     msg._arg3 = sfr
     self.transceiver.conn.send_scp_msg(msg)
    def init_p2p_tables(self, cx, cy):
        """
        Configure the P2P tables on the remote SpiNNaker using the Manchester
        algorithm which superimposes a 2D co-ordinate space on the SpiNNaker
        fabric.

        :param int cx: width of the P2P space
        :param int cy: height of the P2P space

        """

        msg = SCPMessage (cmd_rc=scamp.CMD_P2PC)

        # generate a new sequence number
        seq = self.next_seq_num()

        # the following lines have been taken almost verbatim from ybug.
        # the comments state the following organisation but this is clearly no
        # longer the case:
        #   arg1 = 00 : 00 :   00   : seq num
        #   arg2 = cx : cy : addr x : addr y
        #   arg3 = 00 : 00 :   fwd  :  retry
        msg.arg1 = (0x003e << 16) | seq
        msg.arg2 = (cx << 24) | (cy << 16)
        msg.arg3 = 0x3ff8

        # send the command to SpiNNaker
        self.send_scp_msg (msg)
    def get_iptag (self, index):
        """
        Retrieve an IP-tag from the target SpiNNaker machine.

        :param int index: index in the IP-tag table.
        :returns:         IP tag data in a :py:class:`IPTag`
        :raises:          SCPError

        """

        # build up the request as follows:
        #   arg1 = 0 : command : 0 :  tag
        #   arg2 = 0 :    0    : 0 : count
        #   arg3 = 0 :    0    : 0 :   0
        msg        = SCPMessage ()
        msg.cmd_rc = scamp.CMD_IPTAG
        msg.arg1   = scamp.IPTAG_GET << 16 | index
        msg.arg2   = 1
        msg.arg3   = 0
        resp_msg   = self.send_scp_msg (msg)

        # deconstruct the returned data
        if len (resp_msg.data) != 16:
            raise ValueError ("insufficient data received in response.")
        (ip, mac, port, timeout, flags) = struct.unpack ('<4s6s3H',
            resp_msg.data)

        # format the IP and MAC addresses correctly
        ip  = '.'.join (['%d'   % ord (c) for c in ip])
        mac = ':'.join (['%02X' % ord (c) for c in mac])

        # return the data as a struct
        return IPTag(ip=ip, mac=mac, port=port, timeout=timeout/100.0,
            flags=flags, index=index)
    def get_iptag_table_info (self):
        """
        Retrieve the number of fixed and transient tags available as well as
        the default timeout for all transient tags.

        :returns: fixed record count, transient record count, default timeout
        :raises:  SCPError

        """

        # build up the request according to the following formula:
        #   arg1 = 0 : command : 0 :    0
        #   arg2 = 0 :    0    : 0 : timeout
        #   arg3 = 0 :    0    : 0 :    0
        msg        = SCPMessage ()
        msg.cmd_rc = scamp.CMD_IPTAG
        msg.arg1   = scamp.IPTAG_TTO << 16
        msg.arg2   = 255                  # must be 16 or greater to be ignored
        msg.arg3   = 0
        resp_msg   = self.send_scp_msg (msg)

        # decode the response data (32bits) structured as follows:
        #   31:24 - max. number of fixed tags
        #   23:16 - max. number of transient tags
        #   15: 8 - reserved (0)
        #    7: 0 - transient timeout exponent
        if len (resp_msg.data) != 4:
            raise ValueError ("insufficient data received in response.")
        (ttoE, trans, fixed) =  struct.unpack ('Bx2B', resp_msg.data)

        # convert the timeout into seconds using the equation:
        #    timeout = 10ms * 2^(ttoE - 1)
        timeout = (1 << (ttoE - 1)) * 0.01

        return (fixed, trans, timeout)
    def set_leds(self,
                 led1=scamp.LED_NO_CHANGE,
                 led2=scamp.LED_NO_CHANGE,
                 led3=scamp.LED_NO_CHANGE,
                 led4=scamp.LED_NO_CHANGE):
        """
        Changes the state of the LEDs of the target SpiNNaker node.

        :param int led1: action for LED 1
        :param int led2: action for LED 2
        :param int led3: action for LED 3
        :param int led4: action for LED 4
        :raises: SCPError

        Each ``ledN`` parameter may be given one of four values from the SC&MP
        definitions: ``LED_NO_CHANGE``, ``LED_INVERT``, ``LED_OFF``, or
        ``LED_ON``.

        """

        # LED control signals exist only in the lowest byte of arg1
        msg = SCPMessage()
        msg.cmd_rc = scamp.CMD_LED
        msg.arg1 = (led4 << 6) | (led3 << 4) | (led2 << 2) | led1
        self.send_scp_msg(msg)
    def init_p2p_tables(self, cx, cy):
        """
        Configure the P2P tables on the remote SpiNNaker using the Manchester
        algorithm which superimposes a 2D co-ordinate space on the SpiNNaker
        fabric.

        :param int cx: width of the P2P space
        :param int cy: height of the P2P space

        """

        msg = SCPMessage(cmd_rc=scamp.CMD_P2PC)

        # generate a new sequence number
        seq = self.next_seq_num()

        # the following lines have been taken almost verbatim from ybug.
        # the comments state the following organisation but this is clearly no
        # longer the case:
        #   arg1 = 00 : 00 :   00   : seq num
        #   arg2 = cx : cy : addr x : addr y
        #   arg3 = 00 : 00 :   fwd  :  retry
        msg.arg1 = (0x003e << 16) | seq
        msg.arg2 = (cx << 24) | (cy << 16)
        msg.arg3 = 0x3ff8

        # send the command to SpiNNaker
        self.send_scp_msg(msg)
 def nnp(self, key, data, sfr):
     msg = SCPMessage(cmd_rc=scamp.CMD_NNP)
     #initlise values
     msg._arg1 = key
     msg._arg2 = data
     msg._arg3 = sfr
     self.transceiver.conn.send_scp_msg(msg)
    def write_mem (self, start_addr, type, data):
        """
        Uploads data to a target SpiNNaker node at a specific memory location.

        :param int start_addr: base address for the uploaded data
        :param int type:       one of ``TYPE_BYTE``, ``TYPE_HALF``, or
                               ``TYPE_WORD`` to indicate element type
        :param str data:       string of data to upload
        :raises:               SCPError

        """

        msg = SCPMessage (cmd_rc=scamp.CMD_WRITE, arg3=type)

        # confirm the data length is aligned to the appropriate boundary
        self._check_size_alignment(type, len (data))

        # upload the data in maximum-sized chunks
        addr = start_addr
        for chunk in self.gen_slice(data, scamp.SDP_DATA_SIZE):
            # build up the packet as follows:
            #   arg1 = start address
            #   arg2 = chunk length
            #   arg3 = element size
            msg.arg1    = addr
            msg.arg2    = len (chunk)
            msg.payload = chunk
            self.transceiver.conn.send_scp_msg(msg)

            # increment the address pointer
            addr += len (chunk)
    def flood_fill(self, buf, region, mask, app_id,
                   app_flags, base=0x67800000):

        num_bytes = len(buf)
        blocks = int(num_bytes / BLOCK_SIZE)
        if (num_bytes % BLOCK_SIZE) != 0:
          blocks += 1
          
        logger.debug("Bytes %u blocks %u" % (num_bytes, blocks))
   
        sfwd, srty = 0x3f, 0x18# Forward, retry parameters

        ff_id = self.next_id()

        fr = (sfwd << 8) + srty# Pack up fwd, rty
        sfr = (1 << 31) + fr# Bit 31 says allocate ID on Spin

        key = (NN_CMD_FFS << 24) + (ff_id << 16) + (blocks << 8) + 0
        data = region

        self.nnp(key, data, sfr)

        #send FFD data

        ptr = 0

        for block in range(blocks):
            end = ptr + BLOCK_SIZE
            data = buf[ptr:end]

            word_size = (len(data) / 4) - 1 #convert to word size (why -1?)
            arg1 = (sfwd << 24) + (srty << 16) + (0 << 8) + ff_id #??
            arg2 = (0 << 24) + (block << 16) + (word_size << 8) + 0 #??

            msg = SCPMessage(cmd_rc=scamp.CMD_FFD)
            #initlise values
            msg.arg1 = arg1
            msg.arg2 = arg2
            msg.arg3 = base
            msg.payload = data

            self.transceiver.conn.send_scp_msg(msg)
            #update pointer to next block
            base += BLOCK_SIZE
            ptr += BLOCK_SIZE

        # send FFE packet
        key = (NN_CMD_FFE << 24) + (0 << 16) + (0 << 8) + ff_id # const
        data = (app_id << 24) + (app_flags << 18) + (mask & 0x3ffff)
        self.nnp(key, data, fr)
Exemple #13
0
    def exec_aplx(self, start_addr):
        """
        Executes an APLX image on the target SpiNNaker node.

        :param int start_addr: memory address of the APLX image
        :raises: SCPError

        """

        # simple packet:
        #   arg1 = address of "table" (i.e. program start in SDRAM)
        #   arg2 = unused parameter - must be 0
        #   arg3 = unused
        msg = SCPMessage()
        msg.cmd_rc = scamp.CMD_APLX
        msg.arg1 = start_addr
        self.transceiver.conn.send_scp_msg(msg)
    def exec_aplx (self, start_addr):
        """
        Executes an APLX image on the target SpiNNaker node.

        :param int start_addr: memory address of the APLX image
        :raises: SCPError

        """

        # simple packet:
        #   arg1 = address of "table" (i.e. program start in SDRAM)
        #   arg2 = unused parameter - must be 0
        #   arg3 = unused
        msg        = SCPMessage ()
        msg.cmd_rc = scamp.CMD_APLX
        msg.arg1   = start_addr
        self.transceiver.conn.send_scp_msg (msg)
    def clear_iptag (self, index):
        """
        Removes an IP-tag from the remote SpiNNaker.

        :param int index: index to remove from the table
        :raises:          SCPError

        """

        # build up the request as follows:
        #   arg1 = 0 : command : 0 : tag
        #   arg2 = 0 :    0    : 0 :  0
        #   arg3 = 0 :    0    : 0 :  0
        msg        = SCPMessage ()
        msg.cmd_rc = scamp.CMD_IPTAG
        msg.arg1   = (scamp.IPTAG_CLR << 16) | index

        # fire off the command
        self.send_scp_msg (msg)
    def clear_iptag(self, index):
        """
        Removes an IP-tag from the remote SpiNNaker.

        :param int index: index to remove from the table
        :raises:          SCPError

        """

        # build up the request as follows:
        #   arg1 = 0 : command : 0 : tag
        #   arg2 = 0 :    0    : 0 :  0
        #   arg3 = 0 :    0    : 0 :  0
        msg = SCPMessage()
        msg.cmd_rc = scamp.CMD_IPTAG
        msg.arg1 = (scamp.IPTAG_CLR << 16) | index

        # fire off the command
        self.send_scp_msg(msg)
    def read_mem (self, start_addr, type, size):
        """
        Reads an amount of data from the target SpiNNaker node starting at
        address ``start_addr``.

        :param int start_addr: address to start reading from
        :param int type:       one of ``TYPE_BYTE``, ``TYPE_HALF``, or
                               ``TYPE_WORD`` to indicate element type
        :param int size:       number of bytes to read
        :returns:              string containing the data read
        :raises:               SCPError

        """

        msg = SCPMessage (cmd_rc=scamp.CMD_READ)

        # confirm the data size is aligned to the appropriate boundary
        self._check_size_alignment (type, size)

        # initialise tracker variables
        addr      = start_addr
        buf       = ''
        read_size = size

        # read all the data
        while (addr - start_addr) < size:
            # build up the packet as follows:
            #   arg1 = start address
            #   arg2 = chunk length
            #   arg3 = element size
            msg.arg1 = addr
            msg.arg2 = min (read_size, scamp.SDP_DATA_SIZE)
            msg.arg3 = type
            resp = self.transceiver.conn.send_scp_msg (msg)

            # add the data to the buffer and update the tracker variables
            buf       += resp.data
            addr      += len (resp.data)
            read_size -= len (resp.data)

        # return the (hopefully valid) data buffer
        return buf
    def read_mem (self, start_addr, type, size):
        """
        Reads an amount of data from the target SpiNNaker node starting at
        address ``start_addr``.

        :param int start_addr: address to start reading from
        :param int type:       one of ``TYPE_BYTE``, ``TYPE_HALF``, or
                               ``TYPE_WORD`` to indicate element type
        :param int size:       number of bytes to read
        :returns:              string containing the data read
        :raises:               SCPError

        """

        msg = SCPMessage (cmd_rc=scamp.CMD_READ)

        # confirm the data size is aligned to the appropriate boundary
        self._check_size_alignment (type, size)

        # initialise tracker variables
        addr      = start_addr
        buf       = ''
        read_size = size

        # read all the data
        while (addr - start_addr) < size:
            # build up the packet as follows:
            #   arg1 = start address
            #   arg2 = chunk length
            #   arg3 = element size
            msg.arg1 = addr
            msg.arg2 = min (read_size, scamp.SDP_DATA_SIZE)
            msg.arg3 = type
            resp = self.transceiver.conn.send_scp_msg (msg)

            # add the data to the buffer and update the tracker variables
            buf       += resp.data
            addr      += len (resp.data)
            read_size -= len (resp.data)

        # return the (hopefully valid) data buffer
        return buf
    def set_iptag (self, index, host, port):
        """
        Set an IP-tag record at the required index.

        :param int index:   index in the IP-tag table
        :param str host:    hostname or IP address of destination
        :param int port:    port to use on destination
        :param int timeout: specific timeout to use, or 0 for default
        :returns:           record index in the IP-tag table
        :raises:            SCPError

        """

        # clamp the port and timeout to their appropriate ranges
        port    &= 0xFFFF

        # ensure that the given hostname is always an IP
        if host.lower () in ("localhost", "127.0.0.1", "."):
            host = self._sock.getsockname()[0]
        ip = socket.gethostbyname (host)

        # decompose the IP address into the component numbers and store in an
        # integer in REVERSE order so that it's correct after packing
        ip, segs = 0, ip.split ('.')
        if len (segs) != 4:
            raise ValueError ("IP address format is incorrect")
        for n, seg in enumerate (segs):
            ip |= (int (seg) << (8*n))

        msg = SCPMessage (cmd_rc=scamp.CMD_IPTAG)
        msg.arg1 = scamp.IPTAG_SET << 16 | (index & 0xFF)

        # the rest of the arguments follow the order:
        #   arg2 = port
        #   arg3 = IP
        msg.arg2 = port
        msg.arg3 = ip

        # fire off the packet
        self.send_scp_msg (msg)
    def set_iptag(self, index, host, port):
        """
        Set an IP-tag record at the required index.

        :param int index:   index in the IP-tag table
        :param str host:    hostname or IP address of destination
        :param int port:    port to use on destination
        :param int timeout: specific timeout to use, or 0 for default
        :returns:           record index in the IP-tag table
        :raises:            SCPError

        """

        # clamp the port and timeout to their appropriate ranges
        port &= 0xFFFF

        # ensure that the given hostname is always an IP
        if host.lower() in ("localhost", "127.0.0.1", "."):
            host = self._sock.getsockname()[0]
        ip = socket.gethostbyname(host)

        # decompose the IP address into the component numbers and store in an
        # integer in REVERSE order so that it's correct after packing
        ip, segs = 0, ip.split('.')
        if len(segs) != 4:
            raise ValueError("IP address format is incorrect")
        for n, seg in enumerate(segs):
            ip |= (int(seg) << (8 * n))

        msg = SCPMessage(cmd_rc=scamp.CMD_IPTAG)
        msg.arg1 = scamp.IPTAG_SET << 16 | (index & 0xFF)

        # the rest of the arguments follow the order:
        #   arg2 = port
        #   arg3 = IP
        msg.arg2 = port
        msg.arg3 = ip

        # fire off the packet
        self.send_scp_msg(msg)
    def get_iptag_table_info(self):
        """
        Retrieve the number of fixed and transient tags available as well as
        the default timeout for all transient tags.

        :returns: fixed record count, transient record count, default timeout
        :raises:  SCPError

        """

        # build up the request according to the following formula:
        #   arg1 = 0 : command : 0 :    0
        #   arg2 = 0 :    0    : 0 : timeout
        #   arg3 = 0 :    0    : 0 :    0
        msg = SCPMessage()
        msg.cmd_rc = scamp.CMD_IPTAG
        msg.arg1 = scamp.IPTAG_TTO << 16
        msg.arg2 = 255  # must be 16 or greater to be ignored
        msg.arg3 = 0
        resp_msg = self.send_scp_msg(msg)

        # decode the response data (32bits) structured as follows:
        #   31:24 - max. number of fixed tags
        #   23:16 - max. number of transient tags
        #   15: 8 - reserved (0)
        #    7: 0 - transient timeout exponent
        if len(resp_msg.data) != 4:
            raise ValueError("insufficient data received in response.")
        (ttoE, trans, fixed) = struct.unpack('Bx2B', resp_msg.data)

        # convert the timeout into seconds using the equation:
        #    timeout = 10ms * 2^(ttoE - 1)
        timeout = (1 << (ttoE - 1)) * 0.01

        return (fixed, trans, timeout)
def reset(hostname):
    """
    Establishes a SCP connection to the board-management processor specified
    by ``hostname`` and sends a reset command.

    :param hostname: hostname of the board-management processor of the target
                     SpiNNaker

    .. warning::

        This function is only applicable to SpiNN-4 (or greater) boards that
        have board-management processors on the PCB.

    """

    # simple packet:
    #   arg1 = 2 (denotes pulse reset)
    conn = SCPConnection(hostname)
    msg = SCPMessage()
    msg.cmd_rc = scamp.CMD_RESET
    msg.arg1 = 2
    conn.send_scp_msg(msg)
    def read_link_word(start_addr, linkid, conn):
        """
        Reads data from a neighbouring chip over that link

        :param int start_addr: address to start reading from (type is always a 32-bit word!)
        :param int linkid:     which link to use, i.e. 0:E, 1: NE, 2:N, 3:W, 4:SW, 5:S
        :returns:              string containing the data read
        :raises:               SCPError

        """

        msg = SCPMessage(cmd_rc=scamp.CMD_LINK_READ)

        # confirm the data size is aligned to the appropriate boundary
        #self._check_size_alignment (type, size)

        # initialise tracker variables
        addr = start_addr
        buf = ''
        read_size = 4

        # read all the data
        while (addr - start_addr) < read_size:
            # build up the packet as follows:
            #   arg1 = start address
            #   arg2 = chunk length
            #   arg3 = element size
            msg.arg1 = addr
            msg.arg2 = min(read_size, scamp.SDP_DATA_SIZE)
            msg.arg3 = linkid
            resp = conn.conn.send_scp_msg(msg)

            # add the data to the buffer and update the tracker variables
            buf += resp.data
            addr += len(resp.data)
            read_size -= len(resp.data)

        # return the (hopefully valid) data buffer requested
        return buf
Exemple #24
0
    def read_link_word(start_addr, linkid, conn):
        """
        Reads data from a neighbouring chip over that link

        :param int start_addr: address to start reading from (type is always a 32-bit word!)
        :param int linkid:     which link to use, i.e. 0:E, 1: NE, 2:N, 3:W, 4:SW, 5:S
        :returns:              string containing the data read
        :raises:               SCPError

        """

        msg = SCPMessage(cmd_rc=scamp.CMD_LINK_READ)

        # confirm the data size is aligned to the appropriate boundary
        #self._check_size_alignment (type, size)

        # initialise tracker variables
        addr = start_addr
        buf = ''
        read_size = 4

        # read all the data
        while (addr - start_addr) < read_size:
            # build up the packet as follows:
            #   arg1 = start address
            #   arg2 = chunk length
            #   arg3 = element size
            msg.arg1 = addr
            msg.arg2 = min(read_size, scamp.SDP_DATA_SIZE)
            msg.arg3 = linkid
            resp = conn.conn.send_scp_msg(msg)

            # add the data to the buffer and update the tracker variables
            buf += resp.data
            addr += len(resp.data)
            read_size -= len(resp.data)

        # return the (hopefully valid) data buffer requested
        return buf
Exemple #25
0
def reset(hostname):
    """
    Establishes a SCP connection to the board-management processor specified
    by ``hostname`` and sends a reset command.

    :param hostname: hostname of the board-management processor of the target
                     SpiNNaker

    .. warning::

        This function is only applicable to SpiNN-4 (or greater) boards that
        have board-management processors on the PCB.

    """

    # simple packet:
    #   arg1 = 2 (denotes pulse reset)
    conn = SCPConnection(hostname)
    msg = SCPMessage()
    msg.cmd_rc = scamp.CMD_RESET
    msg.arg1 = 2
    conn.send_scp_msg(msg)
    def set_leds (self, led1=scamp.LED_NO_CHANGE, led2=scamp.LED_NO_CHANGE,
            led3=scamp.LED_NO_CHANGE, led4=scamp.LED_NO_CHANGE):
        """
        Changes the state of the LEDs of the target SpiNNaker node.

        :param int led1: action for LED 1
        :param int led2: action for LED 2
        :param int led3: action for LED 3
        :param int led4: action for LED 4
        :raises: SCPError

        Each ``ledN`` parameter may be given one of four values from the SC&MP
        definitions: ``LED_NO_CHANGE``, ``LED_INVERT``, ``LED_OFF``, or
        ``LED_ON``.

        """

        # LED control signals exist only in the lowest byte of arg1
        msg        = SCPMessage ()
        msg.cmd_rc = scamp.CMD_LED
        msg.arg1   = (led4 << 6) | (led3 << 4) | (led2 << 2) | led1
        self.send_scp_msg (msg)
    def version(self, retries=10):
        """
        Retreives the version information about the host operating system.

        :returns: version of OS in a class
        :raises:  SCPError

        """

        cmd_msg = SCPMessage(cmd_rc=scamp.CMD_VER)
        ver_msg = self.send_scp_msg(cmd_msg, retries=retries)

        # decode the payload into a usable struct
        return VersionInfo(ver_msg)
    def set_transient_iptag_timeout (self, timeout):
        """
        Sets the timeout for all transient IP-tags on the target machine.

        :param float: timeout in *seconds*
        :raises: SCPError

        .. note::

            On the SpiNNaker node, all timeouts are stored in an exponential
            representation that limits the number of valid timeout durations to
            a small set.  Timeouts are calculated (from the node's perspective)
            as follows::

                timeout = 10ms * 2^(tto - 1)

            Hence timeout values passed into this function will be decomposed
            into ``tto`` in the above equation.

        """

        # convert the timeout into the exponent as explained above
        tto = int (math.ceil (math.log ((timeout / 0.01), 2))) + 1
        if tto >= 16:
            raise ValueError ("specific timeout is too large.")

        # set the new transient timeout
        #   arg1 = 0 : command : 0 :    0
        #   arg2 = 0 :    0    : 0 : timeout
        #   arg3 = 0 :    0    : 0 :    0
        msg        = SCPMessage ()
        msg.cmd_rc = scamp.CMD_IPTAG
        msg.arg1   = scamp.IPTAG_TTO << 16
        msg.arg2   = tto
        msg.arg3   = 0
        self.send_scp_msg (msg)
    def flood_fill(self,
                   buf,
                   region,
                   mask,
                   app_id,
                   app_flags,
                   base=0x67800000):

        num_bytes = len(buf)
        blocks = int(num_bytes / BLOCK_SIZE)
        if (num_bytes % BLOCK_SIZE) != 0:
            blocks += 1

        logger.debug("Bytes %u blocks %u" % (num_bytes, blocks))

        sfwd, srty = 0x3f, 0x18  # Forward, retry parameters

        ff_id = self.next_id()

        fr = (sfwd << 8) + srty  # Pack up fwd, rty
        sfr = (1 << 31) + fr  # Bit 31 says allocate ID on Spin

        key = (NN_CMD_FFS << 24) + (ff_id << 16) + (blocks << 8) + 0
        data = region

        self.nnp(key, data, sfr)

        #send FFD data

        ptr = 0

        for block in range(blocks):
            end = ptr + BLOCK_SIZE
            data = buf[ptr:end]

            word_size = (len(data) / 4) - 1  #convert to word size (why -1?)
            arg1 = (sfwd << 24) + (srty << 16) + (0 << 8) + ff_id  #??
            arg2 = (0 << 24) + (block << 16) + (word_size << 8) + 0  #??

            msg = SCPMessage(cmd_rc=scamp.CMD_FFD)
            #initlise values
            msg.arg1 = arg1
            msg.arg2 = arg2
            msg.arg3 = base
            msg.payload = data

            self.transceiver.conn.send_scp_msg(msg)
            #update pointer to next block
            base += BLOCK_SIZE
            ptr += BLOCK_SIZE

        # send FFE packet
        key = (NN_CMD_FFE << 24) + (0 << 16) + (0 << 8) + ff_id  # const
        data = (app_id << 24) + (app_flags << 18) + (mask & 0x3ffff)
        self.nnp(key, data, fr)
    def get_iptag(self, index):
        """
        Retrieve an IP-tag from the target SpiNNaker machine.

        :param int index: index in the IP-tag table.
        :returns:         IP tag data in a :py:class:`IPTag`
        :raises:          SCPError

        """

        # build up the request as follows:
        #   arg1 = 0 : command : 0 :  tag
        #   arg2 = 0 :    0    : 0 : count
        #   arg3 = 0 :    0    : 0 :   0
        msg = SCPMessage()
        msg.cmd_rc = scamp.CMD_IPTAG
        msg.arg1 = scamp.IPTAG_GET << 16 | index
        msg.arg2 = 1
        msg.arg3 = 0
        resp_msg = self.send_scp_msg(msg)

        # deconstruct the returned data
        if len(resp_msg.data) != 16:
            raise ValueError("insufficient data received in response.")
        (ip, mac, port, timeout,
         flags) = struct.unpack('<4s6s3H', resp_msg.data)

        # format the IP and MAC addresses correctly
        ip = '.'.join(['%d' % ord(c) for c in ip])
        mac = ':'.join(['%02X' % ord(c) for c in mac])

        # return the data as a struct
        return IPTag(ip=ip,
                     mac=mac,
                     port=port,
                     timeout=timeout / 100.0,
                     flags=flags,
                     index=index)
    def set_transient_iptag_timeout(self, timeout):
        """
        Sets the timeout for all transient IP-tags on the target machine.

        :param float: timeout in *seconds*
        :raises: SCPError

        .. note::

            On the SpiNNaker node, all timeouts are stored in an exponential
            representation that limits the number of valid timeout durations to
            a small set.  Timeouts are calculated (from the node's perspective)
            as follows::

                timeout = 10ms * 2^(tto - 1)

            Hence timeout values passed into this function will be decomposed
            into ``tto`` in the above equation.

        """

        # convert the timeout into the exponent as explained above
        tto = int(math.ceil(math.log((timeout / 0.01), 2))) + 1
        if tto >= 16:
            raise ValueError("specific timeout is too large.")

        # set the new transient timeout
        #   arg1 = 0 : command : 0 :    0
        #   arg2 = 0 :    0    : 0 : timeout
        #   arg3 = 0 :    0    : 0 :    0
        msg = SCPMessage()
        msg.cmd_rc = scamp.CMD_IPTAG
        msg.arg1 = scamp.IPTAG_TTO << 16
        msg.arg2 = tto
        msg.arg3 = 0
        self.send_scp_msg(msg)
    def app_signal(self, app_id, signal_id, state_id=None, x=None,
                   y=None, range=None):
        '''
        method that allows signals to be polled and sent to areas of a board
        '''
        #define the region
        region = ""
        if(x is None and y is None):
            region = "all"

        if signal_id not in self.signal_states:
            raise exceptions.SpinnManException("signal definition does not "
                                               "exist for {}. List is {}"
                                               .format(signal_id,
                                                       self.signal_states))
        region = self.spinnaker_utility.parse_region(region, x, y)
        
        #locate signal name id
        signal = self.signal_states[signal_id]
        
        #locate state id
        state = None
        if signal_id >= 16:
            if state_id is not None:
                if state_id in self.states:
                    state = self.states[state_id]
                else:
                    raise exceptions.SpinnManException("No state with that id")
            else:
                raise exceptions.SpinnManException("state was defined as None "
                                                   "when using a and/or/count "
                                                   "signal")

        #locate type of signal
        signal_type = self.sig_type[signal]
        
        #parse the apps for a app mask
        app_mask = self.spinnaker_utility.parse_apps(app_id, range)
        mask = int(region) & 0xffff
        data = (app_mask << 8) + app_id
        
        #if signal type is 1
        if signal_type == 1:
            level = (region >> 16) & 3
            op, mode = 2, 2
            
            #if signal is a and/or/count
            if signal_id >= 16:
                op = 1
                mode = signal_id - 16
                data += (level << 26) + (op << 22) + (mode << 20)
                if op == 1:
                    data += state_id << 16
                if op != 1:
                    data += signal_id << 16
               # logger.debug("Level {} op {} mode {}".format(level, op, mode))
        else:
            data += signal_id << 16

       # logger.debug("Type {} data {} mask {}".format(signal_type, data, mask))
       # logger.debug("Region {} signal {} state {}".format(region, signal, state))

        #send scp message and catch the return data
        msg = SCPMessage(cmd_rc=scamp.CMD_SIG)
        msg._arg1 = signal_type
        msg._arg2 = data
        msg._arg3 = mask
        return_data = self.transceiver.conn.send_scp_msg(msg).data

        # if the signal requires a repsonse, output resposne and return it
        if signal_type == 1:
            r = struct.unpack("<I", return_data)[0]
            if signal_id == 18: #count
                #logger.debug("count {}".format(r))
                return r
           # else:
                #logger.debug("mask {}".format(r))
        return 0
Exemple #33
0
    def app_signal(self,
                   app_id,
                   signal_id,
                   state_id=None,
                   x=None,
                   y=None,
                   range=None):
        '''
        method that allows signals to be polled and sent to areas of a board
        '''
        #define the region
        region = ""
        if (x is None and y is None):
            region = "all"

        if signal_id not in self.signal_states:
            raise exceptions.SpinnManException(
                "signal definition does not "
                "exist for {}. List is {}".format(signal_id,
                                                  self.signal_states))
        region = self.spinnaker_utility.parse_region(region, x, y)

        #locate signal name id
        signal = self.signal_states[signal_id]

        #locate state id
        state = None
        if signal_id >= 16:
            if state_id is not None:
                if state_id in self.states:
                    state = self.states[state_id]
                else:
                    raise exceptions.SpinnManException("No state with that id")
            else:
                raise exceptions.SpinnManException("state was defined as None "
                                                   "when using a and/or/count "
                                                   "signal")

        #locate type of signal
        signal_type = self.sig_type[signal]

        #parse the apps for a app mask
        app_mask = self.spinnaker_utility.parse_apps(app_id, range)
        mask = int(region) & 0xffff
        data = (app_mask << 8) + app_id

        #if signal type is 1
        if signal_type == 1:
            level = (region >> 16) & 3
            op, mode = 2, 2

            #if signal is a and/or/count
            if signal_id >= 16:
                op = 1
                mode = signal_id - 16
                data += (level << 26) + (op << 22) + (mode << 20)
                if op == 1:
                    data += state_id << 16
                if op != 1:
                    data += signal_id << 16
            # logger.debug("Level {} op {} mode {}".format(level, op, mode))
        else:
            data += signal_id << 16

    # logger.debug("Type {} data {} mask {}".format(signal_type, data, mask))
    # logger.debug("Region {} signal {} state {}".format(region, signal, state))

    #send scp message and catch the return data
        msg = SCPMessage(cmd_rc=scamp.CMD_SIG)
        msg._arg1 = signal_type
        msg._arg2 = data
        msg._arg3 = mask
        return_data = self.transceiver.conn.send_scp_msg(msg).data

        # if the signal requires a repsonse, output resposne and return it
        if signal_type == 1:
            r = struct.unpack("<I", return_data)[0]
            if signal_id == 18:  #count
                #logger.debug("count {}".format(r))
                return r
        # else:
        #logger.debug("mask {}".format(r))
        return 0