// Example program #include #include #include #define WORD uint16_t #define DWORD uint32_t #define BYTE uint8_t #define PBYTE uint8_t* #define TRUE 1 #define BOOL int #define QWORD uint64_t #define FALSE 0 #define PDWORD DWORD* #define ENDIAN_SWAP_DWORD(x) (x = (x << 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x >> 24)) #define TLP_MRd32 0x00 #define TLP_MRd64 0x20 #define TLP_MRdLk32 0x01 #define TLP_MRdLk64 0x21 #define TLP_MWr32 0x40 #define TLP_MWr64 0x60 #define TLP_IORd 0x02 #define TLP_IOWr 0x42 #define TLP_CfgRd0 0x04 #define TLP_CfgRd1 0x05 #define TLP_CfgWr0 0x44 #define TLP_CfgWr1 0x45 #define TLP_Cpl 0x0A #define TLP_CplD 0x4A #define TLP_CplLk 0x0B #define TLP_CplDLk 0x4B #define MAX_SIZE_TX 0x3f0 typedef struct tdTLP_HDR { WORD Length : 10; WORD _AT : 2; WORD _Attr : 2; WORD _EP : 1; WORD _TD : 1; BYTE _R1 : 4; BYTE _TC : 3; BYTE _R2 : 1; BYTE TypeFmt; } TLP_HDR, *PTLP_HDR; typedef struct tdTLP_HDR_MRdWr32 { TLP_HDR h; BYTE FirstBE : 4; BYTE LastBE : 4; BYTE Tag; WORD RequesterID; DWORD Address; } TLP_HDR_MRdWr32, *PTLP_HDR_MRdWr32; typedef struct tdTLP_HDR_MRdWr64 { TLP_HDR h; BYTE FirstBE : 4; BYTE LastBE : 4; BYTE Tag; WORD RequesterID; DWORD AddressHigh; DWORD AddressLow; } TLP_HDR_MRdWr64, *PTLP_HDR_MRdWr64; int pfnFT_WritePipe(PBYTE pb, DWORD cb) { printf("writepipe: %d bytes\n", cb); for (int i = 0; i < cb; i++) { printf("%d, ", (int)pb[i]); } printf("\n\n"); return 0; } BOOL DeviceFPGA_TxTlp(PBYTE pbTlp, DWORD cbTlp, BOOL fRdKeepalive, BOOL fFlush) { PBYTE txbuf_pb = (PBYTE)malloc(0x1000 * 32); DWORD txbuf_cb = 0; DWORD status; PBYTE pbTx; QWORD i; DWORD cbTx, cbTxed = 0; if(cbTlp & 0x3) { return FALSE; } if(cbTlp > 4 * 4 + 128) { return FALSE; } if(cbTlp && (txbuf_cb + (cbTlp << 1) + (fFlush ? 8 : 0) >= MAX_SIZE_TX)) { if(!DeviceFPGA_TxTlp(NULL, 0, FALSE, TRUE)) { return FALSE; } } //if(ctxLC->fPrintf[LC_PRINTF_VVV]) { // TLP_Print(ctxLC, pbTlp, cbTlp, TRUE); //} // prepare transmit buffer pbTx = txbuf_pb + txbuf_cb; cbTx = 2 * cbTlp; for(i = 0; i < cbTlp; i += 4) { *(PDWORD)(pbTx + (i << 1)) = *(PDWORD)(pbTlp + i); *(PDWORD)(pbTx + ((i << 1) + 4)) = 0x77000000; // TX TLP } if(cbTlp) { *(PDWORD)(pbTx + ((i << 1) - 4)) = 0x77040000; // TX TLP VALID LAST } if(fRdKeepalive) { cbTx += 8; *(PDWORD)(pbTx + (i << 1)) = 0xffeeddcc; *(PDWORD)(pbTx + ((i << 1) + 4)) = 0x77020000; // LOOPBACK TX } txbuf_cb += cbTx; // transmit if((txbuf_cb >= MAX_SIZE_TX) || (fFlush && txbuf_cb)) { status = pfnFT_WritePipe(txbuf_pb, txbuf_cb); if(status == 0x20) { //DeviceFPGA_ReInitializeFTDI(ctx); // try recovery if possible. status = pfnFT_WritePipe(txbuf_pb, txbuf_cb); } txbuf_cb = 0; //usleep(ctx->perf.DELAY_WRITE); return (0 == status); } return TRUE; } int main() { DWORD tx[4] = { 0 }; PBYTE txb = (PBYTE)tx; PTLP_HDR_MRdWr64 hdrRd64 = (PTLP_HDR_MRdWr64)tx; PTLP_HDR_MRdWr32 hdrRd32 = (PTLP_HDR_MRdWr32)tx; printf("stuff: 0x%x\n", (WORD)(0x123 >> 2)); /* hdrRd32->h.TypeFmt = TLP_MRd64; hdrRd32->h.Length = (WORD)(0x123 >> 2); */ hdrRd32->h.TypeFmt = TLP_MRd32; hdrRd32->h.Length = (WORD)(0x123 >> 2); hdrRd32->RequesterID = 17; hdrRd32->Tag = 0x80; hdrRd32->FirstBE = 0xf; hdrRd32->LastBE = 0xf; hdrRd32->Address = (DWORD)(0x6000); //uint64_t addr = 0x100000000 + 0x6000; //hdrRd64->AddressHigh = (DWORD)(addr >> 32); //hdrRd64->AddressLow = (DWORD)(addr); //printf("sizeof 32: 0x%x\n", sizeof(TLP_HDR_MRdWr32)); //printf("sizeof 64: 0x%x\n", sizeof(TLP_HDR_MRdWr64)); printf("tlp:\n"); for (int i = 0; i < 16; i++) { printf("%d ", (int)txb[i]); //printf("%X ", tx[i]); } printf("\n"); for(int j = 0; j < 4; j++) { ENDIAN_SWAP_DWORD(tx[j]); } DeviceFPGA_TxTlp((PBYTE)tx, /*is32 ? 12 : 16*/ 12, FALSE, TRUE); }