예제 #1
0
    def __init__(self):
        self.m_testutil = testutil.testUtil()
        self.m_config_mgr = spicfg.configMgr()
        self.m_spi_msg = pmmsg.promactMessages()
        self.m_eepromAPI = eepromAPI()
        self.m_spiio = self.m_eepromAPI.getobjectSpiIO()

        self.m_pagesize = eepromAPI.EEPROM_PAGE_SIZE

        #block_protect_bitmap  = testutil.array_u08(18)
        self.m_rxdata_array = testutil.array_u08(self.m_pagesize)
        self.m_txdata_array = testutil.array_u08(self.m_pagesize)
        self.m_random_page_array = testutil.array_u08(self.m_pagesize)

        self.m_configVal = spicfg.configVal()
        return
 def buildBusyTestQueues(self, read_status_cmd):
   
     read_status=testutil.array_u08(1)
     read_status[1]=read_status_cmd
     
     '''
     Start Busy Test
       this instruction queue request the status register
     '''
     start_busytest_queue = pmact.ps_queue_create(self.m_app_conn_handle,
                                         pmact.PS_MODULE_ID_SPI_ACTIVE)
     pmact.ps_queue_clear(start_busytest_queue)
     pmact.ps_queue_spi_oe(start_busytest_queue, self.m_ss_mask)
     pmact.ps_queue_spi_write(start_busytest_queue, protocol.SPIIO_SINGLE, 8, 1, read_status )
     pmact.ps_queue_spi_write_word(start_busytest_queue, protocol.SPIIO_SINGLE, 8, 1, 0)
     
     '''
     continue_busytest_queue
       this instruction queue re-reads the status register
       it MUST be committed AFTER a start_busytest_queue queue
     '''
     cont_busytest_queue = pmact.ps_queue_create(self.m_app_conn_handle,
                                         pmact.PS_MODULE_ID_SPI_ACTIVE)
     pmact.ps_queue_clear(cont_busytest_queue)
     pmact.ps_queue_spi_oe(cont_busytest_queue, 1)
     pmact.ps_queue_spi_write(cont_busytest_queue, protocol.SPIIO_SINGLE, 8, 1, read_status )
  def signalEvent(self):
    if self.m_in_signal_event:
      return
    
    #signal_ss_polarity  = (self.m_spi_ss_polarity) &0xf    
    data_out=testutil.array_u08(1)
    data_out[0]=0xAA
    #invert chip select polarity, send a byte
    _retval=pmact.ps_spi_configure( self.m_channel_handle,
                                   self.m_spi_clk_mode, 
                                   self.m_spi_bit_order, 
                                   self.m_spi_ss_polarity)

    signal_queue = pmact.ps_queue_create( self.m_app_conn_handle,
                                                  pmact.PS_MODULE_ID_SPI_ACTIVE)
    pmact.ps_queue_clear(signal_queue)
    pmact.ps_queue_spi_oe(signal_queue, 0x01)
    for _ndx in range(2):
      pmact.ps_queue_spi_write_word(signal_queue, protocol.SPIIO_SINGLE, 8, 32, 0xAA)
      pmact.ps_queue_delay_ms(signal_queue, 250)
      pmact.ps_queue_spi_write_word(signal_queue, protocol.SPIIO_SINGLE, 8, 32, 0x91)
    pmact.ps_queue_spi_oe(signal_queue, 0x00)
        
    self.m_in_signal_event=True
    status_collect, _dc = pmact.ps_queue_submit(signal_queue, self.m_channel_handle, pmact.PS_MODULE_ID_SPI_ACTIVE)
    _collect_length, _collect_buf, _fatal_error = self.procDevCollect(status_collect)
    pmact.ps_queue_destroy(signal_queue)
    self.m_in_signal_event=False
예제 #4
0
 def readBlockProtectBitmap(self):
   self.m_block_protect_bitmap = testutil.array_u08(18)
   spi_result = self.m_spiio.spiMasterMultimodeCmd(protocol.SPICMD_RBPR,
                                                           None, len(self.m_block_protect_bitmap),
                                                           self.m_block_protect_bitmap)
   data_in_length=spi_result.xfer_length
   if data_in_length==18:
     return True
   else:
     self.m_testutil.fatalError("Protect Bitmap Read fail")
예제 #5
0
    def writeDevicePattern(self,
                           start_page_address,
                           length,
                           array_sequence,
                           verify=False):

        if start_page_address % self.m_eepromAPI.EEPROM_PAGE_SIZE != 0:
            self.m_testutil.fatalError("illegal page address")

        if length % self.m_eepromAPI.EEPROM_PAGE_SIZE != 0:
            self.m_testutil.fatalError("illegal page fill length")

        last_write_index = (length / array_sequence.pageSize())

        array_sequence.setIndexByAddress(start_page_address)
        page_address = start_page_address
        write_index = 0

        while write_index < last_write_index:

            page_address = start_page_address + (write_index *
                                                 array_sequence.pageSize())
            pattern_array = array_sequence.arrayAtAddress(page_address)
            if verify:
                rxdata_array = testutil.array_u08(array_sequence.pageSize())

            # need to catch promira adapter faults
            #
            try_count = 0
            while try_count < 3:
                try:
                    self.m_eepromAPI.writePages(page_address,
                                                array_sequence.pageSize(),
                                                pattern_array)

                    if verify:
                        self.m_eepromAPI.readData(page_address,
                                                  array_sequence.pageSize(),
                                                  rxdata_array)
                        if not self.m_testutil.arraysMatch(
                                pattern_array, rxdata_array):
                            self.m_testutil.fatalError(
                                "writeDevicePattern(): write/verify failed")

                    break

                except self.m_spiio.PromiraError as e:
                    print("Promira Error: %s" % e)
                    #re-init Promira Interfaces
                    self.m_spiio.devResetOpen()
                    try_count += 1

            write_index += 1
            array_sequence.nextIndex()
예제 #6
0
 def readStatusRegister(self):
   data_array = testutil.array_u08(1)
   
   spi_result = self.m_spiio.spiMasterMultimodeCmd(protocol.SPICMD_RDSR,
                                                           None,
                                                           len(data_array),
                                                           data_array)
   self.m_eepromStatus = None
   data_in_length=spi_result.xfer_length
   
   if data_in_length>=1:
     #offset=len(data_array)-data_in_length
     self.m_eepromStatus = data_array[0]
     return self.m_eepromStatus
   
   self.m_testutil.fatalError("ReadStatusRegister error")
   return self.EESTATUS_READ_ERROR
  def spiMasterMultimodeCmd(self,
                                spi_cmd,
                                address=None,
                                data_length=None,
                                data_buffer=None): 
    # -> self.SpiResult


    def submitQueue(queue_handle, channel_handle, ctrlID):
      if self.m_debug_devCollect:
        self.m_testutil.bufferDetailInfo(" queue_handle %d ; channel_handle %d ; ctrlID %d" 
                                        % (queue_handle, channel_handle, ctrlID))
      collect, _dc = pmact.ps_queue_submit(queue_handle, channel_handle, ctrlID)
      if collect < 0:
        raise self.PromiraError("ps_queue_submit", collect, self.m_pm_msg.apiIfError(collect))

      return collect


      
    if self.m_spi_initialized != True:
      self.m_testutil.fatalError("attempt to transact on uninitialized SPI bus")
        
    cmd_byte=spi_cmd[0]
    cmd_spec=protocol.precedentCmdSpec(spi_cmd)
    spi_session=protocol.spiTransaction(spi_cmd, cmd_spec)
    spi_session.setInitialPhase()
    collect = None
    toggle_select_after_wren=True
    
    
    #****DEBUG****
    if self.m_debug_devCollect:
      cmd_msg="cmd_byte= %02x" % cmd_byte
      if self.m_testutil.traceEnabled():
        self.m_testutil.bufferDetailInfo(cmd_msg)
        self.m_testutil.bufferDetailInfo(repr(spi_session.m_spi_phases))
      else:
        print(cmd_msg)
    #****DEBUG****
    '''
    Initialize the session queue for all phases of this SPI Command.
    '''
    session_queue = pmact.ps_queue_create(self.m_app_conn_handle,
                                          pmact.PS_MODULE_ID_SPI_ACTIVE)
    pmact.ps_queue_clear(session_queue)
    pmact.ps_queue_spi_oe(session_queue, 1)
    pmact.ps_queue_spi_ss(session_queue, self.m_ss_mask)


    '''
    enqueue WREN (write enable)
    ...when WREN is required for data and register write operations
    TODO: this is expedient, but should be in the eeprom application
    layer of code, rather than in the spi transaction layer.

    toggle chip select after wren send to enact it for the following
    of the enqueued writes
    '''
    
    

    
    
    '''
    process fast busy_wait if intrinsic
      instructions for initial status read and follow-on reads
      are in built-once and cached queues
    '''
    
    if spi_session.isBusyPhase():
      slave_busy=True
      read_status = array.array('B', [protocol.RDSR])
      first_pass=True
      
      start_queue, continue_queue=self.getBusyTestQueues(read_status)
      
      while slave_busy:
        if first_pass:
          status_collect = submitQueue(start_queue, self.m_channel_handle, pmact.PS_MODULE_ID_SPI_ACTIVE)
          collect_length, collect_buf = self.devCollect(status_collect)
        else:
          status_collect = submitQueue(continue_queue, self.m_channel_handle, pmact.PS_MODULE_ID_SPI_ACTIVE)
          collect_length, collect_buf = self.devCollect(status_collect)
          
        status=collect_buf[0]
        slave_busy = (status & 1 == 1)
      
      spi_session.nextSpiPhase()  
    
    '''
    process write enable command if intrinsic
      instructions are emitted into the general session queue
    '''
    
    if spi_session.isWrenPhase()==True:
      data_out = array.array('B', [protocol.WREN])
      pmact.ps_queue_spi_write(session_queue, protocol.SPIIO_SINGLE, 8, 1, data_out )

      
      if toggle_select_after_wren:
        '''
        optionally toggle chip select after wren
        spend some clock cycles to permit the slave to process WREN cmd
        before continuing with re-select
        '''
        pmact.ps_queue_spi_ss(session_queue, 0)
        #pmact.ps_queue_spi_delay_ns(session_queue, 1)
        pmact.ps_queue_spi_ss(session_queue, self.m_ss_mask)

      spi_session.nextSpiPhase()


        
    
    '''
    cmd_phase
    ''' 
    if spi_session.isCmdPhase()==True:
      data_out = array.array('B', [cmd_byte])
      
      '''
      look ahead to see if the next phase has same io_mode
      if yes, then delay sending bytes till next phase (at least)
      '''
      
      pmact.ps_queue_spi_write(session_queue, 
                                spi_session.phaseSpec().mode,
                                8,
                                1,
                                data_out)
      #pmact.ps_queue_spi_ss(session_queue, 0)

      '''
      Finish up if no data exchange
      '''
      if spi_session.endOfSession()==True:
        pmact.ps_queue_spi_ss(session_queue, 0)
        pmact.ps_queue_spi_oe(session_queue, 0)        

        collect_handle = submitQueue(session_queue, self.m_channel_handle, pmact.PS_MODULE_ID_SPI_ACTIVE)
        if collect_handle==None:
          self.m_testutil.fatalError("NoneType collected")

          
        _result_length, _dc = self.devCollect(collect_handle)
        pmact.ps_queue_destroy(session_queue)
        return self.SpiResult(True, None, None)
      else:
        spi_session.nextSpiPhase()

    
    '''
    address phase
    '''
    if (spi_session.isAddressPhase()==True):
      # Assemble address byte array per phase.length
      phase=spi_session.currentSpiPhase()

      data_out=testutil.array_u08(phase.length)
      address_shifter=address
      for ndx in range(phase.length):
        data_out[phase.length-1-ndx]=address_shifter&0xff
        address_shifter=address_shifter>>8

      #pmact.ps_queue_spi_ss(session_queue, self.m_ss_mask)
      pmact.ps_queue_spi_write(session_queue,
                               phase.mode,
                               8,
                               phase.length,
                               data_out)

      #self.m_testutil.printArrayHexDump("addr: ", data_out)

        #pmact.ps_queue_spi_ss(session_queue, 0)
        
      if spi_session.endOfSession():
        pmact.ps_queue_spi_ss(session_queue, 0)
        pmact.ps_queue_spi_oe(session_queue, 0)        
        collect = submitQueue(session_queue, self.m_channel_handle, pmact.PS_MODULE_ID_SPI_ACTIVE)
        collect_length, collect_buf = self.devCollect(collect)
        pmact.ps_queue_destroy(session_queue)
        return self.SpiResult(True, collect_length, collect_buf)
        
      spi_session.nextSpiPhase()

    '''
    dummy phase
    '''
    if spi_session.isDummyPhase()==True:

      phase=spi_session.currentSpiPhase()
      prev_phase=spi_session.prevSpiPhase()
      
      pmact.ps_queue_spi_write_word( session_queue,
                                     prev_phase.mode,
                                     8,
                                     phase.length,
                                     0)
      spi_session.nextSpiPhase()


    '''
    data (read or write) phase
    
      sanity check the buffer and length
      if data_read: flush pending writes
    '''
    if spi_session.isDataPhase()==True:
      phase=spi_session.currentSpiPhase()
      length_spec=spi_session.currentSpiPhase().lengthSpec
      data_length_bad=False

      '''
      verify the data length is 'sane'
      '''
          
      if data_length > len(data_buffer):
        data_length_bad
      else:
        if length_spec.fixed == None:
          #depend on range check
          if (data_length<length_spec.rangeMin):
            data_length_bad=True
          elif length_spec.rangeMax!=None:
            if length_spec.rangeMax<data_length:
              data_length_bad=True
        else:      
          if data_length!=length_spec.fixed:
            data_length_bad=True

      if data_length_bad:  
        self.m_testutil.fatalError("cmd data spec error")

      # data_length is valid
      iotype=spi_session.readNotWrite()
      if iotype==protocol.IOTYPE_NONE:
        self.m_testutil.fatalError("illegal data phase spec")


      '''
      write to complete data_write phase
      -or-
      write to complete data_read don't care/read phase
      
      data_out contains either the final segments of bytes ot output including data payload
      or don't chare bytes to stimulate data input from the slave.
      data_out contains only the final non-payload segments of bytes to output
      '''

      if iotype==protocol.IOTYPE_WRITE:
        # append valid buffer bytes to pending data_out
        pmact.ps_queue_spi_delay_cycles(session_queue, 32)        
        pmact.ps_queue_spi_write(session_queue,
                                 phase.mode,
                                 8,
                                 data_length,
                                 data_buffer)

        pmact.ps_queue_spi_ss(session_queue, 0)
        pmact.ps_queue_spi_oe(session_queue, 0)
        #pmact.ps_queue_delay_ms(session_queue, 1)
          
        collect = submitQueue(session_queue, self.m_channel_handle, pmact.PS_MODULE_ID_SPI_ACTIVE)
        _in_length, _in_buf = self.devCollect(collect)
        pmact.ps_queue_destroy(session_queue)
        
        return self.SpiResult(True, data_length, data_buffer)

      else:
        '''
        complete the read phase
        '''
        pmact.ps_queue_spi_read(session_queue,
                                phase.mode,
                                8,
                                data_length)
        
        pmact.ps_queue_spi_ss(session_queue, 0)
        pmact.ps_queue_spi_oe(session_queue, 0)
        
        
        collect = submitQueue(session_queue, self.m_channel_handle, pmact.PS_MODULE_ID_SPI_ACTIVE) 
        if self.m_debug_devCollect:       
          self.m_testutil.bufferDetailInfo("Read collect handle = %d" % collect)
        if collect < 0:
          self.m_testutil.fatalError("Failed Read Queue Submission: collect handle = %d" % collect)

          
        collect_length, collect_buf = self.devCollect(collect)
        
        if not isinstance(collect_buf, coll.Iterable):
          self.m_testutil.fatalError("return buf not 'iterable'")

        if data_length > len(data_buffer) or data_length > len(collect_buf):
          self.m_testutil.fatalError("buffer, size out of sync")
                      
        for index in range(data_length):
          data_buffer[index]=collect_buf[index]

        pmact.ps_queue_destroy(session_queue)
        return self.SpiResult(True, collect_length, data_buffer)
    else:
      self.m_testutil.fatalError("corrupt session/session_spec")  
    self.m_testutil.fatalError("how did I get here?")