SLAU723A October 2017 – October 2018 MSP432E401Y , MSP432E411Y
The EPI Controller supports a special kind of read called a nonblocking read, also referred to as a posted read. Where a normal read stalls the processor or µDMA until the data is returned, a nonblocking read is performed in the background.
A nonblocking read is configured by writing the start address into a EPIRADDRn register, the size per transaction into a EPIRSIZEn register, and then the count of operations into a EPIRPSTDn register. After each read is completed, the result is written into the NBRFIFO and the EPIRADDRn register is incremented by the size (1, 2, or 4). The three most significant bits of the EPIRADDRn register are only relevant in the host bus multi-chip select mode when they are used to enable the different chip selects.
If the NBRFIFO is filled, then the reads pause until space is made available. The NBRFIFO can be configured to interrupt the processor or trigger the µDMA based on the amount of data in the FIFO using the EPIFIFOLVL register. By using the trigger and interrupt method, the µDMA (or processor) can keep space available in the NBRFIFO and allow the reads to continue unimpeded.
When performing nonblocking reads, the SDRAM controller issues two additional read transactions after the burst request is terminated. The data for these additional transfers is discarded. This situation is transparent to the user other than the additional EPI bus activity and can safely be ignored.
Two nonblocking read register sets are available to allow sequencing and ping-pong use. When one completes, the other then activates. So, for example, if 20 words are to be read from 0x100 and 10 words from 0x200, the EPIRPSTD0 register can be set up with the read from 0x100 (with a count of 20), and the EPIRPSTD1 register can be set up with the read from 0x200 (with a count of 10). When EPIRPSTD0 finishes (count goes to 0), the EPIRPSTD1 register then starts its operation. The NBRFIFO has then passed 30 values. When used with the µDMA, it may transfer 30 values (simple sequence), or the primary/alternate model may be used to handle the first 20 in one way and the second 10 in another. It is also possible to reload the EPIRPSTD0 register when it is finished (and the EPIRPSTD1 register is active); thereby, keeping the interface constantly busy.
To cancel a nonblocking read, the EPIRPSTDn register is cleared. Care must be taken, however if the register set was active to drain away any values read into the NBRFIFO and ensure that any read in progress is allowed to complete.
To ensure that the cancel is complete, the following algorithm is used (using the EPIRPSTD0 register for example):
EPIRPSTD0 = 0;
while ((EPISTAT & 0x11) == 0x10)
; // we are active and busy
// if here, then other one is active or interface no longer busy
cnt = (EPIRADDR0 - original_address) / EPIRSIZE0; // count of values read
cnt -= values_read_so_far;
// cnt is now number left in FIFO
while (cnt--)
value = EPIREADFIFO; // drain
ISB
The preceding algorithm can be optimized in code; however, the important point is to wait for the cancel to complete, because the external interface could have been in the process of reading a value when the cancel came in, and it must be allowed to complete.