Skip to main content
Explorer II
April 5, 2022
Question

FatFS on SDMMC not working with DMA on STM32L4A6ZGT6U

  • April 5, 2022
  • 22 replies
  • 16999 views

I'm on STM32CubeIDE Version: 1.9.0 Build: 12015_20220302_0855 (UTC), MCU STM32L4A6ZGTx, Firmware STM32Cube FW_L4 V1.17.1. I'm using a NUCLEO-L4A6ZG.

I'm trying to get FatFS working on SDMMC, with DMA, and having problems.

First, the bundled version of FatFS seems to be ancient. It is so old that it doesn't resemble the documented API at http://elm-chan.org/fsw/ff/00index_e.html. Is there a way I can update it such that my changes won't be wiped out each time I run or update the Device Configuration tool?

The big problem is that it won't work if I select "Use dma template" in Device Configuration Tool/Pinout & Configuration/FATFS/Advanced Settings. If I disable "Use dma template", it works OK (with polling).

With DMA enabled, it gets hung up here:

SD_write() at sd_diskio.c:351 0x80081c8

disk_write() at diskio.c:104 0x800837c

f_mkfs() at ff.c:5,661 0x8008af0

test() at test.c:23 0x80011fc

main() at main.c:103 0x8000914

where I see

if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,
 (uint32_t)(sector),
 count) == MSD_OK)
 {
 /* Wait that writing process is completed or a timeout occurs */
 
 timeout = HAL_GetTick();
 while((WriteStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))
 {
 }
 /* in case of a timeout return error */
 if (WriteStatus == 0)
 {
 res = RES_ERROR;
 }

(SD_write() at sd_diskio.c:351 is line 8 in the snippet).

Apparently, it is waiting for BSP_SD_WriteCpltCallback (or HAL_SD_TxCpltCallback, HAL_SD_IRQHandler, SDMMC1_IRQHandler) which is never called:

void BSP_SD_WriteCpltCallback(void)
{
 
 WriteStatus = 1;
}

At this point, if I look at hsd1, I see:

Instance SDMMC_TypeDef * 0x40012800 (Hex)

POWER volatile uint32_t 0x3 (Hex)

CLKCR volatile uint32_t 0x4900 (Hex)

ARG volatile uint32_t 0x3f (Hex)

CMD volatile uint32_t 0x458 (Hex)

RESPCMD const volatile uint32_t 0x18 (Hex)

RESP1 const volatile uint32_t 0x900 (Hex)

RESP2 const volatile uint32_t 0x5b590000 (Hex)

RESP3 const volatile uint32_t 0x76b27f80 (Hex)

RESP4 const volatile uint32_t 0xa404012 (Hex)

DTIMER volatile uint32_t 0xffffffff (Hex)

DLEN volatile uint32_t 0x200 (Hex)

DCTRL volatile uint32_t 0x99 (Hex)

DCOUNT const volatile uint32_t 0x200 (Hex)

STA const volatile uint32_t 0x145000 (Hex)

ICR volatile uint32_t 0x0 (Hex)

MASK volatile uint32_t 0x1a (Hex)

RESERVED0 uint32_t [2] 0x40012840 (Hex)

FIFOCNT const volatile uint32_t 0x80 (Hex)

RESERVED1 uint32_t [13] 0x4001284c (Hex)

FIFO volatile uint32_t 0x4d90feeb (Hex)

I find it interesting that the MASK is Binary:11010, so only bits 1, 3, and 4 are set, which are:

  • Bit 1 DCRCFAILIE: Data CRC fail interrupt enable
  • Bit 3 DTIMEOUTIE: Data timeout interrupt enable
  • Bit 4 TXUNDERRIE: Tx FIFO underrun error interrupt enable

so this list does not include Bit 8 DATAENDIE: Data end interrupt enable.

STA is Binary:101000101000000000000, which is bits 12, 14, 18, and 20:

  • Bit 20 TXDAVL: Data available in transmit FIFO
  • Bit 18 TXFIFOE: Transmit FIFO empty
  • Bit 14 TXFIFOHE: Transmit FIFO half empty: at least 8 words can be written into the FIFO
  • Bit 12 TXACT: Data transmit in progress

It's trying to send a 512 byte block:

  • DLEN volatile uint32_t 0x200 (Hex)
  • DCOUNT const volatile uint32_t 0x200 (Hex)

Since DCOUNT has not decremented, it looks like no data has been transferred.

What could be the problem?

I put the project on GitHub: https://github.com/carlk3/STM32L4A6ZGTx_SDMMC. It should be complete enough to build. (Is that the best way to share code here? It's fairly painless with EGit: the Git integration for Eclipse).

    This topic has been closed for replies.

    22 replies

    CKugl.1Author
    Explorer II
    April 7, 2022

    I'm still trying to get this working. For now, I've disabled FatFS in the Device Configuration Tool and I'm just trying to work at the HAL level.

    First, initialization:

     	HAL_StatusTypeDef hal_rc = HAL_SD_Init(&hsd1);
     	if (hal_rc != HAL_OK)
    		return RES_ERROR;
     
    	/* Configure SD Bus width (4 bits mode selected) */
    	/* Enable wide operation */
    	if (HAL_SD_ConfigWideBusOperation(&hsd1, SDMMC_BUS_WIDE_4B) != HAL_OK)
    		return RES_ERROR;
     

    Next, to write a block to the SD card:

    assert(0 == ((uintptr_t )buff & 0x3)); // Check for WORD alignment for DMA
     
    	if (HAL_SD_WriteBlocks_DMA(&hsd1, (uint8_t*) buff, sector, count) != HAL_OK) {
    		return RES_ERROR;
    	}

    At this point I would expect a `HAL_SD_TxCpltCallback` but it never comes.

    `HAL_DMA_GetState` just returns HAL_DMA_STATE_BUSY forever.

    In hsd1, DLEN and DCOUNT are both 512 (the block size).

    DCTRL is Binary:10011001

    STA is Binary:100000101000000000000.

    MASK is Binary:11010.

    In hsd1.hdmatx,

    CCR: Binary:10101010011011

    CNDTR: Decimal:128 (Hex:0x80)

    If I'm reading this right, DCTRL says:

    • DTEN: Data transfer enabled bit: enabled
    • DMAEN: DMA enable bit: enabled
    • DBLOCKSIZE: Data block size: 512 bytes

    DMA CCR says:

    • PL[1:0]: priority level: high
    • MSIZE[1:0]: memory size: 32 bits
    • PSIZE[1:0]: peripheral size: 32 bits
    • MINC: memory increment mode: enabled
    • PINC: peripheral increment mode: disabled
    • CIRC: circular mode: disabled
    • DIR: data transfer direction: read from memory
    • TEIE: transfer error interrupt enable: enabled
    • HTIE: half transfer interrupt enable: disabled
    • TCIE: transfer complete interrupt enable: enabled
    • EN: channel enable: enabled

    Why isn't my transfer completing?

    If I change the code to `HAL_SD_WriteBlocks(&hsd1, (uint8_t*) buff, sector, count, Timeout)` instead of `HAL_SD_WriteBlocks_DMA(&hsd1, (uint8_t*) buff, sector, count)` it runs.

    I have tried with and without Hardware Flow Control. (If I don't use DMA I get underrun errors without the Flow Control).

    ST Employee
    April 7, 2022

    Hi @CKugl.1​ 

    >STM32Cube FW_L4 V1.17.1. I'm using a NUCLEO-L4A6ZG.

    AFAIK, this board is not equipped with uSD slot, how are you running the example on it?

    are you using an arduino shield?

    CKugl.1Author
    Explorer II
    April 7, 2022

    I'm using an Adafruit 4682 Micro SD SPI or SDIO Card Breakout Board wired to SDMMC1. Originally, I used a breadboard and some jumpers. Since then I've moved it to a soldered protoboard plugged into CN8 and CN9 with berg strips (but it doesn't work any better).

    CKugl.1Author
    Explorer II
    April 7, 2022

    I can read successfully with DMA, but not write. I.e., HAL_SD_ReadBlocks_DMA works, but HAL_SD_WriteBlocks_DMA does not. If I write with HAL_SD_WriteBlocks and read the data back with HAL_SD_ReadBlocks_DMA, it works, as shown in the attached test case. It produces the following output:

    test:152: SD Card State:Card is in transfer state        

    test:172: SD Card State:Card is in programming state       

    test:172: SD Card State:Card is in transfer state        

    test:184: DMA State:DMA initialized and ready for use  

    test:188: SD Card State:Card is in transfer state        

     Read data matched.

    CKugl.1Author
    Explorer II
    April 7, 2022

    I modified my test case to use HAL_SD_WriteBlocks_DMA. I added some code to print out the SDMMC and DMA registers before and after the call. Here is the output:

    test:185: Starting
    test:201: SD Card State: Card is in transfer state 
    test:219: SDMMC registers:
     3 2 1 0
     10987654321098765432109876543210
     POWER : 0b00000000000000000000000000000011
     CLKCR : 0b00000000000000000100100100000001
     ARG : 0b11100110001001000000000000000000
     CMD : 0b00000000000000000000010001001101
     RESPCMD: 0b00000000000000000000000000001101
     RESP1 : 0b00000000000000000000100100000000
     RESP2 : 0b01011011010110010000000000000000
     RESP3 : 0b01110110101100100111111110000000
     RESP4 : 0b00001010010000000100000000010010
     DTIMER : 0b11111111111111111111111111111111
     DLEN : 0b00000000000000000000000000001000
     DCTRL : 0b00000000000000000000000000110011
     DCOUNT : 0b00000000000000000000000000000000
     STA : 0b00000000000000000000000000000000
     ICR : 0b00000000000000000000000000000000
     MASK : 0b00000000000000000000000000000000
     FIFOCNT: 0b00000000000000000000000000000000
     FIFO : 0b00000011100000000011010100000010
    test:221: TX DMA State: DMA initialized and ready for use 
    test:223: TX DMA registers:
     3 2 1 0
     10987654321098765432109876543210
     CCR : 0b00000000000000000011101010010000
     CNDTR : 0b00000000000000000000000000000000
     CPAR : 0b00000000000000000000000000000000
     CMAR : 0b00000000000000000000000000000000
     
    test:226: Writing
    test:233: SDMMC registers:
     3 2 1 0
     10987654321098765432109876543210
     POWER : 0b00000000000000000000000000000011
     CLKCR : 0b00000000000000000100100100000001
     ARG : 0b00000000000000000000000000000000
     CMD : 0b00000000000000000000010001011000
     RESPCMD: 0b00000000000000000000000000011000
     RESP1 : 0b00000000000000000000100100000000
     RESP2 : 0b01011011010110010000000000000000
     RESP3 : 0b01110110101100100111111110000000
     RESP4 : 0b00001010010000000100000000010010
     DTIMER : 0b11111111111111111111111111111111
     DLEN : 0b00000000000000000000001000000000
     DCTRL : 0b00000000000000000000000010011001
     DCOUNT : 0b00000000000000000000001000000000
     STA : 0b00000000000101000101000000000000
     ICR : 0b00000000000000000000000000000000
     MASK : 0b00000000000000000000000000011010
     FIFOCNT: 0b00000000000000000000000010000000
     FIFO : 0b00000011000000100000000100000000
    test:236: TX DMA State: DMA process is ongoing 
    test:238: TX DMA registers:
     3 2 1 0
     10987654321098765432109876543210
     CCR : 0b00000000000000000011101010011011
     CNDTR : 0b00000000000000000000000010000000
     CPAR : 0b01000000000000010010100010000000
     CMAR : 0b00100000000001001111011111001100
    test:245: SD Card State: Card is receiving operation information 
    test:245: SD Card State: Card is receiving operation information 
    test:245: SD Card State: Card is receiving operation information 
    test:245: SD Card State: Card is receiving operation information 
    test:245: SD Card State: Card is receiving operation information 
    test:245: SD Card State: Card is receiving operation information 
     

     Here is a diff of before and after the HAL_SD_WriteBlocks_DMA call:

    1c1
    < test:219: SDMMC registers:
    ---
    > test:233: SDMMC registers:
    6,8c6,8
    < ARG : 0b11100110001001000000000000000000
    < CMD : 0b00000000000000000000010001001101
    < RESPCMD: 0b00000000000000000000000000001101
    ---
    > ARG : 0b00000000000000000000000000000000
    > CMD : 0b00000000000000000000010001011000
    > RESPCMD: 0b00000000000000000000000000011000
    14,17c14,17
    < DLEN : 0b00000000000000000000000000001000
    < DCTRL : 0b00000000000000000000000000110011
    < DCOUNT : 0b00000000000000000000000000000000
    < STA : 0b00000000000000000000000000000000
    ---
    > DLEN : 0b00000000000000000000001000000000
    > DCTRL : 0b00000000000000000000000010011001
    > DCOUNT : 0b00000000000000000000001000000000
    > STA : 0b00000000000101000101000000000000
    19,23c19,23
    < MASK : 0b00000000000000000000000000000000
    < FIFOCNT: 0b00000000000000000000000000000000
    < FIFO : 0b00000011100000000011010100000010
    < test:221: TX DMA State: DMA initialized and ready for use
    < test:223: TX DMA registers:
    ---
    > MASK : 0b00000000000000000000000000011010
    > FIFOCNT: 0b00000000000000000000000010000000
    > FIFO : 0b00000011000000100000000100000000
    > test:236: TX DMA State: DMA process is ongoing
    > test:238: TX DMA registers:
    26,29c26,29
    < CCR : 0b00000000000000000011101010010000
    < CNDTR : 0b00000000000000000000000000000000
    < CPAR : 0b00000000000000000000000000000000
    < CMAR : 0b00000000000000000000000000000000
    ---
    > CCR : 0b00000000000000000011101010011011
    > CNDTR : 0b00000000000000000000000010000000
    > CPAR : 0b01000000000000010010100010000000
    > CMAR : 0b00100000000001001111011111001100

    CKugl.1Author
    Explorer II
    April 9, 2022

    I happen to have a NUCLEO-F413ZH lying around, so I unplugged my SD card adapter from the NUCLEO-L4A6ZG and plugged it into that, then ported my test case. It runs great, reading and writing with DMA! However, I need to use the L4 chip (for the low power consumption). So, I'm still trying to figure out why that gets hung up in HAL_SD_WriteBlocks_DMA .

    CKugl.1Author
    Explorer II
    April 11, 2022

    I'm back on the NUCLEO-L4A6ZG trying to run the same test case that runs successfully on the NUCLEO-F413ZH.

    On the NUCLEO-F413ZH, here's what I see with a logic analyzer on the SD bus when I call HAL_SD_WriteBlocks_DMA:

    0693W00000LxcmFQAR.pngOn the NUCLEO-L4A6ZG, here's what I see with a logic analyzer on the SD bus when I call HAL_SD_WriteBlocks_DMA:

    0693W00000LxcsmQAB.pngThere is no activity at all on the data lines!

    Now, again on NUCLEO-L4A6ZG, if I simply change HAL_SD_WriteBlocks_DMA to HAL_SD_WriteBlocks, I get this:

    0693W00000LxcuiQAB.pngSo, when I call HAL_SD_WriteBlocks_DMA on the L4A6ZG, the command is sent but no data is ever sent.

    Graduate II
    April 11, 2022

    The F4 and L4+ have different SDIO vs SDMMC IP, and the L4 has at least 3 implementations, including different approaches to integrating DMA, and using 1 or 2 DMA channels So let's avoid an Apples to Oranges comparison about how thing need to work, because its different between various architectures.

    The L496/L4A6 DMA for write should looks something like this, as it has ONE DMA resource, and it must be configured in a directionally appropriate manner.

    /**
     * @brief Writes block(s) to a specified address in an SD card, in DMA mode.
     * @param pData: Pointer to the buffer that will contain the data to transmit
     * @param WriteAddr: Address from where data is to be written
     * @param NumOfBlocks: Number of SD blocks to write
     * @retval SD status
     */
    uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks)
    {
     HAL_StatusTypeDef sd_state = HAL_OK;
     
     /* Invalidate the dma rx handle*/
     uSdHandle.hdmarx = NULL;
     
     /* Prepare the dma channel for a write/tx operation */
     sd_state = SD_DMAConfigTx(&uSdHandle);
     
     if (sd_state == HAL_OK)
     {
     /* Write block(s) in DMA transfer mode */
     sd_state = HAL_SD_WriteBlocks_DMA(&uSdHandle, (uint8_t *)pData, WriteAddr, NumOfBlocks);
     }
     
     if (sd_state == HAL_OK)
     {
     return MSD_OK;
     }
     else
     {
     return MSD_ERROR;
     }
    }
    ...
    /**
     * @brief Configure the DMA to transmit data to the SD card
     * @retval
     * HAL_ERROR or HAL_OK
     */
    static HAL_StatusTypeDef SD_DMAConfigTx(SD_HandleTypeDef *hsd)
    {
     static DMA_HandleTypeDef hdma_tx;
     HAL_StatusTypeDef status;
     
     /* Configure DMA Tx parameters */
     hdma_tx.Init.Request = DMA_REQUEST_7;
     hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
     hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
     hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
     hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
     hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
     hdma_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
     
     hdma_tx.Instance = SD_DMAx_STREAM;
     
     /* Associate the DMA handle */
     __HAL_LINKDMA(hsd, hdmatx, hdma_tx);
     
     /* Stop any ongoing transfer and reset the state*/
     HAL_DMA_Abort(&hdma_tx);
     
     /* Deinitialize the Channel for new transfer */
     HAL_DMA_DeInit(&hdma_tx);
     
     /* Configure the DMA Channel */
     status = HAL_DMA_Init(&hdma_tx);
     
     /* NVIC configuration for DMA transfer complete interrupt */
     HAL_NVIC_SetPriority(SD_DMAx_IRQn, 6, 0);
     HAL_NVIC_EnableIRQ(SD_DMAx_IRQn);
     
     return (status);
    }

    CKugl.1Author
    Explorer II
    April 11, 2022

    Thanks. I tried your code, but it still hangs up:

    test:334: Starting

    test:339: SD State: SD initialized and ready for use  

    test:340: SD Card State: Card is in transfer state        

    test:387: TX DMA registers:
     3 2 1 0
     10987654321098765432109876543210
     CCR : 0b00000000000000000011101010011011
     CNDTR : 0b00000000000000000000000010000000
     CPAR : 0b01000000000000010010100010000000
     CMAR : 0b00100000000000000001110101110000
     ISR : 0b00000000000000000000000000000000

    test:394: SD Card State: Card is receiving operation information 

    test:396: TX DMA State: DMA process is ongoing       

    SD State: SD process ongoing         

    test:394: SD Card State: Card is receiving operation information 

    test:396: TX DMA State: DMA process is ongoing       

    SD State: SD process ongoing         

    test:394: SD Card State: Card is receiving operation information 

    test:396: TX DMA State: DMA process is ongoing       

    SD State: SD process ongoing         

    test:394: SD Card State: Card is receiving operation information 

    test:396: TX DMA State: DMA process is ongoing       

    SD State: SD process ongoing         

    test:394: SD Card State: Card is receiving operation information 

    test:396: TX DMA State: DMA process is ongoing       

    SD State: SD process ongoing         

    CKugl.1Author
    Explorer II
    April 11, 2022

    Prior to the call to HAL_SD_WriteBlocks_DMA on the L4A6ZG, the TX DMA registers:

     TX DMA registers:
     3 2 1 0
     10987654321098765432109876543210
     CCR : 0b00000000000000000011101010010000
     CNDTR : 0b00000000000000000000000000000000
     CPAR : 0b00000000000000000000000000000000
     CMAR : 0b00000000000000000000000000000000
     ISR : 0b00000000000000000000000000000000

    The DMA channel x configuration register (DMA_CCRx) says:

    • Bit 0 EN: channel enable: 0: disabled
    • Bit 1 TCIE: transfer complete interrupt enable: 0: disabled
    • HTIE: half transfer interrupt enable and TEIE: transfer error interrupt enable: disabled
    • Bit 4 DIR: data transfer direction: 1: read from memory
    • Bit 5 CIRC: circular mode: 0: disabled
    • Bit 6 PINC: peripheral increment mode: 0: disabled
    • Bit 7 MINC: memory increment mode: 1: enabled
    • Bits 9:8 PSIZE[1:0]: peripheral size: 10: 32 bits
    • Bits 11:10 MSIZE[1:0]: memory size: 10: 32 bits
    • Bits 13:12 PL[1:0]: priority level: 11: very high
    • Bit 14 MEM2MEM: memory-to-memory mode: 0: disabled

    DMA channel x number of data to transfer register (DMA_CNDTRx) is 0.

    DMA channel x peripheral address register (DMA_CPARx) is 0.

    DMA channel x memory address register (DMA_CMARx) is 0.

    DMA interrupt status register (DMA_ISR) is all 0.

    CKugl.1Author
    Explorer II
    April 11, 2022

    After the call to HAL_SD_WriteBlocks_DMA on the L4A6ZG, the TX DMA registers:

    TX DMA registers:
     3 2 1 0
     10987654321098765432109876543210
     CCR : 0b00000000000000000011101010011011
     CNDTR : 0b00000000000000000000000010000000
     CPAR : 0b01000000000000010010100010000000
     CMAR : 0b00100000000000000001110101110000
     ISR : 0b00000000000000000000000000000000

    The DMA channel x configuration register (DMA_CCRx) says:

    • Bit 0 EN: channel enable: 1: enabled
    • Bit 1 TCIE: transfer complete interrupt enable: 1: enabled
    • Bit 2 HTIE: half transfer interrupt enable: 0: disabled
    • Bit 3 TEIE: transfer error interrupt enable: 1: enabled
    • Bit 4 DIR: data transfer direction: 1: read from memory
    • Bit 5 CIRC: circular mode: 0: disabled
    • Bit 6 PINC: peripheral increment mode: 0: disabled
    • Bit 7 MINC: memory increment mode: 1: enabled
    • Bits 9:8 PSIZE[1:0]: peripheral size: 10: 32 bits
    • Bits 11:10 MSIZE[1:0]: memory size: 10: 32 bits
    • Bits 13:12 PL[1:0]: priority level: 11: very high
    • Bit 14 MEM2MEM: memory-to-memory mode: 0: disabled

    DMA channel x number of data to transfer register (DMA_CNDTRx): Decimal:128 (Hex:0x80) (which I assume is the number of WORDS).

    DMA channel x peripheral address register (DMA_CPARx) is Hex:0x40012880.

    DMA channel x memory address register (DMA_CMARx) is 0x20001d70.

    DMA interrupt status register (DMA_ISR) is all 0.

    If channel enable is 1: enabled, what's stopping it from running?

    CKugl.1Author
    Explorer II
    April 11, 2022

    Do these interrupt priorities seem reasonable?

    NVIC Interrupt Table	Enabled	Preemption Priority	Sub Priority																						
    Non maskable interrupt	TRUE	0	0																						
    Hard fault interrupt	TRUE	0	0																						
    Memory management fault	TRUE	0	0																						
    Prefetch fault, memory access fault	TRUE	0	0																						
    Undefined instruction or illegal state	TRUE	0	0																						
    System service call via SWI instruction	TRUE	0	0																						
    Debug monitor	TRUE	0	0																						
    Pendable request for system service	TRUE	0	0																						
    System tick timer	TRUE	15	0																						
    PVD/PVM1/PVM2/PVM3/PVM4 interrupts through EXTI lines 16/35/36/37/38	FALSE	0	0																						
    Flash global interrupt	FALSE	0	0																						
    RCC global interrupt	FALSE	0	0																						
    Time base: TIM1 trigger and commutation interrupts and TIM17 global interrupt	TRUE	15	0																						
    EXTI line[15:10] interrupts	FALSE	0	0																						
    SDMMC1 global interrupt	TRUE	7	0																						
    DMA2 channel4 global interrupt	TRUE	6	0																						
    DMA2 channel5 global interrupt	TRUE	6	0																						
    USB OTG FS global interrupt	FALSE	0	0																						
    LPUART1 global interrupt	TRUE	10	0																						
    FPU global interrupt	FALSE	0	0																						

    In case that's too hard to read:

    0693W00000Lxe7dQAB.png

    Graduate II
    April 11, 2022

    Look to be reasonable.

    I'd avoid printing the FIFO register, no good is likely to occur.

    I'm not looking to put engineering hours into this.