KurtE
Senior Member+
Not sure if anyone will be interested or not. But with the talk of maybe using SDIO to support some different WIFI controllers,
wondering how hard it would be to support SDFat on SDIO2, and with this could one use both of them on the same T4.1
Or custom boards.
Sorry, in advance - probably long and convoluted and confusing.
On T4.1 I am using:
CLK = 23, CMD = 22, Data: 40, 41, 17, 16
So, I am starting to experiment...
Steps I have done so far: Split off Teensy SDIO4 into two different source files. T3.x and T4.x.
Started updates to teensy\cores\imxrt.h - Created typedef structure for SDIO:
So far I have not created pointers to the different objects within IMXRT.h.
@PaulStoffregen - Assuming something like other updates like this? Should I update the current defines as well?
like:
Would go to something like:
Moved all of the state variables and functions to be private in SDCardIO.h - not sure if that will fly. Currently SDIO in your fork only supported by Teensy, but I believe maybe supports RPI... or was it ESP...
Added define for SDIO Options: So currently only way to use SDIO 2 (in my test code)
Changes in the code so far:
a) Modify functions to not assume USDHC1... Note: I am trying to remove most of the usage of the code to not use mapping T3.x to T4.x register names...
It is passing different static functions into waitTimeout that is checking fixed status registers...
So modified to be methods on class, which gets called so it has address of the SDIO register structure...
But then had to learn how to call function pointers to non-static class methods. ...
Init the CCM clocks:
Initialize the pins: Note: Different pins and different mode of pins for the SDIO2 pins I am using.
Initialize IRQ: ...
DMA: ? not sure we doing much yet here.
Now starting to test: First issue I ran into none of the pins were outputting anything...
Need to Input select them:
Code is still erroring out with Test program. Just using ListFiles with the change
Still getting errors, but some output as partial output:
So it looks like somethings are limping along and maybe hope...
Thought I would mention it and also say I pushed the WIP stuff up to:
Have not pushed up the imxrt.h changes yet, but...
wondering how hard it would be to support SDFat on SDIO2, and with this could one use both of them on the same T4.1
Or custom boards.
Sorry, in advance - probably long and convoluted and confusing.
On T4.1 I am using:
CLK = 23, CMD = 22, Data: 40, 41, 17, 16
So, I am starting to experiment...
Steps I have done so far: Split off Teensy SDIO4 into two different source files. T3.x and T4.x.
Started updates to teensy\cores\imxrt.h - Created typedef structure for SDIO:
Code:
typedef struct {
volatile uint32_t DS_ADDR; //offset000)
volatile uint32_t BLK_ATT; //offset004)
volatile uint32_t CMD_ARG; //offset008)
volatile uint32_t CMD_XFR_TYP; //offset00C)
volatile uint32_t CMD_RSP0; //offset010)
volatile uint32_t CMD_RSP1; //offset014)
volatile uint32_t CMD_RSP2; //offset018)
volatile uint32_t CMD_RSP3; //offset01C)
volatile uint32_t DATA_BUFF_ACC_PORT; //offset020)
volatile uint32_t PRES_STATE; //offset024)
volatile uint32_t PROT_CTRL; //offset028)
volatile uint32_t SYS_CTRL; //offset02C)
volatile uint32_t INT_STATUS; //offset030)
volatile uint32_t INT_STATUS_EN; //offset034)
volatile uint32_t INT_SIGNAL_EN; //offset038)
volatile uint32_t AUTOCMD12_ERR_STATUS; //offset03C)
volatile uint32_t HOST_CTRL_CAP; //offset040)
volatile uint32_t WTMK_LVL; //offset044)
volatile uint32_t MIX_CTRL; //offset048)
uint32_t unused1;
volatile uint32_t FORCE_EVENT; //offset050)
volatile uint32_t ADMA_ERR_STATUS; //offset054)
volatile uint32_t ADMA_SYS_ADDR; //offset058)
uint32_t unused2;
volatile uint32_t DLL_CTRL; //offset060)
volatile uint32_t DLL_STATUS; //offset064)
volatile uint32_t CLK_TUNE_CTRL_STATUS; //offset068)
uint32_t unused3[21]; //6c 70 80 90 A0 B0
volatile uint32_t VEND_SPEC; //offset0C0)
volatile uint32_t MMC_BOOT; //offset0C4)
volatile uint32_t VEND_SPEC2; //offset0C8)
volatile uint32_t TUNING_CTRL; //offset0CC)
} IMXRT_USDHC_t;
@PaulStoffregen - Assuming something like other updates like this? Should I update the current defines as well?
like:
Code:
#define IMXRT_USDHC1 (*(IMXRT_REGISTER32_t *)IMXRT_USDHC1_ADDRESS)
// USDHC1 requires CCM_CCGR6_USDHC1
#define USDHC1_DS_ADDR (IMXRT_USDHC1.offset000)
#define USDHC1_BLK_ATT (IMXRT_USDHC1.offset004)
#define USDHC1_CMD_ARG (IMXRT_USDHC1.offset008)
#define USDHC1_CMD_XFR_TYP (IMXRT_USDHC1.offset00C)
Code:
#define IMXRT_USDHC1 (*(IMXRT_USDHC_t *)IMXRT_USDHC1_ADDRESS)
// USDHC1 requires CCM_CCGR6_USDHC1
#define USDHC1_DS_ADDR (IMXRT_USDHC1.DS_ADR)
#define USDHC1_BLK_ATT (IMXRT_USDHC1.BLK_ATT)
#define USDHC1_CMD_ARG (IMXRT_USDHC1.CMD_ARG)
#define USDHC1_CMD_XFR_TYP (IMXRT_USDHC1.XFR_TYP)
...
Moved all of the state variables and functions to be private in SDCardIO.h - not sure if that will fly. Currently SDIO in your fork only supported by Teensy, but I believe maybe supports RPI... or was it ESP...
Added define for SDIO Options: So currently only way to use SDIO 2 (in my test code)
Code:
if (!SD.sdfs.begin(SdioConfig(FIFO_SDIO | USE_SDIO2))) {
Changes in the code so far:
a) Modify functions to not assume USDHC1... Note: I am trying to remove most of the usage of the code to not use mapping T3.x to T4.x register names...
Code:
static bool isBusyTransferComplete() {
return !(SDHC_IRQSTAT & (SDHC_IRQSTAT_TC | SDHC_IRQSTAT_ERROR));
}
...
// Return true if timeout occurs.
static bool waitTimeout(bool (*fcn)()) {
uint32_t m = micros();
while (fcn()) {
if ((micros() - m) > BUSY_TIMEOUT_MICROS) {
return true;
}
}
return false; // Caller will set errorCode.
}
//------------------------------------------------------------------------------
static bool waitTransferComplete() {
if (!m_transferActive) {
return true;
}
bool timeOut = waitTimeout(isBusyTransferComplete);
m_transferActive = false;
...
So modified to be methods on class, which gets called so it has address of the SDIO register structure...
But then had to learn how to call function pointers to non-static class methods. ...
Init the CCM clocks:
Code:
/* Enable USDHC clock. */
if (!fUseSDIO2) {
CCM_CCGR6 |= CCM_CCGR6_USDHC1(CCM_CCGR_ON);
CCM_CSCDR1 &= ~(CCM_CSCDR1_USDHC1_PODF(7));
CCM_CSCMR1 |= CCM_CSCMR1_USDHC1_CLK_SEL; // PLL2PFD0
// CCM_CSCDR1 |= CCM_CSCDR1_USDHC1_CLK_PODF((7)); / &0x7 WHG
CCM_CSCDR1 |= CCM_CSCDR1_USDHC1_CLK_PODF((1));
} else {
CCM_CCGR6 |= CCM_CCGR6_USDHC2(CCM_CCGR_ON);
CCM_CSCDR1 &= ~(CCM_CSCDR1_USDHC2_PODF(7));
CCM_CSCMR1 |= CCM_CSCMR1_USDHC2_CLK_SEL; // PLL2PFD0
// CCM_CSCDR1 |= CCM_CSCDR1_USDHC2_CLK_PODF((7)); / &0x7 WHG
CCM_CSCDR1 |= CCM_CSCDR1_USDHC2_PODF(1);
}
}
Initialize the pins: Note: Different pins and different mode of pins for the SDIO2 pins I am using.
Code:
void SdioCard::gpioMux(uint8_t mode, bool fUseSDIO2) {
if (!fUseSDIO2) {
IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_04 = mode; // DAT2
IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_05 = mode; // DAT3
IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_00 = mode; // CMD
IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_01 = mode; // CLK
IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_02 = mode; // DAT0
IOMUXC_SW_MUX_CTL_PAD_GPIO_SD_B0_03 = mode; // DAT1
} else {
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07 = mode; //USDHC2_DATA3
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06 = mode; //USDHC2_DATA2
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_08 = mode; //USDHC2_CMD
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_09 = mode; //USDHC2_CLK
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_04 = mode; //USDHC2_DATA0
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_05 = mode; //USDHC2_DATA1
}
}
//------------------------------------------------------------------------------
// add speed strength args?
void SdioCard::enableGPIO(bool enable, bool fUseSDIO2) {
const uint32_t CLOCK_MASK = IOMUXC_SW_PAD_CTL_PAD_PKE |
IOMUXC_SW_PAD_CTL_PAD_DSE(7) |
IOMUXC_SW_PAD_CTL_PAD_SPEED(2);
const uint32_t DATA_MASK = CLOCK_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE |
IOMUXC_SW_PAD_CTL_PAD_PUS(1);
if (enable) {
gpioMux(fUseSDIO2? 6 : 0, fUseSDIO2); // SDIO2 is on ALT6
if (!fUseSDIO2) {
IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_04 = DATA_MASK; // DAT2
IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_05 = DATA_MASK; // DAT3
IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_00 = DATA_MASK; // CMD
IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_01 = CLOCK_MASK; // CLK
IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_02 = DATA_MASK; // DAT0
IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_03 = DATA_MASK; // DAT1
} else {
IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_07 = DATA_MASK; //USDHC2_DATA3
IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_06 = DATA_MASK; //USDHC2_DATA2
IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_08 = DATA_MASK; //USDHC2_CMD
IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_09 = CLOCK_MASK; //USDHC2_CLK
IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_04 = DATA_MASK; //USDHC2_DATA0
IOMUXC_SW_PAD_CTL_PAD_GPIO_AD_B1_05 = DATA_MASK; //USDHC2_DATA1
}
Initialize IRQ: ...
DMA: ? not sure we doing much yet here.
Now starting to test: First issue I ran into none of the pins were outputting anything...
Need to Input select them:
Code:
// We need to set select input bits...
IOMUXC_USDHC2_CLK_SELECT_INPUT = 0x1;
IOMUXC_USDHC2_CMD_SELECT_INPUT = 0x01;
IOMUXC_USDHC2_DATA0_SELECT_INPUT = 0x01;
IOMUXC_USDHC2_DATA1_SELECT_INPUT = 0x01;
IOMUXC_USDHC2_DATA2_SELECT_INPUT = 0x01;
IOMUXC_USDHC2_DATA3_SELECT_INPUT = 0x01;
Code is still erroring out with Test program. Just using ListFiles with the change
Code:
if (!SD.sdfs.begin(SdioConfig(FIFO_SDIO | USE_SDIO2))) {
//if (!SD.sdfs.begin(SdioConfig(FIFO_SDIO))) {
//if (!SD.begin(chipSelect)) {
Serial.println("initialization failed! ");
return;
}
Serial.println("initialization done.");
Still getting errors, but some output as partial output:
Code:
Initializing SD card...SdioCard::begin: 1
351 IRQSTAT 2
911 IRQSTAT 2
351 IRQSTAT 2
initialization done.
cardCommand(cdb0000, 0) error return false
LINE: 942
BLKATTR 10200
XFERTYP CDB0000 CMD12 TYP0
PRSSTAT F0888088 SDOFF SDSTB
PROCTL 8800022 EMODE2 DWT1
IRQSTAT 28001 CC
m_irqstat 88000
x.txt 32012 12:42 October 13, 2021
FS.h 8732 16:50 October 3, 2021
T4LargeIndexedTestfile.txt 22014964 07:20 November 5, 2021
test1.txt 21 00:00 ??? 0, 1980
mtpindex.dat 0
foo/
911 IRQSTAT 28001
351 IRQSTAT 28001
cardCommand(d1a0000, b3680000) error return false351 IRQSTAT 18000
cardCommand(d1a0000, b3680000) error isBusyCommandInhibit)
LINE: 913
BLKATTR 10200
XFERTYP D1A0000 CMD13 TYP0
PRSSTAT FF888089 SDOFF SDSTB CIHB
PROCTL 8800022 EMODE2 DWT1
IRQSTAT 18000
m_irqstat 28001
333/
911 IRQSTAT 18000
351 IRQSTAT 18000
cardCommand(d1a0000, b3680000) error isBusyCommandInhibit)
So it looks like somethings are limping along and maybe hope...
Thought I would mention it and also say I pushed the WIP stuff up to:
GitHub - KurtE/SdFat at Experiment_SDIO2
Arduino FAT16/FAT32 Library. Contribute to KurtE/SdFat development by creating an account on GitHub.
github.com
Have not pushed up the imxrt.h changes yet, but...