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
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")
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()
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?")