How to cancel multi-block SDHC transfers?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to cancel multi-block SDHC transfers?

3,605 Views
mjbcswitzerland
Specialist V

Hi All

Has anyone knowledge of how to cancel a multi-block transfer than is in process to/from an SD card using the SDHC controller.

The basic transfer itself is not a problem (eg. multi-block write):

- the number of blocks to be transfered is set in the SDHC_BLKATTR register
- the CMD25 is sent to the SD card to set it to the multi-block mode (it doesn't need to know how any blocks will arrive)

- When the number of data blocks have been transfered the CMD12 is sent (either manually or automatically by the SDHC controller)

However there are various applications accessing the SD card and so there are instances when the transfer has to be terminated before the block count has been reached, and then continued later. This not a problem for the SD card since it just needs to receive the CMD12 after any number of blocks but how does the SDHC handle this?
There are (at least) two possible solutions - both of which are presently causing difficulties:
1. If not using automatic CMD12 it would be possible to simply send a multiple number of single blocks and simply send the CMD12 when the transmission needs to be terminate (either at end or prematurely). The problem is that the SDHC controller is not allowing this without first sending a command before each single block. It disables the data transmission after one single block. (SDHC_PRSSTAT_BWEN in SDHC_PRSSTAT remains at '0')

2. Set the block count for transmission and simply send the CMD12 manually in case the transmission needs to be terminated early. The difficulty with this is that the SDHC controller doesn't allow the command to be send before the complete data transmission has terminated without resetting the data unit. Furthermore it is not easy to be sure that the complete block presently in progress has really been completely sent out (transmission complete flag is not set since the SDHC is expecting more blocks). After resetting the data unit the CMD12 is possible but there are some otherside effects that cause other problems (at the moment) so doesn't seen be a good solution.

Is there a "correct" way to do this that is foreseen in the controller?

Regards

Mark

Labels (1)
Tags (3)
0 Kudos
Reply
4 Replies

1,612 Views
gbelokrylov
Contributor II

Hi, Mark.

I don't think it is possible to correctly terminate transmission mid-block.

Otherwise, for a muiti-block read you can set SABGREQ bit in the PROCTL register, completely read host controller's buffer until BREN in PRSSTAT has been cleared, clear SABGREQ and manually send CMD12. My tests show that if you don't wait too long there will be no more than one sector in the buffer.

For a multi-block write you need to set SABGREQ, wait until TCSEN bit in IRQSTATEN has been set, clear SABGREQ, send CMD12 and wait until card transitions from prg to tran state (just like after full write, using CMD13 to monitor card status).

0 Kudos
Reply

1,612 Views
mjbcswitzerland
Specialist V

Hi Grigorii

Thanks for pointing out the SABGREQ bit!

Unfortunately, when trying to use this to stop a mult-block write it is having no effect at the moment.

What I do as a test is set up for 3 block transfers but only make 2 of them. This leaves the SDHC waiting for the third and final block to be sent (after which all would be OK). I then try to stop the transfer (this is always 'between' blocs and not actually "during" a block transfer) by using this bit and hoping to be able to send CMD12 afterwards.

When I set SABGREQ nothing seems to happen; according to its description there should be an effect on PRSSTAT[RTA], PRSSTAT[WTA] and PRSSTAT[CDIHB] but no change is seen. Also, the description says that one must wait for IRQSTATEN[TCSEN] to set to 1, but this bit is already set to '1' - its default value. In fact this looks to be a mistake because IRQSTATEN[TCSEN] is an enable bit and not a status bit - there is a staus bit called BGE (block gap event) in SDHC_IRQSTAT which seems more likely (it remains at '0').


Since there is no reaction to setting SABGREQ I am worried that it may only work when set 'during' a block transfer and not between blocks in the transfer.


This means that presently the SHCD interface is still blocked, waiting for more blocks to be sent, so the CMD12 still cannot be issued!.


Have you been able to get this to work?

Regards

Mark

0 Kudos
Reply

1,612 Views
ferdinandnavarr
Contributor I

Hello Mark,

Have you found a way to solve this? SABGREQ seems not to work also on my side, maybe I have incorrect setting. As a temporary work around, I tried to software reset the CMD and DAT line to cancel multi-block write transfer, but maybe this is not a very clean work around. Maybe you can also share your solution to this issue. Thank you.

0 Kudos
Reply

1,612 Views
mjbcswitzerland
Specialist V

Hi Ferdinand

I did not find a way to stop transfers so had to give up on fast block data transfers with the Kinetis SDHC.

For high speed applications it may be more efficient to use 1 bit SPI mode.

Regards

Mark

0 Kudos
Reply