mirror of
https://github.com/dwhinham/mt32-pi.git
synced 2026-10-27 06:21:59 +00:00
Update to circle-stdlib v15.7/Circle Step 44
This commit is contained in:
1 parent
7a04338cd2
commit
25c5d654bc
13 files changed
+4
-2412
No files matched your search
@@ -26,6 +26,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
### Changed
|
||||
|
||||
- Update to circle-stdlib v15.7/Circle Step 44.
|
||||
- Update to libmt32emu v2.5.0.
|
||||
- Update to FluidSynth v2.2.1.
|
||||
- The activity LED no longer illuminates for System Common or System Real-Time messages.
|
||||
|
||||
@@ -16,16 +16,7 @@ $(CIRCLE_STDLIB_CONFIG) $(CIRCLE_CONFIG)&:
|
||||
$(CIRCLESTDLIBHOME)/configure --raspberrypi=$(RASPBERRYPI) --prefix=$(PREFIX)
|
||||
|
||||
# Apply patches
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-minimal-usb-drivers.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-pi4-usb-fix.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-fix-hard-errors.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-retry-bulk-transfer.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-low-speed-bulk-fix.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-move-dma-defines.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-add-parity32.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-add-iec958.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-add-hdmi-sound-base.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-allow-any-screen-size.patch
|
||||
@patch -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-44-minimal-usb-drivers.patch
|
||||
|
||||
ifeq ($(strip $(GC_SECTIONS)),1)
|
||||
# Enable function/data sections for circle-stdlib
|
||||
@@ -123,16 +114,7 @@ clean:
|
||||
#
|
||||
veryclean: clean
|
||||
# Reverse patches
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-allow-any-screen-size.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-add-hdmi-sound-base.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-add-iec958.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-add-parity32.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-move-dma-defines.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-low-speed-bulk-fix.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-retry-bulk-transfer.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-usb-fix-hard-errors.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-pi4-usb-fix.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-43.3-minimal-usb-drivers.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(CIRCLEHOME) < patches/circle-44-minimal-usb-drivers.patch
|
||||
@patch -R -N -p1 --no-backup-if-mismatch -r - -d $(FLUIDSYNTHHOME) < patches/fluidsynth-2.2.1-circle.patch
|
||||
|
||||
# Clean circle-stdlib
|
||||
|
||||
Vendored
+1
-1
Submodule external/circle-stdlib updated: 44ae08ea8a...0c00c192fe.
File diff suppressed because it is too large.
Load diff
@@ -1,190 +0,0 @@
|
||||
From 68ae9ec6cce5d5c37e21cada0093200f22ef2d77 Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Sun, 28 Mar 2021 14:55:15 +0200
|
||||
Subject: [PATCH] soundbasedevice: Add IEC958 (S/PDIF) hardware format
|
||||
|
||||
---
|
||||
include/circle/soundbasedevice.h | 11 ++++-
|
||||
lib/soundbasedevice.cpp | 85 +++++++++++++++++++++++++++++++-
|
||||
2 files changed, 93 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/circle/soundbasedevice.h b/include/circle/soundbasedevice.h
|
||||
index 07a6686c..6b254e7c 100644
|
||||
--- a/include/circle/soundbasedevice.h
|
||||
+++ b/include/circle/soundbasedevice.h
|
||||
@@ -2,7 +2,7 @@
|
||||
// soundbasedevice.h
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2017-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2017-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -28,12 +28,19 @@
|
||||
#define SOUND_MAX_SAMPLE_SIZE (sizeof (u32))
|
||||
#define SOUND_MAX_FRAME_SIZE (SOUND_HW_CHANNELS * SOUND_MAX_SAMPLE_SIZE)
|
||||
|
||||
+// IEC958 (S/PDIF)
|
||||
+#define IEC958_FRAMES_PER_BLOCK 192
|
||||
+#define IEC958_SUBFRAMES_PER_BLOCK (SOUND_HW_CHANNELS * IEC958_FRAMES_PER_BLOCK)
|
||||
+#define IEC958_STATUS_BYTES 5
|
||||
+#define IEC958_B_FRAME_PREAMBLE 0x0F
|
||||
+
|
||||
enum TSoundFormat /// All supported formats are interleaved little endian
|
||||
{
|
||||
SoundFormatUnsigned8, /// Not supported as hardware format
|
||||
SoundFormatSigned16,
|
||||
SoundFormatSigned24,
|
||||
SoundFormatUnsigned32, /// Not supported as write format
|
||||
+ SoundFormatIEC958, /// Not supported as write format
|
||||
SoundFormatUnknown
|
||||
};
|
||||
|
||||
@@ -168,6 +175,8 @@ class CSoundBaseDevice : public CDevice /// Base class of sound devices
|
||||
void *m_pCallbackParam;
|
||||
|
||||
CSpinLock m_SpinLock;
|
||||
+
|
||||
+ u8 m_uchIEC958Status[IEC958_STATUS_BYTES];
|
||||
};
|
||||
|
||||
#endif
|
||||
diff --git a/lib/soundbasedevice.cpp b/lib/soundbasedevice.cpp
|
||||
index b156239b..d3788495 100644
|
||||
--- a/lib/soundbasedevice.cpp
|
||||
+++ b/lib/soundbasedevice.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// soundbasedevice.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2017-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2017-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -18,6 +18,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
#include <circle/soundbasedevice.h>
|
||||
+#include <circle/macros.h>
|
||||
#include <circle/util.h>
|
||||
#include <assert.h>
|
||||
|
||||
@@ -46,6 +47,7 @@ CSoundBaseDevice::CSoundBaseDevice (TSoundFormat HWFormat, u32 nRange32, unsigne
|
||||
break;
|
||||
|
||||
case SoundFormatSigned24:
|
||||
+ case SoundFormatIEC958:
|
||||
m_nHWSampleSize = sizeof (u32);
|
||||
m_nRangeMin = -(1 << 23)+1;
|
||||
m_nRangeMax = (1 << 23)-1;
|
||||
@@ -67,6 +69,33 @@ CSoundBaseDevice::CSoundBaseDevice (TSoundFormat HWFormat, u32 nRange32, unsigne
|
||||
}
|
||||
|
||||
m_nHWFrameSize = SOUND_HW_CHANNELS * m_nHWSampleSize;
|
||||
+
|
||||
+ if (m_HWFormat == SoundFormatIEC958)
|
||||
+ {
|
||||
+ u8 uchFS, uchOrigFS;
|
||||
+ switch (m_nSampleRate)
|
||||
+ {
|
||||
+ case 22050: uchFS = 4; uchOrigFS = 11; break;
|
||||
+ case 24000: uchFS = 6; uchOrigFS = 9; break;
|
||||
+ case 32000: uchFS = 3; uchOrigFS = 12; break;
|
||||
+ case 44100: uchFS = 0; uchOrigFS = 15; break;
|
||||
+ case 48000: uchFS = 2; uchOrigFS = 13; break;
|
||||
+ case 88200: uchFS = 8; uchOrigFS = 7; break;
|
||||
+ case 96000: uchFS = 10; uchOrigFS = 5; break;
|
||||
+ case 176400: uchFS = 12; uchOrigFS = 3; break;
|
||||
+ case 192000: uchFS = 14; uchOrigFS = 1; break;
|
||||
+
|
||||
+ default:
|
||||
+ assert (0);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ m_uchIEC958Status[0] = 0b100; // consumer, PCM, no copyright, no pre-emphasis
|
||||
+ m_uchIEC958Status[1] = 0; // category (general mode)
|
||||
+ m_uchIEC958Status[2] = 0; // source number, take no account of channel number
|
||||
+ m_uchIEC958Status[3] = uchFS; // sampling frequency
|
||||
+ m_uchIEC958Status[4] = 0b1011 | (uchOrigFS << 4); // 24 bit samples, original freq.
|
||||
+ }
|
||||
}
|
||||
|
||||
CSoundBaseDevice::~CSoundBaseDevice (void)
|
||||
@@ -279,7 +308,8 @@ unsigned CSoundBaseDevice::GetChunk (s16 *pBuffer, unsigned nChunkSize)
|
||||
unsigned CSoundBaseDevice::GetChunk (u32 *pBuffer, unsigned nChunkSize)
|
||||
{
|
||||
assert ( m_HWFormat == SoundFormatSigned24
|
||||
- || m_HWFormat == SoundFormatUnsigned32);
|
||||
+ || m_HWFormat == SoundFormatUnsigned32
|
||||
+ || m_HWFormat == SoundFormatIEC958);
|
||||
|
||||
return GetChunkInternal (pBuffer, nChunkSize);
|
||||
}
|
||||
@@ -340,6 +370,18 @@ void CSoundBaseDevice::ConvertSoundFormat (void *pTo, const void *pFrom)
|
||||
*pValue = (u32) llValue;
|
||||
} break;
|
||||
|
||||
+ case SoundFormatIEC958: {
|
||||
+ nValue >>= 4;
|
||||
+ nValue &= 0xFFFFFF0;
|
||||
+ if (parity32 (nValue))
|
||||
+ {
|
||||
+ nValue |= 0x80000000;
|
||||
+ }
|
||||
+
|
||||
+ s32 *pValue = reinterpret_cast<s32 *> (pTo);
|
||||
+ *pValue = nValue;
|
||||
+ } break;
|
||||
+
|
||||
default:
|
||||
assert (0);
|
||||
break;
|
||||
@@ -382,6 +424,45 @@ unsigned CSoundBaseDevice::GetChunkInternal (void *pBuffer, unsigned nChunkSize)
|
||||
nBytes += m_nHWFrameSize;
|
||||
}
|
||||
|
||||
+ // insert control channel and parity bits, and preamble into IEC958 block
|
||||
+ if (m_HWFormat == SoundFormatIEC958)
|
||||
+ {
|
||||
+ u32 *pBuffer32 = static_cast<u32 *> (pBuffer);
|
||||
+
|
||||
+ unsigned i;
|
||||
+ for (i = 0; i < nChunkSize; i += IEC958_SUBFRAMES_PER_BLOCK)
|
||||
+ {
|
||||
+ unsigned j;
|
||||
+ for (j = 0; j < IEC958_STATUS_BYTES * 8 * SOUND_HW_CHANNELS; j++)
|
||||
+ {
|
||||
+ u32 *pSubFrame = &pBuffer32[i + j];
|
||||
+
|
||||
+ unsigned nFrame = j / SOUND_HW_CHANNELS;
|
||||
+ if (m_uchIEC958Status[nFrame / 8] & BIT(nFrame % 8))
|
||||
+ {
|
||||
+ u32 nValue = *pSubFrame;
|
||||
+
|
||||
+ nValue |= 0x40000000;
|
||||
+
|
||||
+ nValue &= 0x7FFFFFFF;
|
||||
+ if (parity32 (nValue))
|
||||
+ {
|
||||
+ nValue |= 0x80000000;
|
||||
+ }
|
||||
+
|
||||
+ *pSubFrame = nValue;
|
||||
+ }
|
||||
+
|
||||
+ if (nFrame == 0)
|
||||
+ {
|
||||
+ *pSubFrame |= IEC958_B_FRAME_PREAMBLE;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ assert (i == nChunkSize); // nChunkSize must be a multiple of 384
|
||||
+ }
|
||||
+
|
||||
if ( m_pCallback != 0
|
||||
&& nQueueBytesAvail < m_nNeedDataThreshold)
|
||||
{
|
||||
@@ -1,52 +0,0 @@
|
||||
From ae0a7b847fbfdc8631ebeec8e5c821c3127dd32c Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Sun, 28 Mar 2021 14:48:17 +0200
|
||||
Subject: [PATCH] util: Add parity32()
|
||||
|
||||
---
|
||||
include/circle/util.h | 6 ++++++
|
||||
lib/util.cpp | 17 +++++++++++++++++
|
||||
2 files changed, 23 insertions(+)
|
||||
|
||||
diff --git a/include/circle/util.h b/include/circle/util.h
|
||||
index c7075a8a..86c08476 100644
|
||||
--- a/include/circle/util.h
|
||||
+++ b/include/circle/util.h
|
||||
@@ -78,6 +78,12 @@ u32 bswap32 (u32 ulValue);
|
||||
#define be2le16 bswap16
|
||||
#define be2le32 bswap32
|
||||
|
||||
+#if !defined (__GNUC__) || (AARCH == 32 && STDLIB_SUPPORT == 0)
|
||||
+ int parity32 (unsigned nValue); // returns number of ones % 1
|
||||
+#else
|
||||
+ #define parity32 __builtin_parity
|
||||
+#endif
|
||||
+
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
diff --git a/lib/util.cpp b/lib/util.cpp
|
||||
index fa4d51a2..0ca3b6cf 100644
|
||||
--- a/lib/util.cpp
|
||||
+++ b/lib/util.cpp
|
||||
@@ -721,3 +721,20 @@ u32 bswap32 (u32 ulValue)
|
||||
}
|
||||
|
||||
#endif
|
||||
+
|
||||
+#if !defined (__GNUC__) || (AARCH == 32 && STDLIB_SUPPORT == 0)
|
||||
+
|
||||
+int parity32 (unsigned nValue)
|
||||
+{
|
||||
+ int nResult = 0;
|
||||
+
|
||||
+ while (nValue != 0)
|
||||
+ {
|
||||
+ nResult ^= (nValue & 1);
|
||||
+ nValue >>= 1;
|
||||
+ }
|
||||
+
|
||||
+ return nResult;
|
||||
+}
|
||||
+
|
||||
+#endif
|
||||
@@ -1,42 +0,0 @@
|
||||
From 127c03b88d281f1e9ee0c3e000e844bd59ff6098 Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Mon, 26 Apr 2021 10:29:45 +0200
|
||||
Subject: [PATCH] koptions: Allow to set any screen size
|
||||
|
||||
---
|
||||
lib/koptions.cpp | 8 +++-----
|
||||
1 file changed, 3 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/lib/koptions.cpp b/lib/koptions.cpp
|
||||
index 5f2cc34d..978e266e 100644
|
||||
--- a/lib/koptions.cpp
|
||||
+++ b/lib/koptions.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// koptions.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -64,8 +64,7 @@ CKernelOptions::CKernelOptions (void)
|
||||
if (strcmp (pOption, "width") == 0)
|
||||
{
|
||||
unsigned nValue;
|
||||
- if ( (nValue = GetDecimal (pValue)) != INVALID_VALUE
|
||||
- && 640 <= nValue && nValue <= 1980)
|
||||
+ if ((nValue = GetDecimal (pValue)) != INVALID_VALUE)
|
||||
{
|
||||
m_nWidth = nValue;
|
||||
}
|
||||
@@ -73,8 +72,7 @@ CKernelOptions::CKernelOptions (void)
|
||||
else if (strcmp (pOption, "height") == 0)
|
||||
{
|
||||
unsigned nValue;
|
||||
- if ( (nValue = GetDecimal (pValue)) != INVALID_VALUE
|
||||
- && 480 <= nValue && nValue <= 1080)
|
||||
+ if ((nValue = GetDecimal (pValue)) != INVALID_VALUE)
|
||||
{
|
||||
m_nHeight = nValue;
|
||||
}
|
||||
@@ -1,279 +0,0 @@
|
||||
From 5bc33c66eb4875852f4ebf750ee16107b23e1bfb Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Fri, 26 Mar 2021 07:42:19 +0100
|
||||
Subject: [PATCH] Move defines for DMA controller to dmacommon.h
|
||||
|
||||
---
|
||||
include/circle/dmacommon.h | 49 +++++++++++++++++++++++++++++++++++++-
|
||||
lib/dmachannel.cpp | 45 +---------------------------------
|
||||
lib/i2ssoundbasedevice.cpp | 48 +------------------------------------
|
||||
lib/pwmsoundbasedevice.cpp | 48 +------------------------------------
|
||||
4 files changed, 51 insertions(+), 139 deletions(-)
|
||||
|
||||
diff --git a/include/circle/dmacommon.h b/include/circle/dmacommon.h
|
||||
index f50a74dc..56599352 100644
|
||||
--- a/include/circle/dmacommon.h
|
||||
+++ b/include/circle/dmacommon.h
|
||||
@@ -2,7 +2,7 @@
|
||||
/// \file dmacommon.h
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -20,6 +20,7 @@
|
||||
#ifndef _circle_dmacommon_h
|
||||
#define _circle_dmacommon_h
|
||||
|
||||
+#include <circle/bcm2835.h>
|
||||
#include <circle/types.h>
|
||||
|
||||
enum TDREQ
|
||||
@@ -40,4 +41,50 @@ enum TDREQ
|
||||
|
||||
typedef void TDMACompletionRoutine (unsigned nChannel, boolean bStatus, void *pParam);
|
||||
|
||||
+//
|
||||
+// Legacy platform DMA controller
|
||||
+//
|
||||
+#define ARM_DMACHAN_CS(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x00)
|
||||
+ #define CS_RESET (1 << 31)
|
||||
+ #define CS_ABORT (1 << 30)
|
||||
+ #define CS_WAIT_FOR_OUTSTANDING_WRITES (1 << 28)
|
||||
+ #define CS_PANIC_PRIORITY_SHIFT 20
|
||||
+ #define DEFAULT_PANIC_PRIORITY 15
|
||||
+ #define CS_PRIORITY_SHIFT 16
|
||||
+ #define DEFAULT_PRIORITY 1
|
||||
+ #define CS_ERROR (1 << 8)
|
||||
+ #define CS_INT (1 << 2)
|
||||
+ #define CS_END (1 << 1)
|
||||
+ #define CS_ACTIVE (1 << 0)
|
||||
+#define ARM_DMACHAN_CONBLK_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x04)
|
||||
+#define ARM_DMACHAN_TI(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x08)
|
||||
+ #define TI_PERMAP_SHIFT 16
|
||||
+ #define TI_BURST_LENGTH_SHIFT 12
|
||||
+ #define DEFAULT_BURST_LENGTH 0
|
||||
+ #define TI_SRC_IGNORE (1 << 11)
|
||||
+ #define TI_SRC_DREQ (1 << 10)
|
||||
+ #define TI_SRC_WIDTH (1 << 9)
|
||||
+ #define TI_SRC_INC (1 << 8)
|
||||
+ #define TI_DEST_DREQ (1 << 6)
|
||||
+ #define TI_DEST_WIDTH (1 << 5)
|
||||
+ #define TI_DEST_INC (1 << 4)
|
||||
+ #define TI_WAIT_RESP (1 << 3)
|
||||
+ #define TI_TDMODE (1 << 1)
|
||||
+ #define TI_INTEN (1 << 0)
|
||||
+#define ARM_DMACHAN_SOURCE_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x0C)
|
||||
+#define ARM_DMACHAN_DEST_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x10)
|
||||
+#define ARM_DMACHAN_TXFR_LEN(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x14)
|
||||
+ #define TXFR_LEN_XLENGTH_SHIFT 0
|
||||
+ #define TXFR_LEN_YLENGTH_SHIFT 16
|
||||
+ #define TXFR_LEN_MAX 0x3FFFFFFF
|
||||
+ #define TXFR_LEN_MAX_LITE 0xFFFF
|
||||
+#define ARM_DMACHAN_STRIDE(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x18)
|
||||
+ #define STRIDE_SRC_SHIFT 0
|
||||
+ #define STRIDE_DEST_SHIFT 16
|
||||
+#define ARM_DMACHAN_NEXTCONBK(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x1C)
|
||||
+#define ARM_DMACHAN_DEBUG(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x20)
|
||||
+ #define DEBUG_LITE (1 << 28)
|
||||
+#define ARM_DMA_INT_STATUS (ARM_DMA_BASE + 0xFE0)
|
||||
+#define ARM_DMA_ENABLE (ARM_DMA_BASE + 0xFF0)
|
||||
+
|
||||
#endif
|
||||
diff --git a/lib/dmachannel.cpp b/lib/dmachannel.cpp
|
||||
index ed79f676..4edccdab 100644
|
||||
--- a/lib/dmachannel.cpp
|
||||
+++ b/lib/dmachannel.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// dmachannel.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -28,49 +28,6 @@
|
||||
|
||||
#define DMA_CHANNELS (DMA_CHANNEL_MAX + 1)
|
||||
|
||||
-#define ARM_DMACHAN_CS(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x00)
|
||||
- #define CS_RESET (1 << 31)
|
||||
- #define CS_ABORT (1 << 30)
|
||||
- #define CS_WAIT_FOR_OUTSTANDING_WRITES (1 << 28)
|
||||
- #define CS_PANIC_PRIORITY_SHIFT 20
|
||||
- #define DEFAULT_PANIC_PRIORITY 15
|
||||
- #define CS_PRIORITY_SHIFT 16
|
||||
- #define DEFAULT_PRIORITY 1
|
||||
- #define CS_ERROR (1 << 8)
|
||||
- #define CS_INT (1 << 2)
|
||||
- #define CS_END (1 << 1)
|
||||
- #define CS_ACTIVE (1 << 0)
|
||||
-#define ARM_DMACHAN_CONBLK_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x04)
|
||||
-#define ARM_DMACHAN_TI(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x08)
|
||||
- #define TI_PERMAP_SHIFT 16
|
||||
- #define TI_BURST_LENGTH_SHIFT 12
|
||||
- #define DEFAULT_BURST_LENGTH 0
|
||||
- #define TI_SRC_IGNORE (1 << 11)
|
||||
- #define TI_SRC_DREQ (1 << 10)
|
||||
- #define TI_SRC_WIDTH (1 << 9)
|
||||
- #define TI_SRC_INC (1 << 8)
|
||||
- #define TI_DEST_DREQ (1 << 6)
|
||||
- #define TI_DEST_WIDTH (1 << 5)
|
||||
- #define TI_DEST_INC (1 << 4)
|
||||
- #define TI_WAIT_RESP (1 << 3)
|
||||
- #define TI_TDMODE (1 << 1)
|
||||
- #define TI_INTEN (1 << 0)
|
||||
-#define ARM_DMACHAN_SOURCE_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x0C)
|
||||
-#define ARM_DMACHAN_DEST_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x10)
|
||||
-#define ARM_DMACHAN_TXFR_LEN(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x14)
|
||||
- #define TXFR_LEN_XLENGTH_SHIFT 0
|
||||
- #define TXFR_LEN_YLENGTH_SHIFT 16
|
||||
- #define TXFR_LEN_MAX 0x3FFFFFFF
|
||||
- #define TXFR_LEN_MAX_LITE 0xFFFF
|
||||
-#define ARM_DMACHAN_STRIDE(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x18)
|
||||
- #define STRIDE_SRC_SHIFT 0
|
||||
- #define STRIDE_DEST_SHIFT 16
|
||||
-#define ARM_DMACHAN_NEXTCONBK(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x1C)
|
||||
-#define ARM_DMACHAN_DEBUG(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x20)
|
||||
- #define DEBUG_LITE (1 << 28)
|
||||
-#define ARM_DMA_INT_STATUS (ARM_DMA_BASE + 0xFE0)
|
||||
-#define ARM_DMA_ENABLE (ARM_DMA_BASE + 0xFF0)
|
||||
-
|
||||
CDMAChannel::CDMAChannel (unsigned nChannel, CInterruptSystem *pInterruptSystem)
|
||||
: m_nChannel (CMachineInfo::Get ()->AllocateDMAChannel (nChannel)),
|
||||
m_pControlBlockBuffer (0),
|
||||
diff --git a/lib/i2ssoundbasedevice.cpp b/lib/i2ssoundbasedevice.cpp
|
||||
index c6057922..ba6014b3 100644
|
||||
--- a/lib/i2ssoundbasedevice.cpp
|
||||
+++ b/lib/i2ssoundbasedevice.cpp
|
||||
@@ -11,7 +11,7 @@
|
||||
// https://www.raspberrypi.org/forums/viewtopic.php?f=44&t=8496
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2016-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2016-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -77,52 +77,6 @@
|
||||
#define DREQ_A_TX__SHIFT 8
|
||||
#define DREQ_A_TX__MASK (0x7F << 8)
|
||||
|
||||
-//
|
||||
-// DMA controller
|
||||
-//
|
||||
-#define ARM_DMACHAN_CS(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x00)
|
||||
- #define CS_RESET (1 << 31)
|
||||
- #define CS_ABORT (1 << 30)
|
||||
- #define CS_WAIT_FOR_OUTSTANDING_WRITES (1 << 28)
|
||||
- #define CS_PANIC_PRIORITY_SHIFT 20
|
||||
- #define DEFAULT_PANIC_PRIORITY 15
|
||||
- #define CS_PRIORITY_SHIFT 16
|
||||
- #define DEFAULT_PRIORITY 1
|
||||
- #define CS_ERROR (1 << 8)
|
||||
- #define CS_INT (1 << 2)
|
||||
- #define CS_END (1 << 1)
|
||||
- #define CS_ACTIVE (1 << 0)
|
||||
-#define ARM_DMACHAN_CONBLK_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x04)
|
||||
-#define ARM_DMACHAN_TI(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x08)
|
||||
- #define TI_PERMAP_SHIFT 16
|
||||
- #define TI_BURST_LENGTH_SHIFT 12
|
||||
- #define DEFAULT_BURST_LENGTH 0
|
||||
- #define TI_SRC_IGNORE (1 << 11)
|
||||
- #define TI_SRC_DREQ (1 << 10)
|
||||
- #define TI_SRC_WIDTH (1 << 9)
|
||||
- #define TI_SRC_INC (1 << 8)
|
||||
- #define TI_DEST_DREQ (1 << 6)
|
||||
- #define TI_DEST_WIDTH (1 << 5)
|
||||
- #define TI_DEST_INC (1 << 4)
|
||||
- #define TI_WAIT_RESP (1 << 3)
|
||||
- #define TI_TDMODE (1 << 1)
|
||||
- #define TI_INTEN (1 << 0)
|
||||
-#define ARM_DMACHAN_SOURCE_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x0C)
|
||||
-#define ARM_DMACHAN_DEST_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x10)
|
||||
-#define ARM_DMACHAN_TXFR_LEN(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x14)
|
||||
- #define TXFR_LEN_XLENGTH_SHIFT 0
|
||||
- #define TXFR_LEN_YLENGTH_SHIFT 16
|
||||
- #define TXFR_LEN_MAX 0x3FFFFFFF
|
||||
- #define TXFR_LEN_MAX_LITE 0xFFFF
|
||||
-#define ARM_DMACHAN_STRIDE(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x18)
|
||||
- #define STRIDE_SRC_SHIFT 0
|
||||
- #define STRIDE_DEST_SHIFT 16
|
||||
-#define ARM_DMACHAN_NEXTCONBK(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x1C)
|
||||
-#define ARM_DMACHAN_DEBUG(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x20)
|
||||
- #define DEBUG_LITE (1 << 28)
|
||||
-#define ARM_DMA_INT_STATUS (ARM_DMA_BASE + 0xFE0)
|
||||
-#define ARM_DMA_ENABLE (ARM_DMA_BASE + 0xFF0)
|
||||
-
|
||||
CI2SSoundBaseDevice::CI2SSoundBaseDevice (CInterruptSystem *pInterrupt,
|
||||
unsigned nSampleRate,
|
||||
unsigned nChunkSize,
|
||||
diff --git a/lib/pwmsoundbasedevice.cpp b/lib/pwmsoundbasedevice.cpp
|
||||
index 2f6a42ba..e7e183af 100644
|
||||
--- a/lib/pwmsoundbasedevice.cpp
|
||||
+++ b/lib/pwmsoundbasedevice.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// pwmsoundbasedevice.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2016-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2016-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// Information to implement PWM sound is from:
|
||||
// "Bare metal sound" by Joeboy (RPi forum)
|
||||
@@ -101,52 +101,6 @@
|
||||
#define ARM_PWM_DMAC_PANIC__SHIFT 8
|
||||
#define ARM_PWM_DMAC_ENAB (1 << 31)
|
||||
|
||||
-//
|
||||
-// DMA controller
|
||||
-//
|
||||
-#define ARM_DMACHAN_CS(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x00)
|
||||
- #define CS_RESET (1 << 31)
|
||||
- #define CS_ABORT (1 << 30)
|
||||
- #define CS_WAIT_FOR_OUTSTANDING_WRITES (1 << 28)
|
||||
- #define CS_PANIC_PRIORITY_SHIFT 20
|
||||
- #define DEFAULT_PANIC_PRIORITY 15
|
||||
- #define CS_PRIORITY_SHIFT 16
|
||||
- #define DEFAULT_PRIORITY 1
|
||||
- #define CS_ERROR (1 << 8)
|
||||
- #define CS_INT (1 << 2)
|
||||
- #define CS_END (1 << 1)
|
||||
- #define CS_ACTIVE (1 << 0)
|
||||
-#define ARM_DMACHAN_CONBLK_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x04)
|
||||
-#define ARM_DMACHAN_TI(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x08)
|
||||
- #define TI_PERMAP_SHIFT 16
|
||||
- #define TI_BURST_LENGTH_SHIFT 12
|
||||
- #define DEFAULT_BURST_LENGTH 0
|
||||
- #define TI_SRC_IGNORE (1 << 11)
|
||||
- #define TI_SRC_DREQ (1 << 10)
|
||||
- #define TI_SRC_WIDTH (1 << 9)
|
||||
- #define TI_SRC_INC (1 << 8)
|
||||
- #define TI_DEST_DREQ (1 << 6)
|
||||
- #define TI_DEST_WIDTH (1 << 5)
|
||||
- #define TI_DEST_INC (1 << 4)
|
||||
- #define TI_WAIT_RESP (1 << 3)
|
||||
- #define TI_TDMODE (1 << 1)
|
||||
- #define TI_INTEN (1 << 0)
|
||||
-#define ARM_DMACHAN_SOURCE_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x0C)
|
||||
-#define ARM_DMACHAN_DEST_AD(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x10)
|
||||
-#define ARM_DMACHAN_TXFR_LEN(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x14)
|
||||
- #define TXFR_LEN_XLENGTH_SHIFT 0
|
||||
- #define TXFR_LEN_YLENGTH_SHIFT 16
|
||||
- #define TXFR_LEN_MAX 0x3FFFFFFF
|
||||
- #define TXFR_LEN_MAX_LITE 0xFFFF
|
||||
-#define ARM_DMACHAN_STRIDE(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x18)
|
||||
- #define STRIDE_SRC_SHIFT 0
|
||||
- #define STRIDE_DEST_SHIFT 16
|
||||
-#define ARM_DMACHAN_NEXTCONBK(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x1C)
|
||||
-#define ARM_DMACHAN_DEBUG(chan) (ARM_DMA_BASE + ((chan) * 0x100) + 0x20)
|
||||
- #define DEBUG_LITE (1 << 28)
|
||||
-#define ARM_DMA_INT_STATUS (ARM_DMA_BASE + 0xFE0)
|
||||
-#define ARM_DMA_ENABLE (ARM_DMA_BASE + 0xFF0)
|
||||
-
|
||||
CPWMSoundBaseDevice::CPWMSoundBaseDevice (CInterruptSystem *pInterrupt,
|
||||
unsigned nSampleRate,
|
||||
unsigned nChunkSize)
|
||||
@@ -1,252 +0,0 @@
|
||||
From 3a3bec6ec8a21abb63171af51b1333108aa2b28f Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Wed, 10 Mar 2021 20:40:05 +0100
|
||||
Subject: [PATCH] usb/xhci: Use PCIe INTA instead of MSI
|
||||
|
||||
* MSI did not work on RPi 4B v1.1 4GB any more for unknown reason
|
||||
* Results in a more unique interrupt handling for internal and
|
||||
external xHCI controller
|
||||
* bcmpciehostbridge: Do not enable MSI in enable_device() any more
|
||||
* bcmpciehostbridge: Enable INTX instead
|
||||
|
||||
Issue #209
|
||||
---
|
||||
include/circle/bcm2711int.h | 3 +-
|
||||
include/circle/usb/xhcidevice.h | 11 ++-----
|
||||
lib/bcmpciehostbridge.cpp | 7 +++--
|
||||
lib/usb/xhcidevice.cpp | 53 +++++++--------------------------
|
||||
4 files changed, 20 insertions(+), 54 deletions(-)
|
||||
|
||||
diff --git a/include/circle/bcm2711int.h b/include/circle/bcm2711int.h
|
||||
index c2237ce0..96e280d4 100644
|
||||
--- a/include/circle/bcm2711int.h
|
||||
+++ b/include/circle/bcm2711int.h
|
||||
@@ -2,7 +2,7 @@
|
||||
// bcm2711int.h
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2019-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2019-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -52,6 +52,7 @@
|
||||
#define ARM_IRQ_GPIO3 GIC_SPI (116)
|
||||
#define ARM_IRQ_UART GIC_SPI (121)
|
||||
#define ARM_IRQ_ARASANSDIO GIC_SPI (126)
|
||||
+#define ARM_IRQ_PCIE_HOST_INTA GIC_SPI (143)
|
||||
#define ARM_IRQ_PCIE_HOST_MSI GIC_SPI (148)
|
||||
#define ARM_IRQ_BCM54213_0 GIC_SPI (157)
|
||||
#define ARM_IRQ_BCM54213_1 GIC_SPI (158)
|
||||
diff --git a/include/circle/usb/xhcidevice.h b/include/circle/usb/xhcidevice.h
|
||||
index 2ca7bb30..bd9a416b 100644
|
||||
--- a/include/circle/usb/xhcidevice.h
|
||||
+++ b/include/circle/usb/xhcidevice.h
|
||||
@@ -2,7 +2,7 @@
|
||||
// xhcidevice.h
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2019-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2019-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -65,21 +65,16 @@ class CXHCIDevice : public CUSBHostController /// USB host controller interface
|
||||
#endif
|
||||
|
||||
private:
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
void InterruptHandler (void);
|
||||
static void InterruptStub (void *pParam);
|
||||
-#else
|
||||
- void InterruptHandler (unsigned nVector);
|
||||
- static void InterruptStub (unsigned nVector, void *pParam);
|
||||
-#endif
|
||||
|
||||
boolean HWReset (void);
|
||||
|
||||
private:
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
CInterruptSystem *m_pInterruptSystem;
|
||||
boolean m_bInterruptConnected;
|
||||
-#else
|
||||
+
|
||||
+#ifndef USE_XHCI_INTERNAL
|
||||
CBcmPCIeHostBridge m_PCIeHostBridge;
|
||||
#endif
|
||||
|
||||
diff --git a/lib/bcmpciehostbridge.cpp b/lib/bcmpciehostbridge.cpp
|
||||
index f7a41791..e64cebb0 100644
|
||||
--- a/lib/bcmpciehostbridge.cpp
|
||||
+++ b/lib/bcmpciehostbridge.cpp
|
||||
@@ -7,7 +7,7 @@
|
||||
// Licensed under GPL-2.0
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2019-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2019-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -550,6 +550,7 @@ int CBcmPCIeHostBridge::enable_device (u32 nClassCode, unsigned nSlot, unsigned
|
||||
| PCI_BASE_ADDRESS_MEM_TYPE_64);
|
||||
write32 (conf + PCI_BASE_ADDRESS_1, upper_32_bits (MEM_PCIE_RANGE_PCIE_START));
|
||||
|
||||
+#if 0
|
||||
uintptr msi_conf = find_pci_capability (conf, PCI_CAP_ID_MSI);
|
||||
if (!msi_conf)
|
||||
return -1;
|
||||
@@ -562,12 +563,14 @@ int CBcmPCIeHostBridge::enable_device (u32 nClassCode, unsigned nSlot, unsigned
|
||||
write8 (msi_conf + PCI_MSI_FLAGS, PCI_MSI_FLAGS_ENABLE
|
||||
| PCI_MSI_FLAGS_64BIT
|
||||
| uchQueueSize << 4);
|
||||
+#endif
|
||||
|
||||
write16 (conf + PCI_COMMAND, PCI_COMMAND_MEMORY
|
||||
| PCI_COMMAND_MASTER
|
||||
| PCI_COMMAND_PARITY
|
||||
| PCI_COMMAND_SERR
|
||||
- | PCI_COMMAND_INTX_DISABLE);
|
||||
+ //| PCI_COMMAND_INTX_DISABLE
|
||||
+ );
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff --git a/lib/usb/xhcidevice.cpp b/lib/usb/xhcidevice.cpp
|
||||
index c5880f40..570251f2 100644
|
||||
--- a/lib/usb/xhcidevice.cpp
|
||||
+++ b/lib/usb/xhcidevice.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// xhcidevice.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2019-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2019-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -27,14 +27,19 @@
|
||||
#include <circle/machineinfo.h>
|
||||
#include <assert.h>
|
||||
|
||||
+#ifdef USE_XHCI_INTERNAL
|
||||
+ #define ARM_IRQ_XHCI ARM_IRQ_XHCI_INTERNAL
|
||||
+#else
|
||||
+ #define ARM_IRQ_XHCI ARM_IRQ_PCIE_HOST_INTA
|
||||
+#endif
|
||||
+
|
||||
static const char From[] = "xhci";
|
||||
|
||||
CXHCIDevice::CXHCIDevice (CInterruptSystem *pInterruptSystem, CTimer *pTimer, boolean bPlugAndPlay)
|
||||
: CUSBHostController (bPlugAndPlay),
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
m_pInterruptSystem (pInterruptSystem),
|
||||
m_bInterruptConnected (FALSE),
|
||||
-#else
|
||||
+#ifndef USE_XHCI_INTERNAL
|
||||
m_PCIeHostBridge (pInterruptSystem),
|
||||
#endif
|
||||
m_SharedMemAllocator (
|
||||
@@ -63,14 +68,12 @@ CXHCIDevice::~CXHCIDevice (void)
|
||||
HWReset ();
|
||||
}
|
||||
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
if (m_bInterruptConnected)
|
||||
{
|
||||
assert (m_pInterruptSystem != 0);
|
||||
- m_pInterruptSystem->DisconnectIRQ (ARM_IRQ_XHCI_INTERNAL);
|
||||
+ m_pInterruptSystem->DisconnectIRQ (ARM_IRQ_XHCI);
|
||||
m_bInterruptConnected = FALSE;
|
||||
}
|
||||
-#endif
|
||||
|
||||
m_pScratchpadBufferArray = 0;
|
||||
m_pScratchpadBuffers = 0;
|
||||
@@ -126,13 +129,6 @@ boolean CXHCIDevice::Initialize (boolean bScanDevices)
|
||||
| XHCI_PCIE_FUNC << 12;
|
||||
Tags.GetTag (PROPTAG_NOTIFY_XHCI_RESET, &NotifyXHCIReset, sizeof NotifyXHCIReset, 4);
|
||||
|
||||
- if (!m_PCIeHostBridge.ConnectMSI (InterruptStub, this))
|
||||
- {
|
||||
- CLogger::Get ()->Write (From, LogError, "Cannot connect MSI");
|
||||
-
|
||||
- return FALSE;
|
||||
- }
|
||||
-
|
||||
if (!m_PCIeHostBridge.EnableDevice (XHCI_PCI_CLASS_CODE, XHCI_PCIE_SLOT, XHCI_PCIE_FUNC))
|
||||
{
|
||||
CLogger::Get ()->Write (From, LogError, "Cannot enable xHCI device");
|
||||
@@ -236,11 +232,9 @@ boolean CXHCIDevice::Initialize (boolean bScanDevices)
|
||||
m_pRootHub = new CXHCIRootHub (nMaxPorts, this);
|
||||
assert (m_pRootHub != 0);
|
||||
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
assert (m_pInterruptSystem != 0);
|
||||
- m_pInterruptSystem->ConnectIRQ (ARM_IRQ_XHCI_INTERNAL, InterruptStub, this);
|
||||
+ m_pInterruptSystem->ConnectIRQ (ARM_IRQ_XHCI, InterruptStub, this);
|
||||
m_bInterruptConnected = TRUE;
|
||||
-#endif
|
||||
|
||||
// start controller
|
||||
m_pMMIO->op_write32 (XHCI_REG_OP_USBCMD, m_pMMIO->op_read32 (XHCI_REG_OP_USBCMD)
|
||||
@@ -346,31 +340,18 @@ void CXHCIDevice::FreeSharedMem (void *pBlock)
|
||||
m_SharedMemAllocator.Free (pBlock);
|
||||
}
|
||||
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
void CXHCIDevice::InterruptHandler (void)
|
||||
-#else
|
||||
-void CXHCIDevice::InterruptHandler (unsigned nVector)
|
||||
-#endif
|
||||
{
|
||||
#ifdef XHCI_DEBUG2
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
CLogger::Get ()->Write (From, LogDebug, "IRQ");
|
||||
-#else
|
||||
- CLogger::Get ()->Write (From, LogDebug, "MSI%u", nVector);
|
||||
-#endif
|
||||
-#endif
|
||||
-#ifndef USE_XHCI_INTERNAL
|
||||
- assert (nVector == 0);
|
||||
#endif
|
||||
|
||||
// acknowledge interrupt
|
||||
u32 nStatus = m_pMMIO->op_read32 (XHCI_REG_OP_USBSTS);
|
||||
m_pMMIO->op_write32 (XHCI_REG_OP_USBSTS, nStatus | XHCI_REG_OP_USBSTS_EINT);
|
||||
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
m_pMMIO->rt_write32 (0, XHCI_REG_RT_IR_IMAN, m_pMMIO->rt_read32 (0, XHCI_REG_RT_IR_IMAN)
|
||||
| XHCI_REG_RT_IR_IMAN_IP);
|
||||
-#endif
|
||||
|
||||
if (nStatus & XHCI_REG_OP_USBSTS_HCH)
|
||||
{
|
||||
@@ -406,8 +387,6 @@ void CXHCIDevice::InterruptHandler (unsigned nVector)
|
||||
}
|
||||
}
|
||||
|
||||
-#ifdef USE_XHCI_INTERNAL
|
||||
-
|
||||
void CXHCIDevice::InterruptStub (void *pParam)
|
||||
{
|
||||
CXHCIDevice *pThis = (CXHCIDevice *) pParam;
|
||||
@@ -416,18 +395,6 @@ void CXHCIDevice::InterruptStub (void *pParam)
|
||||
pThis->InterruptHandler ();
|
||||
}
|
||||
|
||||
-#else
|
||||
-
|
||||
-void CXHCIDevice::InterruptStub (unsigned nVector, void *pParam)
|
||||
-{
|
||||
- CXHCIDevice *pThis = (CXHCIDevice *) pParam;
|
||||
- assert (pThis != 0);
|
||||
-
|
||||
- pThis->InterruptHandler (nVector);
|
||||
-}
|
||||
-
|
||||
-#endif
|
||||
-
|
||||
boolean CXHCIDevice::HWReset (void)
|
||||
{
|
||||
if ( !m_pMMIO->op_wait32 (XHCI_REG_OP_USBSTS, XHCI_REG_OP_USBSTS_CNR, 0, 100000)
|
||||
@@ -1,158 +0,0 @@
|
||||
From 17e015181d02e4b676204e201a9fb4b8e34f730b Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Mon, 15 Mar 2021 18:20:06 +0100
|
||||
Subject: [PATCH] usb/usbmassdevice: Fix hard errors in reset recovery
|
||||
|
||||
The recovery function did not work at all, because it was never used
|
||||
before. Now on the RPi 3A+, Zero and probably A+ it is necessary and
|
||||
has been corrected. Unfortunately this does not solve all problems
|
||||
with USB flash drive access on these RPi models. Reads or writes may
|
||||
still fail, but not as often.
|
||||
|
||||
Issue #211
|
||||
---
|
||||
include/circle/usb/usb.h | 6 ++++-
|
||||
lib/usb/usbmassdevice.cpp | 50 ++++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 46 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/include/circle/usb/usb.h b/include/circle/usb/usb.h
|
||||
index 06dfdc9d..4fb61a98 100644
|
||||
--- a/include/circle/usb/usb.h
|
||||
+++ b/include/circle/usb/usb.h
|
||||
@@ -2,7 +2,7 @@
|
||||
// usb.h
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -84,6 +84,7 @@ PACKED;
|
||||
|
||||
#define REQUEST_TO_DEVICE 0
|
||||
#define REQUEST_TO_INTERFACE 1
|
||||
+#define REQUEST_TO_ENDPOINT 2
|
||||
#define REQUEST_TO_OTHER 3
|
||||
|
||||
// Standard Request Codes
|
||||
@@ -95,6 +96,9 @@ PACKED;
|
||||
#define SET_CONFIGURATION 9
|
||||
#define SET_INTERFACE 11
|
||||
|
||||
+// Standard Feature Selectors
|
||||
+#define ENDPOINT_HALT 0
|
||||
+
|
||||
// Descriptor Types
|
||||
#define DESCRIPTOR_DEVICE 1
|
||||
#define DESCRIPTOR_CONFIGURATION 2
|
||||
diff --git a/lib/usb/usbmassdevice.cpp b/lib/usb/usbmassdevice.cpp
|
||||
index da631e18..10de3f14 100644
|
||||
--- a/lib/usb/usbmassdevice.cpp
|
||||
+++ b/lib/usb/usbmassdevice.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// usbmassdevice.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -28,8 +28,14 @@
|
||||
#include <circle/new.h>
|
||||
#include <assert.h>
|
||||
|
||||
+#define MAX_TRIES 8 // max. read / write attempts
|
||||
+
|
||||
// USB Mass Storage Bulk-Only Transport
|
||||
|
||||
+// Class-specific requests
|
||||
+#define GET_MAX_LUN 0xFE
|
||||
+#define BULK_ONLY_MASS_STORAGE_RESET 0xFF
|
||||
+
|
||||
// Command Block Wrapper
|
||||
struct TCBW
|
||||
{
|
||||
@@ -418,7 +424,7 @@ boolean CUSBBulkOnlyMassStorageDevice::Configure (void)
|
||||
|
||||
int CUSBBulkOnlyMassStorageDevice::Read (void *pBuffer, size_t nCount)
|
||||
{
|
||||
- unsigned nTries = 4;
|
||||
+ unsigned nTries = MAX_TRIES;
|
||||
|
||||
int nResult;
|
||||
|
||||
@@ -443,7 +449,7 @@ int CUSBBulkOnlyMassStorageDevice::Read (void *pBuffer, size_t nCount)
|
||||
|
||||
int CUSBBulkOnlyMassStorageDevice::Write (const void *pBuffer, size_t nCount)
|
||||
{
|
||||
- unsigned nTries = 4;
|
||||
+ unsigned nTries = MAX_TRIES;
|
||||
|
||||
int nResult;
|
||||
|
||||
@@ -629,7 +635,25 @@ int CUSBBulkOnlyMassStorageDevice::Command (void *pCmdBlk, size_t nCmdBlkLen,
|
||||
{
|
||||
CLogger::Get ()->Write (FromUmsd, LogError, "CSW transfer failed");
|
||||
|
||||
- return -1;
|
||||
+ if (pHost->ControlMessage (GetEndpoint0 (),
|
||||
+ REQUEST_TO_ENDPOINT | REQUEST_OUT, CLEAR_FEATURE,
|
||||
+ ENDPOINT_HALT, m_pEndpointIn->GetNumber () | 0x80,
|
||||
+ 0, 0) < 0)
|
||||
+ {
|
||||
+ CLogger::Get ()->Write (FromUmsd, LogDebug,
|
||||
+ "Cannot clear halt on endpoint IN");
|
||||
+
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ m_pEndpointIn->ResetPID ();
|
||||
+
|
||||
+ if (pHost->Transfer (m_pEndpointIn, pCSW, sizeof *pCSW) != (int) sizeof *pCSW)
|
||||
+ {
|
||||
+ CLogger::Get ()->Write (FromUmsd, LogError, "CSW transfer failed twice");
|
||||
+
|
||||
+ return -1;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (pCSW->dCSWSignature != CSWSIGNATURE)
|
||||
@@ -666,23 +690,31 @@ int CUSBBulkOnlyMassStorageDevice::Reset (void)
|
||||
CUSBHostController *pHost = GetHost ();
|
||||
assert (pHost != 0);
|
||||
|
||||
- if (pHost->ControlMessage (GetEndpoint0 (), 0x21, 0xFF, 0, 0x00, 0, 0) < 0)
|
||||
+ if (pHost->ControlMessage (GetEndpoint0 (),
|
||||
+ REQUEST_CLASS | REQUEST_TO_INTERFACE | REQUEST_OUT,
|
||||
+ BULK_ONLY_MASS_STORAGE_RESET, 0, GetInterfaceNumber (), 0, 0) < 0)
|
||||
{
|
||||
CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot reset device");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (pHost->ControlMessage (GetEndpoint0 (), 0x02, 1, 0, 1, 0, 0) < 0)
|
||||
+ CTimer::Get ()->MsDelay (100);
|
||||
+
|
||||
+ if (pHost->ControlMessage (GetEndpoint0 (),
|
||||
+ REQUEST_TO_ENDPOINT | REQUEST_OUT, CLEAR_FEATURE,
|
||||
+ ENDPOINT_HALT, m_pEndpointIn->GetNumber () | 0x80, 0, 0) < 0)
|
||||
{
|
||||
- CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot clear halt on endpoint 1");
|
||||
+ CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot clear halt on endpoint IN");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (pHost->ControlMessage (GetEndpoint0 (), 0x02, 1, 0, 2, 0, 0) < 0)
|
||||
+ if (pHost->ControlMessage (GetEndpoint0 (),
|
||||
+ REQUEST_TO_ENDPOINT | REQUEST_OUT, CLEAR_FEATURE,
|
||||
+ ENDPOINT_HALT, m_pEndpointOut->GetNumber (), 0, 0) < 0)
|
||||
{
|
||||
- CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot clear halt on endpoint 2");
|
||||
+ CLogger::Get ()->Write (FromUmsd, LogDebug, "Cannot clear halt on endpoint OUT");
|
||||
|
||||
return -1;
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
From 91075a403fb952f60c83707e56b239e615c6b3f3 Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Wed, 24 Mar 2021 22:40:05 +0100
|
||||
Subject: [PATCH] usb: Add workaround for low-speed devices with bulk EPs
|
||||
|
||||
There are some low-speed USB devices, which have bulk endpoints. This
|
||||
is normally not allowed by the USB specification. To be able to use
|
||||
such a device, we treat these endpoints being interrupt EPs. This has
|
||||
not been tested on RPi 4 yet.
|
||||
|
||||
See: https://github.com/dwhinham/mt32-pi/discussions/102
|
||||
---
|
||||
lib/usb/dwhcixferstagedata.cpp | 1 -
|
||||
lib/usb/usbendpoint.cpp | 26 +++++++++++++++++++++++++-
|
||||
lib/usb/xhciendpoint.cpp | 15 +++++++++++++++
|
||||
3 files changed, 40 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/lib/usb/dwhcixferstagedata.cpp b/lib/usb/dwhcixferstagedata.cpp
|
||||
index 32f3f356..cc783a2d 100644
|
||||
--- a/lib/usb/dwhcixferstagedata.cpp
|
||||
+++ b/lib/usb/dwhcixferstagedata.cpp
|
||||
@@ -185,7 +185,6 @@ void CDWHCITransferStageData::TransactionComplete (u32 nStatus, u32 nPacketsLeft
|
||||
if ( (nStatus & DWHCI_HOST_CHAN_INT_NAK)
|
||||
&& m_pURB->IsCompleteOnNAK ())
|
||||
{
|
||||
- assert (m_pEndpoint->GetType () == EndpointTypeBulk);
|
||||
assert (m_bIn);
|
||||
|
||||
m_nPackets = 0; // no data is available, complete transfer
|
||||
diff --git a/lib/usb/usbendpoint.cpp b/lib/usb/usbendpoint.cpp
|
||||
index 05a81279..305487c5 100644
|
||||
--- a/lib/usb/usbendpoint.cpp
|
||||
+++ b/lib/usb/usbendpoint.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// usbendpoint.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2019 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -19,6 +19,7 @@
|
||||
//
|
||||
#include <circle/usb/usbendpoint.h>
|
||||
#include <circle/sysconfig.h>
|
||||
+#include <circle/logger.h>
|
||||
#include <assert.h>
|
||||
|
||||
CUSBEndpoint::CUSBEndpoint (CUSBDevice *pDevice)
|
||||
@@ -113,6 +114,29 @@ CUSBEndpoint::CUSBEndpoint (CUSBDevice *pDevice, const TUSBEndpointDescriptor *p
|
||||
}
|
||||
#endif
|
||||
|
||||
+ // workaround for low-speed devices with bulk endpoints,
|
||||
+ // which is normally forbidden by the USB spec.
|
||||
+ if ( m_pDevice->GetSpeed () == USBSpeedLow
|
||||
+ && m_Type == EndpointTypeBulk)
|
||||
+ {
|
||||
+ CLogger::Get ()->Write ("uep", LogWarning, "Device is not fully USB compliant");
|
||||
+
|
||||
+ m_Type = EndpointTypeInterrupt;
|
||||
+
|
||||
+ if (m_nMaxPacketSize > 8)
|
||||
+ {
|
||||
+ m_nMaxPacketSize = 8;
|
||||
+ }
|
||||
+
|
||||
+#if RASPPI <= 3
|
||||
+#ifdef USE_USB_SOF_INTR
|
||||
+ m_nInterval = 1;
|
||||
+#else
|
||||
+ m_nInterval = 20;
|
||||
+#endif
|
||||
+#endif
|
||||
+ }
|
||||
+
|
||||
#if RASPPI >= 4
|
||||
m_pXHCIEndpoint = new CXHCIEndpoint ((CXHCIUSBDevice *) m_pDevice, pDesc,
|
||||
(CXHCIDevice *) m_pDevice->GetHost ());
|
||||
diff --git a/lib/usb/xhciendpoint.cpp b/lib/usb/xhciendpoint.cpp
|
||||
index fa4e8f30..5a9eb837 100644
|
||||
--- a/lib/usb/xhciendpoint.cpp
|
||||
+++ b/lib/usb/xhciendpoint.cpp
|
||||
@@ -100,6 +100,21 @@ CXHCIEndpoint::CXHCIEndpoint (CXHCIUSBDevice *pDevice, const TUSBEndpointDescrip
|
||||
m_uchInterval = 0;
|
||||
}
|
||||
|
||||
+ // workaround for low-speed devices with bulk endpoints,
|
||||
+ // which is normally forbidden by the USB spec.
|
||||
+ if ( m_pDevice->GetSpeed () == USBSpeedLow
|
||||
+ && (m_uchAttributes & 3) == 2)
|
||||
+ {
|
||||
+ m_uchAttributes = 3; // fake interrupt endpoint
|
||||
+
|
||||
+ if (m_usMaxPacketSize > 8)
|
||||
+ {
|
||||
+ m_usMaxPacketSize = 8;
|
||||
+ }
|
||||
+
|
||||
+ m_uchInterval = ConvertInterval (1, USBSpeedLow);
|
||||
+ }
|
||||
+
|
||||
// calculate endpoint ID
|
||||
assert ((m_uchEndpointAddress & 0x0F) >= 1);
|
||||
m_uchEndpointID = (m_uchEndpointAddress & 0x0F) * 2;
|
||||
@@ -1,147 +0,0 @@
|
||||
From 88240494fa02a09cbebd94a3ce35d87303cd0a0e Mon Sep 17 00:00:00 2001
|
||||
From: Rene Stange <rsta2@o2online.de>
|
||||
Date: Thu, 18 Mar 2021 13:12:06 +0100
|
||||
Subject: [PATCH] usb/dwhcidevice: Retry bulk transfers on xact error
|
||||
|
||||
The access to some (especially USB 3.0) flash drives on RPi 3A+ and
|
||||
Zero was not reliable before, because xact errors occurred from time
|
||||
to time. Now transfers will be automatically retried several times,
|
||||
if such an error occurs on a bulk endpoint.
|
||||
|
||||
Issue #211
|
||||
---
|
||||
include/circle/usb/dwhcixferstagedata.h | 4 +++-
|
||||
lib/usb/dwhcidevice.cpp | 17 ++++++++++++++++-
|
||||
lib/usb/dwhcixferstagedata.cpp | 25 +++++++++++++++++++++++--
|
||||
3 files changed, 42 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/include/circle/usb/dwhcixferstagedata.h b/include/circle/usb/dwhcixferstagedata.h
|
||||
index 5300c74c..8890cdfb 100644
|
||||
--- a/include/circle/usb/dwhcixferstagedata.h
|
||||
+++ b/include/circle/usb/dwhcixferstagedata.h
|
||||
@@ -2,7 +2,7 @@
|
||||
// dwhcixferstagedata.h
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -80,6 +80,7 @@ class CDWHCITransferStageData
|
||||
boolean IsStageComplete (void) const;
|
||||
u32 GetResultLen (void) const;
|
||||
boolean IsTimeout (void) const;
|
||||
+ boolean IsRetryOK (void) const;
|
||||
|
||||
CUSBRequest *GetURB (void) const;
|
||||
CUSBDevice *GetDevice (void) const;
|
||||
@@ -109,6 +110,7 @@ class CDWHCITransferStageData
|
||||
unsigned m_nState;
|
||||
unsigned m_nSubState;
|
||||
u32 m_nTransactionStatus;
|
||||
+ unsigned m_nErrorCount;
|
||||
|
||||
u32 *m_pTempBuffer;
|
||||
void *m_pBufferPointer;
|
||||
diff --git a/lib/usb/dwhcidevice.cpp b/lib/usb/dwhcidevice.cpp
|
||||
index c59c5fab..79b22268 100644
|
||||
--- a/lib/usb/dwhcidevice.cpp
|
||||
+++ b/lib/usb/dwhcidevice.cpp
|
||||
@@ -1064,7 +1064,22 @@ void CDWHCIDevice::ChannelInterruptHandler (unsigned nChannel)
|
||||
{
|
||||
case StageStateNoSplitTransfer:
|
||||
nStatus = pStageData->GetTransactionStatus ();
|
||||
- if (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK)
|
||||
+ if ( (nStatus & DWHCI_HOST_CHAN_INT_XACT_ERROR)
|
||||
+ && pURB->GetEndpoint ()->GetType () == EndpointTypeBulk
|
||||
+ && pStageData->IsRetryOK ())
|
||||
+ {
|
||||
+#ifndef USE_USB_SOF_INTR
|
||||
+ StartTransaction (pStageData);
|
||||
+#else
|
||||
+ m_pStageData[nChannel] = 0;
|
||||
+ FreeChannel (nChannel);
|
||||
+
|
||||
+ QueueTransaction (pStageData);
|
||||
+#endif
|
||||
+
|
||||
+ break;
|
||||
+ }
|
||||
+ else if (nStatus & DWHCI_HOST_CHAN_INT_ERROR_MASK)
|
||||
{
|
||||
CLogger::Get ()->Write (FromDWHCI, LogError,
|
||||
"Transaction failed (status 0x%X)", nStatus);
|
||||
diff --git a/lib/usb/dwhcixferstagedata.cpp b/lib/usb/dwhcixferstagedata.cpp
|
||||
index 63cf64eb..32f3f356 100644
|
||||
--- a/lib/usb/dwhcixferstagedata.cpp
|
||||
+++ b/lib/usb/dwhcixferstagedata.cpp
|
||||
@@ -2,7 +2,7 @@
|
||||
// dwhcixferstagedata.cpp
|
||||
//
|
||||
// Circle - A C++ bare metal environment for Raspberry Pi
|
||||
-// Copyright (C) 2014-2020 R. Stange <rsta2@o2online.de>
|
||||
+// Copyright (C) 2014-2021 R. Stange <rsta2@o2online.de>
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
@@ -27,6 +27,8 @@
|
||||
#include <circle/timer.h>
|
||||
#include <assert.h>
|
||||
|
||||
+#define MAX_BULK_TRIES 8
|
||||
+
|
||||
CDWHCITransferStageData::CDWHCITransferStageData (unsigned nChannel,
|
||||
CUSBRequest *pURB,
|
||||
boolean bIn,
|
||||
@@ -42,6 +44,7 @@ CDWHCITransferStageData::CDWHCITransferStageData (unsigned nChannel,
|
||||
m_nState (0),
|
||||
m_nSubState (0),
|
||||
m_nTransactionStatus (0),
|
||||
+ m_nErrorCount (0),
|
||||
m_pTempBuffer (0),
|
||||
m_nStartTicksHZ (0),
|
||||
m_pFrameScheduler (0)
|
||||
@@ -186,9 +189,17 @@ void CDWHCITransferStageData::TransactionComplete (u32 nStatus, u32 nPacketsLeft
|
||||
assert (m_bIn);
|
||||
|
||||
m_nPackets = 0; // no data is available, complete transfer
|
||||
+
|
||||
+ return;
|
||||
}
|
||||
|
||||
- return;
|
||||
+ // bulk transfers with xact error will be retried, return otherwise
|
||||
+ if ( !(nStatus & DWHCI_HOST_CHAN_INT_XACT_ERROR)
|
||||
+ || m_pEndpoint->GetType () != EndpointTypeBulk
|
||||
+ || ++m_nErrorCount > MAX_BULK_TRIES)
|
||||
+ {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
|
||||
u32 nPacketsTransfered = m_nPacketsPerTransaction - nPacketsLeft;
|
||||
@@ -214,6 +225,11 @@ void CDWHCITransferStageData::TransactionComplete (u32 nStatus, u32 nPacketsLeft
|
||||
assert (nPacketsTransfered <= m_nPackets);
|
||||
m_nPackets -= nPacketsTransfered;
|
||||
|
||||
+ if (!m_bSplitTransaction)
|
||||
+ {
|
||||
+ m_nPacketsPerTransaction = m_nPackets;
|
||||
+ }
|
||||
+
|
||||
// if (m_nTotalBytesTransfered > m_nTransferSize) this will be false:
|
||||
if (m_nTransferSize - m_nTotalBytesTransfered < m_nBytesPerTransaction)
|
||||
{
|
||||
@@ -490,6 +506,11 @@ boolean CDWHCITransferStageData::IsTimeout (void) const
|
||||
return CTimer::Get ()->GetTicks ()-m_nStartTicksHZ >= m_nTimeoutHZ ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
+boolean CDWHCITransferStageData::IsRetryOK (void) const
|
||||
+{
|
||||
+ return m_nErrorCount <= MAX_BULK_TRIES;
|
||||
+}
|
||||
+
|
||||
CUSBRequest *CDWHCITransferStageData::GetURB (void) const
|
||||
{
|
||||
assert (m_pURB != 0);
|
||||
File renamed without changes.
Reference in new issue
Block a user