Skip to content

Commit

Permalink
Merge pull request #275 from xross/fix/270
Browse files Browse the repository at this point in the history
Fix/270
  • Loading branch information
xross authored Dec 20, 2021
2 parents b340d33 + e24bf01 commit 49a7eac
Show file tree
Hide file tree
Showing 78 changed files with 2,321 additions and 1,193 deletions.
15 changes: 11 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ _build/
*.pyc
*.expect
*.so
**/bin/**
**/tests/result/*
**/logs*/**
test_results.csv
.DS_Store
Expand All @@ -30,9 +32,14 @@ Installs/
tests/bin.txt
tests/log
tests/test_**/**test_xs2.xn
tests/test_**/**test_xs3_500.xn
tests/test_**/**test_xs3_540.xn
tests/test_**/**test_xs3_600.xn
tests/test_**/**test_xs3_800.xn
tests/test_**/**test_xs3_*.xn
**/venv/**
*.gtkw
**/tests/build/**
**/tests/doc/**
**/build/html/**
**/tests/assets/**
**/build/docstrees/**
tests/report.html
tests/testplan.rst
build/doctrees/environment.pickle
8 changes: 8 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
lib_xud Change Log
==================

2.1.0
-----

* CHANGE: Various optimisations to aid corner-case timings on XS3 based
devices
* CHANGE: Some API functions re-authored in C (from Assembly)
* CHANGE: Testbench now more accurately models XS3 based devices

2.0.2
-----

Expand Down
2 changes: 2 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ The library provides functionality to act as a USB *device* only.

This library is for use with xCORE-200 Series or xCORE-AI series devices only, previous generations of xCORE devices are no longer supported.

Note, at points lib_xud will run in "fast mode" this is a requirement to meet timing.

Features
........

Expand Down
25 changes: 23 additions & 2 deletions lib_xud/api/xud.h
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ XUD_Result_t XUD_SetDevAddr(/*tileref usbtile*/ unsigned addr);
* \param one IN or OUT endpoint identifier to perform the reset on.
* \param two Optional second IN or OUT endpoint structure to perform a reset on.
* \return Either ``XUD_SPEED_HS`` - the host has accepted that this device can execute
* at high speed, ``XUD_SPEED_FS`` - the device is runnig at full speed,
* at high speed, ``XUD_SPEED_FS`` - the device is running at full speed,
* or ``XUD_SPEED_KILL`` to indicate that the USB stack has been shut down
* by another part of the user code (using XUD_Kill). If the last value is
* returned, the endpoint code should call XUD_CloseEndpoint and then
Expand Down Expand Up @@ -552,6 +552,27 @@ void XUD_SetData_Select(chanend c, XUD_ep ep, REFERENCE_PARAM(XUD_Result_t, resu
#define XUD_OSC_MHZ (24)
#endif

#endif //__ASSEMBLER__


/* TODO pack this to save mem
* TODO size of this hardcoded in ResetRpStateByAddr_
*/
typedef struct XUD_ep_info
{
unsigned int array_ptr; // 0
unsigned int xud_chanend; // 1
unsigned int client_chanend; // 2
unsigned int buffer; // 3 Pointer to buffer
unsigned int pid; // 4 Expected out PID
unsigned int epType; // 5 Data
unsigned int actualPid; // 6 Actual OUT PID received for OUT, Length (words) for IN.
unsigned int tailLength; // 7 "tail" length for IN (bytes)
unsigned int epAddress; // 8 EP address assigned by XUD (Used for marking stall etc)
unsigned int resetting; // 9 Flag to indicate to EP a bus-reset occured.
unsigned int halted; // 10 NAK or STALL
unsigned int saved_array_ptr; // 11
} XUD_ep_info;


#endif //__ASSEMBLER__
#endif // _XUD_H_
8 changes: 5 additions & 3 deletions lib_xud/module_build_info
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
VERSION = 2.0.2
VERSION = 2.1.0

MODULE_XCC_FLAGS = $(XCC_FLAGS) \
-O3 \
-DREF_CLK_FREQ=100 \
-fasm-linenum \
-fcomment-asm \
-DXUD_FULL_PIDTABLE=1
-DXUD_FULL_PIDTABLE=1 \
-g

XCC_FLAGS_XUD_IoLoop.S = $(MODULE_XCC_FLAGS) -fschedule -g
XCC_FLAGS_XUD_IoLoop.S = $(MODULE_XCC_FLAGS) -fschedule

XCC_FLAGS_endpoint0.xc = $(MODULE_XCC_FLAGS) -Os
XCC_FLAGS_dfu.xc = $(MODULE_XCC_FLAGS) -Os
Expand Down Expand Up @@ -44,6 +45,7 @@ SOURCE_DIRS = src/core \
EXCLUDE_FILES += XUD_CrcAddrCheck.S \
XUD_G_Crc.S \
XUD_PidJumpTable.S \
XUD_PidJumpTable_RxData.S \
XUD_RxData.S \
XUD_Token_In_DI.S \
XUD_Token_Out_DI.S \
Expand Down
17 changes: 9 additions & 8 deletions lib_xud/src/core/XUD_CrcAddrCheck.S
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@
// r10: Extracted EP number

#ifdef __XS3A__
{in r10, res[RXD]; sub r1, r8, 5} // ldc r1 11
{shr r10, r10, 16; mkmsk r11, r1}
{and r11, r10, r11; shr r4, r10, r1} // r4: Received CRC
{in r10, res[RXD]; sub r1, r8, 5} // ldc r1 11
{shr r10, r10, 16; mkmsk r11, r1}
{and r11, r10, r11; ldw r8, sp[STACK_CRC5TABLE_ADDR]}

ldaw r8, dp[crc5Table_Addr]
ld8u r8, r8[r11] // Correct CRC
{shr r4, r10, r1 // r4: Received CRC
ld8u r8, r8[r11]} // r8: Expected CRC

xor r4, r4, r8 // R4 set to 0 in L code with in from valid tok port
{BRFF_ru6 r4, 5; shr r10, r11, 7} // Extract EP number
//xor r4, r4, r8 // R4 set to 0 in L code with in from valid tok port
{eq r4, r4, r8; shr r10, r11, 7} // Extract EP number
BRFT_ru6 r4, 5

ldw r11, sp[STACK_RXA_PORT] // Wait for RXA to gow low (i.e. end of packet)
ldw r11, sp[STACK_RXA_PORT] // Wait for RXA to gow low (i.e. end of packet)
in r10, res[r11]
bt r10, waitforRXALow0
setc res[RXD], XS1_SETC_RUN_CLRBUF
Expand Down
13 changes: 10 additions & 3 deletions lib_xud/src/core/XUD_IoLoop.S
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ suspend_t_wtwrsths:
#define STACK_TXCRC_INIT (20)
#define STACK_RXCRC_INIT (21)
#define STACK_PIDJUMPTABLE (22)
#define STACK_HANDSHAKETABLEIN (23)
#define STACK_PIDJUMPTABLE_RXDATA (23)
#define STACK_CRC5TABLE_ADDR (24)

// Params
#define STACK_VTOK_PORT (STACK_EXTEND + 1)
Expand Down Expand Up @@ -263,8 +264,13 @@ ConfigSofJump:
#endif
ConfigSofJump_Done:
stw r10, sp[STACK_PIDJUMPTABLE]
ldaw r10, dp[handshakeTable_IN] // Load handshake table
stw r10, sp[STACK_HANDSHAKETABLEIN]

ldaw r10, dp[PidJumpTable_RxData]
stw r10, sp[STACK_PIDJUMPTABLE_RXDATA]

ldaw r10, dp[crc5Table_Addr]
stw r10, sp[STACK_CRC5TABLE_ADDR]


ConfigRxErrEventVector:
setc res[r3], XS1_SETC_COND_EQ
Expand Down Expand Up @@ -374,4 +380,5 @@ Return:

// Tables of tables...
#include "./included/XUD_PidJumpTable.S"
#include "./included/XUD_PidJumpTable_RxData.S"

82 changes: 32 additions & 50 deletions lib_xud/src/core/XUD_Main.xc
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,7 @@ on USB_TILE: clock rx_usb_clk = XS1_CLKBLK_5;
XUD_chan epChans[USB_MAX_NUM_EP];
XUD_chan epChans0[USB_MAX_NUM_EP];

/* TODO pack this to save mem
* TODO size of this hardcoded in ResetRpStateByAddr_
*/
typedef struct XUD_ep_info
{
unsigned int chan_array_ptr; // 0
unsigned int ep_xud_chanend; // 1
unsigned int ep_client_chanend; // 2
unsigned int scratch; // 3 used for datalength in
unsigned int pid; // 4 Expected out PID
unsigned int epType; // 5 Data
unsigned int actualPid; // 6 Actual OUT PID received for OUT, Length (words) for IN.
unsigned int tailLength; // 7 "tail" length for IN (bytes)
unsigned int epAddress; // 8 EP address assigned by XUD (Used for marking stall etc)
unsigned int resetting; // 9 Flag to indicate to EP a bus-reset occured.
} XUD_ep_info;


XUD_ep_info ep_info[USB_MAX_NUM_EP];

Expand All @@ -93,8 +78,8 @@ extern unsigned XUD_LLD_IoLoop(
XUD_EpType epTypeTableOut[], XUD_EpType epTypeTableIn[], XUD_chan epChans[],
int epCount, chanend? c_sof) ;

unsigned handshakeTable_IN[USB_MAX_NUM_EP_IN] = {0}; // 0 or STALL
unsigned handshakeTable_OUT[USB_MAX_NUM_EP_OUT]; // NAK or STALL
unsigned ep_addr[USB_MAX_NUM_EP];

unsigned sentReset=0;

unsigned crcmask = 0b11111111111;
Expand Down Expand Up @@ -181,29 +166,25 @@ static int XUD_Manager_loop(XUD_chan epChans0[], XUD_chan epChans[], chanend ?c
#endif

#ifdef XUD_SIM_XSIM
#if (XUD_CORE_CLOCK > 500)
#define RX_RISE_DELAY 2
#define RX_FALL_DELAY 5
#define TX_RISE_DELAY 2
#define TX_FALL_DELAY 3
#elif (XUD_CORE_CLOCK > 400)
#define RX_RISE_DELAY 5
#define RX_FALL_DELAY 5
#define TX_RISE_DELAY 2
#define TX_FALL_DELAY 3
#else /* 400 */
#define RX_RISE_DELAY 3
#define RX_FALL_DELAY 5
#define TX_RISE_DELAY 3
#define TX_FALL_DELAY 3
#if (XUD_CORE_CLOCK >= 700)
#define RX_RISE_DELAY 0
#define RX_FALL_DELAY 0
#define TX_RISE_DELAY 0
#define TX_FALL_DELAY 7
#elif (XUD_CORE_CLOCK >= 600)
#define RX_RISE_DELAY 0
#define RX_FALL_DELAY 0
#define TX_RISE_DELAY 0
#define TX_FALL_DELAY 5
#else
#error XUD_CORE_CLOCK must be >= 600
#endif
#else
#if (XUD_CORE_CLOCK >= 600)
#define RX_RISE_DELAY 1
#define RX_FALL_DELAY 1
#define TX_RISE_DELAY 1
#define TX_FALL_DELAY 1

#elif (XUD_CORE_CLOCK >= 500)
#define RX_RISE_DELAY 1
#define RX_FALL_DELAY 0
Expand All @@ -230,20 +211,18 @@ static int XUD_Manager_loop(XUD_chan epChans0[], XUD_chan epChans[], chanend ?c
set_port_inv(p_usb_clk);
set_port_sample_delay(p_usb_clk);

#if !defined(XUD_SIM_XSIM)
//This delay controls the capture of rdy
// This delay controls the capture of rdy
set_clock_rise_delay(tx_usb_clk, TX_RISE_DELAY);

//this delay controls the launch of data.
// This delay controls the launch of data.
set_clock_fall_delay(tx_usb_clk, TX_FALL_DELAY);

//this delay th capture of the rdyIn and data.
// This delay the capture of the rdyIn and data.
set_clock_rise_delay(rx_usb_clk, RX_RISE_DELAY);
set_clock_fall_delay(rx_usb_clk, RX_FALL_DELAY);
#endif

#ifdef __XS3A__
set_pad_delay(flag1_port, 3);
set_pad_delay(flag1_port, 2);
#else
set_pad_delay(flag1_port, 2);
#endif
Expand Down Expand Up @@ -312,7 +291,7 @@ static int XUD_Manager_loop(XUD_chan epChans0[], XUD_chan epChans[], chanend ?c
/* Sample line state and check for reset (or suspend) */
XUD_LineState_t ls = XUD_HAL_GetLineState();
if(ls == XUD_LINESTATE_SE0)
reset == 1;
reset = 1;
else
reset = 0;
}
Expand All @@ -337,7 +316,6 @@ static int XUD_Manager_loop(XUD_chan epChans0[], XUD_chan epChans[], chanend ?c
/* Test if coming back from reset or suspend */
if(reset == 1)
{

if(!sentReset)
{
SendResetToEps(epChans0, epChans, epTypeTableOut, epTypeTableIn, noEpOut, noEpIn, USB_RESET_TOKEN);
Expand Down Expand Up @@ -484,16 +462,16 @@ int XUD_Main(chanend c_ep_out[], int noEpOut,

for(int i = 0; i < USB_MAX_NUM_EP_OUT; i++)
{
handshakeTable_OUT[i] = USB_PIDn_NAK;
ep_info[i].epAddress = i;
ep_info[i].resetting = 0;
ep_info[i].halted = USB_PIDn_NAK;
}

for(int i = 0; i < USB_MAX_NUM_EP_IN; i++)
{
handshakeTable_IN[i] = 0;
ep_info[USB_MAX_NUM_EP_OUT+i].epAddress = (i | 0x80);
ep_info[USB_MAX_NUM_EP_OUT+i].resetting = 0;
ep_info[USB_MAX_NUM_EP_OUT+i].halted = 0;
}

/* Populate arrays of channels and status flag tabes */
Expand All @@ -505,16 +483,18 @@ int XUD_Main(chanend c_ep_out[], int noEpOut,
epChans0[i] = XUD_Sup_GetResourceId(c_ep_out[i]);

asm("ldaw %0, %1[%2]":"=r"(x):"r"(epChans),"r"(i));
ep_info[i].chan_array_ptr = x;
ep_info[i].array_ptr = x;
ep_info[i].saved_array_ptr = 0;

asm("mov %0, %1":"=r"(x):"r"(c_ep_out[i]));
ep_info[i].ep_xud_chanend = x;
ep_info[i].xud_chanend = x;

asm("getd %0, res[%1]":"=r"(x):"r"(c_ep_out[i]));
ep_info[i].ep_client_chanend = x;
ep_info[i].client_chanend = x;

asm("ldaw %0, %1[%2]":"=r"(x):"r"(ep_info),"r"(i*sizeof(XUD_ep_info)/sizeof(unsigned)));
outuint(c_ep_out[i], x);
ep_addr[i] = x;

epStatFlagTableOut[i] = epTypeTableOut[i] & XUD_STATUS_ENABLE;
epTypeTableOut[i] = epTypeTableOut[i] & 0x7FFFFFFF;
Expand All @@ -537,17 +517,19 @@ int XUD_Main(chanend c_ep_out[], int noEpOut,
epChans0[i+USB_MAX_NUM_EP_OUT] = XUD_Sup_GetResourceId(c_ep_in[i]);

asm("ldaw %0, %1[%2]":"=r"(x):"r"(epChans),"r"(USB_MAX_NUM_EP_OUT+i));
ep_info[USB_MAX_NUM_EP_OUT+i].chan_array_ptr = x;
ep_info[USB_MAX_NUM_EP_OUT+i].array_ptr = x;
ep_info[USB_MAX_NUM_EP_OUT+i].saved_array_ptr = 0;

asm("mov %0, %1":"=r"(x):"r"(c_ep_in[i]));
ep_info[USB_MAX_NUM_EP_OUT+i].ep_xud_chanend = x;
ep_info[USB_MAX_NUM_EP_OUT+i].xud_chanend = x;

asm("getd %0, res[%1]":"=r"(x):"r"(c_ep_in[i]));
ep_info[USB_MAX_NUM_EP_OUT+i].ep_client_chanend = x;
ep_info[USB_MAX_NUM_EP_OUT+i].client_chanend = x;

asm("ldaw %0, %1[%2]":"=r"(x):"r"(ep_info),"r"((USB_MAX_NUM_EP_OUT+i)*sizeof(XUD_ep_info)/sizeof(unsigned)));

outuint(c_ep_in[i], x);
ep_addr[USB_MAX_NUM_EP_OUT+i] = x;

ep_info[USB_MAX_NUM_EP_OUT+i].pid = USB_PIDn_DATA0;

Expand Down
Loading

0 comments on commit 49a7eac

Please sign in to comment.