Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2e7d7078fc50
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: a0bd7a2143b8
Choose a head ref
  • 1 commit
  • 2 files changed
  • 1 contributor

Commits on Sep 10, 2020

  1. Copy the full SHA
    a0bd7a2 View commit details
Showing with 135 additions and 20 deletions.
  1. +127 −20 scopeprotocols/SPIFlashDecoder.cpp
  2. +8 −0 scopeprotocols/SPIFlashDecoder.h
147 changes: 127 additions & 20 deletions scopeprotocols/SPIFlashDecoder.cpp
Original file line number Diff line number Diff line change
@@ -42,6 +42,12 @@ SPIFlashDecoder::SPIFlashDecoder(string color)
CreateInput("spi_in");
CreateInput("spi_out");
CreateInput("qspi");

m_typename = "Flash Type";
m_parameters[m_typename] = FilterParameter(FilterParameter::TYPE_ENUM, Unit(Unit::UNIT_COUNTS));
m_parameters[m_typename].AddEnumValue("Generic (3-byte address)", FLASH_TYPE_GENERIC_3BYTE_ADDRESS);
m_parameters[m_typename].AddEnumValue("Winbond W25N", FLASH_TYPE_WINBOND_W25N);
m_parameters[m_typename].SetIntVal(FLASH_TYPE_GENERIC_3BYTE_ADDRESS);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -105,6 +111,8 @@ void SPIFlashDecoder::Refresh()
{
ClearPackets();

FlashType flashtype = (FlashType)m_parameters[m_typename].GetIntVal();

//Input/output x1 inputs are required
if( (m_inputs[0].m_channel == NULL) || (m_inputs[1].m_channel == NULL) )
{
@@ -191,14 +199,22 @@ void SPIFlashDecoder::Refresh()
// JEDEC standard commands (in numerical order)

//Write the status register
//TODO: address is W25N specific
case 0x01:
case 0x1f:
current_cmd = SPIFlashSymbol::CMD_WRITE_STATUS_REGISTER;
state = STATE_ADDRESS;
address_bytes_left = 1;
addr = 0;
addr_start = din->m_offsets[iin+1];

//We need an address here
if(flashtype == FLASH_TYPE_WINBOND_W25N)
{
state = STATE_ADDRESS;
address_bytes_left = 1;
addr = 0;
addr_start = din->m_offsets[iin+1];
}

//No address for standard flash
else
state = STATE_WRITE_DATA;

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_CONTROL];
break;
@@ -207,21 +223,43 @@ void SPIFlashDecoder::Refresh()
case 0x02:
current_cmd = SPIFlashSymbol::CMD_PAGE_PROGRAM;
state = STATE_ADDRESS;
address_bytes_left = 2; //TODO: this is device specific, current value is for W25N
addr = 0;
addr_start = din->m_offsets[iin+1];

switch(flashtype)
{
case FLASH_TYPE_WINBOND_W25N:
address_bytes_left = 2;
break;

case FLASH_TYPE_GENERIC_3BYTE_ADDRESS:
default:
address_bytes_left = 3;
break;
}

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_COMMAND];
break;

//Slow read (no dummy clocks)
case 0x03:
current_cmd = SPIFlashSymbol::CMD_READ;
state = STATE_ADDRESS;
address_bytes_left = 2; //TODO: this is device specific, current value is for W25N
addr = 0;
addr_start = din->m_offsets[iin+1];

switch(flashtype)
{
case FLASH_TYPE_WINBOND_W25N:
address_bytes_left = 2;
break;

case FLASH_TYPE_GENERIC_3BYTE_ADDRESS:
default:
address_bytes_left = 3;
break;
}

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_DATA_READ];
break;

@@ -244,24 +282,44 @@ void SPIFlashDecoder::Refresh()
//Fast read (with dummy clocks)
case 0x0b:
current_cmd = SPIFlashSymbol::CMD_FAST_READ;
state = STATE_ADDRESS;
address_bytes_left = 2; //TODO: this is device specific, current value is for W25N

addr = 0;
addr_start = din->m_offsets[iin+1];

switch(flashtype)
{
case FLASH_TYPE_WINBOND_W25N:
address_bytes_left = 2;
state = STATE_ADDRESS;
break;

case FLASH_TYPE_GENERIC_3BYTE_ADDRESS:
default:
state = STATE_DUMMY_BEFORE_ADDRESS;
address_bytes_left = 3;
break;
}

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_DATA_READ];
break;

//Read the status register
//TODO: address is is W25N specific, normal NOR flash jumps right into the data
//(need enum parameters!!!)
case 0x0f:
case 0x5f:
current_cmd = SPIFlashSymbol::CMD_READ_STATUS_REGISTER;
state = STATE_ADDRESS;
address_bytes_left = 1;
addr = 0;
addr_start = din->m_offsets[iin+1];

//We need an address here
if(flashtype == FLASH_TYPE_WINBOND_W25N)
{
state = STATE_ADDRESS;
address_bytes_left = 1;
addr = 0;
addr_start = din->m_offsets[iin+1];
}

//No address for standard flash
else
state = STATE_READ_DATA;

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_STATUS];
break;
@@ -270,10 +328,21 @@ void SPIFlashDecoder::Refresh()
case 0x32:
current_cmd = SPIFlashSymbol::CMD_QUAD_PAGE_PROGRAM;
state = STATE_ADDRESS;
address_bytes_left = 2; //TODO: this is device specific, current value is for W25N
addr = 0;
addr_start = din->m_offsets[iin+1];

switch(flashtype)
{
case FLASH_TYPE_WINBOND_W25N:
address_bytes_left = 2;
break;

case FLASH_TYPE_GENERIC_3BYTE_ADDRESS:
default:
address_bytes_left = 3;
break;
}

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_DATA_WRITE];
break;

@@ -283,10 +352,21 @@ void SPIFlashDecoder::Refresh()
case 0x6b:
current_cmd = SPIFlashSymbol::CMD_READ_1_1_4;
state = STATE_ADDRESS;
address_bytes_left = 2; //TODO: this is device specific, current value is for W25N
addr = 0;
addr_start = din->m_offsets[iin+1];

switch(flashtype)
{
case FLASH_TYPE_WINBOND_W25N:
address_bytes_left = 2;
break;

case FLASH_TYPE_GENERIC_3BYTE_ADDRESS:
default:
address_bytes_left = 3;
break;
}

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_DATA_READ];
break;

@@ -306,21 +386,43 @@ void SPIFlashDecoder::Refresh()
case 0xd8:
current_cmd = SPIFlashSymbol::CMD_BLOCK_ERASE;
state = STATE_ADDRESS;
address_bytes_left = 2; //TODO: this is device specific, current value is for W25N
addr = 0;
addr_start = din->m_offsets[iin+1];

switch(flashtype)
{
case FLASH_TYPE_WINBOND_W25N:
address_bytes_left = 2;
break;

case FLASH_TYPE_GENERIC_3BYTE_ADDRESS:
default:
address_bytes_left = 3;
break;
}

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_COMMAND];
break;

//1-4-4 fast read
case 0xeb:
current_cmd = SPIFlashSymbol::CMD_READ_1_4_4;
state = STATE_QUAD_ADDRESS;
address_bytes_left = 2; //TODO: this is device specific, current value is for W25N
addr = 0;
addr_start = din->m_offsets[iin+1];

switch(flashtype)
{
case FLASH_TYPE_WINBOND_W25N:
address_bytes_left = 2;
break;

case FLASH_TYPE_GENERIC_3BYTE_ADDRESS:
default:
address_bytes_left = 3;
break;
}

pack->m_displayBackgroundColor = m_backgroundColors[COLOR_DATA_READ];
break;

@@ -492,8 +594,13 @@ void SPIFlashDecoder::Refresh()
switch(current_cmd)
{
case SPIFlashSymbol::CMD_READ:

//W25N is weird and needs dummy clocks even with the slow 0x03 read instruction
state = STATE_DUMMY_BEFORE_DATA;
if(flashtype == FLASH_TYPE_WINBOND_W25N)
state = STATE_DUMMY_BEFORE_DATA;
else
state = STATE_READ_DATA;

break;

case SPIFlashSymbol::CMD_FAST_READ:
8 changes: 8 additions & 0 deletions scopeprotocols/SPIFlashDecoder.h
Original file line number Diff line number Diff line change
@@ -132,13 +132,21 @@ class SPIFlashDecoder : public PacketDecoder
VENDOR_ID_WINBOND = 0xef
};

enum FlashType
{
FLASH_TYPE_GENERIC_3BYTE_ADDRESS,
FLASH_TYPE_WINBOND_W25N
};

virtual bool CanMerge(Packet* a, Packet* b);
virtual Packet* CreateMergedHeader(Packet* pack);

PROTOCOL_DECODER_INITPROC(SPIFlashDecoder)

protected:
std::string GetPartID(SPIFlashWaveform* cap, const SPIFlashSymbol& s, int i);

std::string m_typename;
};

#endif