Jump to content
  • 0

AD2 and eMMC protocol


Sid Price

Question

13 answers to this question

Recommended Posts

Hi @Sid Price

image.thumb.png.4a2ee857566703d488bec47232e74818.png

// rgData: input, raw digital data array
// rgValue: output, decoded data array
// rgFlag: output, decoded flag array

cData = rgData.length
clkPrev = 0

const stIdle = 0
const stStart = 1
const stDir = 2
const stCmd = 3
const stCont = 4
const stCrc = 5
const stEnd = 6

stNext = state = stIdle
cBit  = 0
iStart = 0
fsData = 0

// DIO: 0=CLK 1=CMD

for(var i = 0; i < cData; i++){
    sample = rgData[i]
    clk = sample & 1 
    if(clkPrev == 0 && clk != 0){ // sample on clock rising edge 
        // process the next data bit
        bit = (sample >> 1) & 1
        
        // MSbit first deserialization
        fsData <<= 1 
        if(bit != 0) fsData |= 1
        cBit++
        
        switch(state){
            case stIdle:
                if(bit==0){ // sync, change state
                    stNext = stStart
                }
                cBit = 0
                break
            case stStart:
                stNext = stDir
                cBit = 0
                break
            case stDir:
                stNext = stCmd
                cBit = 0
                break
            case stCmd:
                if(cBit==6){
                    stNext = stCont
                    cBit = 0
                }
                break
            case stCont:
                if(cBit==32){
                    stNext = stCrc
                    cBit = 0
                }
                break
            case stCrc:
                if(cBit==7){
                    stNext = stEnd
                    cBit = 0
                }
                break
            case stEnd:
            default:
                stNext = stIdle
                cBit = 0
                break
        }
        // update decoded output 
        if(cBit==0){
            for(var j = iStart; j < i; j++){
                rgFlag[j] = state
                rgValue[j] = fsData
            }
            fsData = 0
            iStart = i
            state = stNext
        }
    }
    clkPrev = clk
}


function Value2Text(flag, value){
  switch(flag){
    case 0: return "X"
    case 1: return "Start"
    case 2: return value?"Host":"Device"
    case 3: return "CMD:"+value.toString(16) // hexadecimal representation
    case 4: return "Cont:"+value.toString(16) 
    case 5: return "CRC:"+value.toString(16)
    case 6: return "End:"+value.toString(2) // binary representation
    default: return value.toString(16)
  }
}

 

Link to comment
Share on other sites

Hi @Sid Price

This should work now.

In the earlier script the sequencing was wrong, wrong value got stored...
Now it is a simplified, the data is sampled on falling edge and updated for nicer display on the active rising edge.

image.png.55099d66758607e53508abaf81f6e7ea.png

// rgData: input, raw digital data array
// rgValue: output, decoded data array
// rgFlag: output, decoded flag array

cData = rgData.length
clk = 0

const stIdle = 0
const stStart = 1
const stDir = 2
const stCmd = 3
const stCont = 4
const stCrc = 5
const stEnd = 6

state = stIdle
cBit  = 0
iStart = 0
fsData = 0
bit = 0
// DIO: 0=CLK 1=CMD

for(var i = 0; i < cData; i++){
    sample = rgData[i]
    clkPrev = clk
    clk = sample & 1 
    if(clkPrev==clk) continue
    if(!clk){ // sample on clock falling edge 
        // process the next data bit
        bit = (sample >> 1) & 1
        // MSbit first deserialization
        fsData <<= 1 
        if(bit != 0) fsData |= 1

        if(cBit>0) continue
        switch(state){
        case stIdle:
            if(bit==0){ // sync, change state
                state = stStart
            }
            cBit = 1
            break
        case stStart:
            state = stDir
            cBit = 1
            break
        case stDir:
            state = stCmd
            cBit = 6
            break 
        case stCmd:
            state = stCont
            cBit = 32
            break
        case stCont:
            state = stCrc
            cBit = 7
            break
        case stCrc:
            state = stEnd
            cBit = 1
            break
        case stEnd:
        default:
            state = stIdle
            cBit = 1
            break
        }
    }else { // update on on the other edge 
        cBit--
        if(cBit>0) continue
        for(var j = iStart; j < i; j++){
            rgFlag[j] = state
            rgValue[j] = fsData
        }
        fsData = 0
        iStart = i
    }
}


function Value2Text(flag, value){
  switch(flag){
    case 0: return "X"
    case 1: return "Start"
    case 2: return value?"Host":"Device"
    case 3: return "CMD:"+value.toString(16) // hexadecimal representation
    case 4: return "Cont:"+value.toString(16) 
    case 5: return "CRC:"+value.toString(16)
    case 6: return "End:"+value.toString(2) // binary representation
    default: return value.toString(16)
  }
}

For the next software version I have added real data for the debugger. It will be easier to debug.
Thank you for the observation.

image.thumb.png.71310c274583f68efad1936ff250f1e2.png

Link to comment
Share on other sites

@attila I am finally back to trying to get an eMMC decoder working and getting more confused, I hope I can get a nudge in the right direction. This is my attempt at a decoder, it does not produce a display at all:

// rgData: input, raw digital data array
// rgValue: output, decoded data array
// rgFlag: output, decoded flag array

samples = rgData.length
synced = 0
bit  = 47
clkState = 0
not_synced = 0
sync_bit = 1
tx_bit = 2
cmd_index = 3
content = 4
crc = 5
end = 6
temp = 1

for(var i = 0; i < samples; i++){
	//
	// check if the clock input is low, if so we done for this loop
	//
    inputSample = rgData[i] ;
    newClkState = inputSample & 0x01 ;
    if ( (inputSample & 0x01) != 0) {
        //
        // check if the clock just went high
//
if ( clkState == 0) {
    //
    // Process the next data bit
    //
    inputData = (inputSample & 0x02) >> 1 ;
    if ( synced == 0) {
        if ( inputData != 0) {   // Data == 1?
        	rgFlag[i] = not_synced ;
        }
        else {   // Data == 0
        	rgFlag[i] = sync_bit ;
        	synced = 1 ;
        }
    }
    else {   // In Sync
        if ( bit == 46) {   // Transmission bit?
        	rgFlag[i] = tx_bit ;
        
        }
        else if ((bit <= 45) && (bit >= 40)) {   // Command Index Field?
        	rgFlag[i] = cmd_index ;
        }
        else if (( bit <= 39) && ( bit >= 8)) {   // Content field?
        	rgFlag[i] = content ;
        }
        else if ( (bit <= 7) && (bit >= 1) ) {   // CRC?
        	rgFlag[i] = crc ;
        }
        else {   // End bit
        	rgFlag = end ;
        }
     }
        bit -= 1 ;
        rgValue[i] = inputData;
        }
    }
    clkState = newClkState ;
}

function Value2Text(flag, value){
  switch(flag){
    case 0: return "X";
    default: return value.toString(2);
  }
}

I have tried to use the decoder debugger window, but again I am not having much success. The logic instrument has a large capture that I can see the data I expect using the "Bus" decoder with the clock and a single data bit. When I enter the debugger from the above decoder the number of samples is only 100. Plus, when I try to evaluate "rgData[0]" in the debugger console, the result is "undefined".

I am obviously missing something important here and I hope you can reveal that too me.

Note that I need to still add the correct display code in the "Value2Text" function, however it should still show something I think.

Link to comment
Share on other sites

@attila

Sad to report that the decoder does not correctly decode the capture for me. The attached screen shot shows the decoder incorrectly shows "Device: 0" (I added the value after it) when the CMD input is "1". 

cap1.PNG.b92fc77548fe6f20b808d7a54491748b.PNG

 

I have tried to use the script debugger to investigate but it appears the debugger only receives a very limited number of samples (100).

 

How should one proceed to debug this? It is a great example and has helped me understand the way to write a decoder.

Sid

Link to comment
Share on other sites

@attilaThe only change I have made is to the output function so I could check what the "DIR" bit value was:

function Value2Text(flag, value){
  switch(flag){
    case 0: return "X"
    case 1: return "Start"
    case 2: return (value?"Host: ":"Device: ")+value.toString(2)
    case 3: return "CMD:"+value.toString(16) // hexadecimal representation
    case 4: return "Cont:"+value.toString(16) 
    case 5: return "CRC:"+value.toString(16)
    case 6: return "End:"+value.toString(2) // binary representation
    default: return value.toString(16)
  }
}

 

Link to comment
Share on other sites

@attilaI just hooked up my new PCB and tried this new decoder, so far it seems to work. I hope to do a little deeper decoding of some of the fields at some point, perhaps after the debugger update :) I am really looking forward to that.

 

Again, I really appreciate your help with this, thank you.

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...