Skip to content

Commit b156a8b

Browse files
committed
dcd_stm32_fsdev : Implement FIFO transfer correctly.
1 parent 1799002 commit b156a8b

File tree

1 file changed

+64
-45
lines changed

1 file changed

+64
-45
lines changed

src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c

Lines changed: 64 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
* Portions:
77
* Copyright (c) 2016 STMicroelectronics
88
* Copyright (c) 2019 Ha Thach (tinyusb.org)
9+
* Copyright (c) 2022 Simon Küppers (skuep)
10+
* Copyright (c) 2022 HiFiPhile
911
*
1012
* Permission is hereby granted, free of charge, to any person obtaining a copy
1113
* of this software and associated documentation files (the "Software"), to deal
@@ -987,7 +989,7 @@ bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16
987989
uint8_t const dir = tu_edpt_dir(ep_addr);
988990

989991
xfer->buffer = NULL;
990-
xfer->ff = ff; // TODO support dcd_edpt_xfer_fifo API
992+
xfer->ff = ff;
991993
xfer->total_len = total_bytes;
992994
xfer->queued_len = 0;
993995

@@ -1088,7 +1090,7 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, si
10881090
if (wNBytes & 0x01)
10891091
{
10901092
temp1 = *srcVal;
1091-
*pdwVal = temp2;
1093+
*pdwVal = temp1;
10921094
}
10931095

10941096
return true;
@@ -1100,41 +1102,47 @@ static bool dcd_write_packet_memory(uint16_t dst, const void *__restrict src, si
11001102
* @param wNBytes no. of bytes to be copied.
11011103
* @retval None
11021104
*/
1103-
1104-
// THIS FUNCTION IS UNTESTED
1105-
11061105
static bool dcd_write_packet_memory_ff(tu_fifo_t * ff, uint16_t dst, uint16_t wNBytes)
11071106
{
11081107
// Since we copy from a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
1109-
// Check for first linear part
11101108
tu_fifo_buffer_info_t info;
1111-
tu_fifo_get_read_info(ff, &info); // We want to read from the FIFO
1112-
TU_VERIFY(info.len_lin && dcd_write_packet_memory(dst, info.ptr_lin, info.len_lin)); // and write it into the PMA
1113-
tu_fifo_advance_read_pointer(ff, info.len_lin);
1109+
tu_fifo_get_read_info(ff, &info);
1110+
1111+
uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin);
1112+
uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap);
1113+
1114+
// We want to read from the FIFO and write it into the PMA, if LIN part is ODD and has WRAPPED part,
1115+
// last lin byte will be combined with wrapped part
1116+
// To ensure PMA is always access 16bit aligned (dst aligned to 16 bit)
1117+
if((cnt_lin & 0x01) && cnt_wrap)
1118+
{
1119+
// Copy first linear part
1120+
dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin &~0x01);
1121+
dst += cnt_lin &~0x01;
1122+
1123+
// Copy last linear byte & first wrapped byte
1124+
uint16_t tmp = ((uint8_t*)info.ptr_lin)[cnt_lin - 1] | ((uint16_t)(((uint8_t*)info.ptr_wrap)[0]) << 8U);
1125+
dcd_write_packet_memory(dst, &tmp, 2);
1126+
dst += 2;
11141127

1115-
// Check for wrapped part
1116-
if (info.len_wrap)
1128+
// Copy rest of wrapped byte
1129+
dcd_write_packet_memory(dst, ((uint8_t*)info.ptr_wrap) + 1, cnt_wrap - 1);
1130+
}
1131+
else
11171132
{
1118-
// Update destination pointer
1133+
// Copy linear part
1134+
dcd_write_packet_memory(dst, info.ptr_lin, cnt_lin);
11191135
dst += info.len_lin;
1120-
uint8_t* src = (uint8_t*)info.ptr_wrap;
1121-
uint16_t len2 = info.len_wrap;
11221136

1123-
// Since PMA is accessed 16-bit wise we need to handle the case when a 16 bit value was split
1124-
if (info.len_lin % 2) // If len is uneven there is a byte left to copy
1137+
if(info.len_wrap)
11251138
{
1126-
TU_ASSERT(false); // TODO: Step through and check -> untested
1127-
1128-
uint16_t temp = ((uint8_t *)info.ptr_lin)[info.len_lin-1] | src[0] << 16; // CHECK endianess
1129-
pma[PMA_STRIDE*(dst>>1)] = temp;
1130-
src++;
1131-
len2--;
1139+
// Copy wrapped byte
1140+
dcd_write_packet_memory(dst, info.ptr_wrap, cnt_wrap);
11321141
}
1133-
1134-
TU_VERIFY(dcd_write_packet_memory(dst, src, len2));
1135-
tu_fifo_advance_write_pointer(ff, info.len_wrap);
11361142
}
11371143

1144+
tu_fifo_advance_read_pointer(ff, cnt_lin + cnt_wrap);
1145+
11381146
return true;
11391147
}
11401148

@@ -1178,40 +1186,51 @@ static bool dcd_read_packet_memory(void *__restrict dst, uint16_t src, size_t wN
11781186
* @param wNBytes no. of bytes to be copied.
11791187
* @retval None
11801188
*/
1181-
1182-
// THIS FUNCTION IS UNTESTED
1183-
11841189
static bool dcd_read_packet_memory_ff(tu_fifo_t * ff, uint16_t src, uint16_t wNBytes)
11851190
{
11861191
// Since we copy into a ring buffer FIFO, a wrap might occur making it necessary to conduct two copies
11871192
// Check for first linear part
11881193
tu_fifo_buffer_info_t info;
11891194
tu_fifo_get_write_info(ff, &info); // We want to read from the FIFO
11901195

1191-
TU_VERIFY(info.len_lin && dcd_read_packet_memory(info.ptr_lin, src, info.len_lin));
1192-
tu_fifo_advance_write_pointer(ff, info.len_lin);
1196+
uint16_t cnt_lin = TU_MIN(wNBytes, info.len_lin);
1197+
uint16_t cnt_wrap = TU_MIN(wNBytes - cnt_lin, info.len_wrap);
11931198

1194-
// Check for wrapped part
1195-
if (info.len_wrap)
1199+
// We want to read from PMA and write it into the FIFO, if LIN part is ODD and has WRAPPED part,
1200+
// last lin byte will be combined with wrapped part
1201+
// To ensure PMA is always access 16bit aligned (src aligned to 16 bit)
1202+
if((cnt_lin & 0x01) && cnt_wrap)
11961203
{
1197-
// Update source pointer
1198-
src += info.len_lin;
1204+
// Copy first linear part
1205+
dcd_read_packet_memory(info.ptr_lin, src, cnt_lin &~0x01);
1206+
src += cnt_lin &~0x01;
1207+
1208+
// Copy last linear byte & first wrapped byte
1209+
uint16_t tmp;
1210+
dcd_read_packet_memory(&tmp, src, 2);
1211+
1212+
((uint8_t*)info.ptr_lin)[cnt_lin - 1] = (uint8_t)tmp;
1213+
((uint8_t*)info.ptr_wrap)[0] = (uint8_t)(tmp >> 8U);
1214+
src += 2;
1215+
1216+
// Copy rest of wrapped byte
1217+
dcd_read_packet_memory(((uint8_t*)info.ptr_wrap) + 1, src, cnt_wrap - 1);
1218+
}
1219+
else
1220+
{
1221+
// Copy linear part
1222+
dcd_read_packet_memory(info.ptr_lin, src, cnt_lin);
1223+
src += cnt_lin;
11991224

1200-
// Since PMA is accessed 16-bit wise we need to handle the case when a 16 bit value was split
1201-
if (info.len_lin % 2) // If len is uneven there is a byte left to copy
1225+
if(info.len_wrap)
12021226
{
1203-
TU_ASSERT(false); //TODO: step through -> untested
1204-
uint32_t temp = pma[PMA_STRIDE*(src>>1)];
1205-
*((uint8_t *)info.ptr_wrap++) = ((temp >> 8) & 0xFF);
1206-
src++;
1207-
tu_fifo_advance_write_pointer(ff, 1);
1208-
info.len_wrap--;
1227+
// Copy wrapped byte
1228+
dcd_read_packet_memory(info.ptr_wrap, src, cnt_wrap);
12091229
}
1210-
1211-
TU_VERIFY(dcd_read_packet_memory(info.ptr_wrap, src, info.len_wrap));
1212-
tu_fifo_advance_write_pointer(ff, info.len_wrap);
12131230
}
12141231

1232+
tu_fifo_advance_write_pointer(ff, cnt_lin + cnt_wrap);
1233+
12151234
return true;
12161235
}
12171236

0 commit comments

Comments
 (0)