1
0
mirror of git://projects.qi-hardware.com/ben-blinkenlights.git synced 2024-11-27 19:14:40 +02:00

ubb-patgen/ubb-patgen.c: describe the pattern transfer logic

This commit is contained in:
Werner Almesberger 2013-01-14 17:01:13 -03:00
parent fa8b5b6324
commit e5cb1c98ea

View File

@ -204,6 +204,13 @@ static void wait_shifted(const struct mmcclk *clk)
static void mmc_buffer(const struct mmcclk *clk, static void mmc_buffer(const struct mmcclk *clk,
uint8_t first, unsigned long buf, int nibbles, uint32_t mask) uint8_t first, unsigned long buf, int nibbles, uint32_t mask)
{ {
/*
* If under control of the MMC controller, DATx tri-state until we
* actually send data. That's why they have been set up as GPIOs and
* we'll only switch them to function when the MMC controller is in a
* well-defined state.
*/
MSC_STRPCL = 1 << 3; /* reset the MSC */ MSC_STRPCL = 1 << 3; /* reset the MSC */
while (MSC_STAT & (1 << 15)); /* wait until reset finishes */ while (MSC_STAT & (1 << 15)); /* wait until reset finishes */
@ -224,6 +231,12 @@ static void mmc_buffer(const struct mmcclk *clk,
MSC_STRPCL = 4; /* START_OP */ MSC_STRPCL = 4; /* START_OP */
/*
* Make sure we've reached the end of the command and then send the
* first pattern (eight times, since this is the smallest amount we
* can send.
*/
wait_response(); wait_response();
MSC_TXFIFO = first*0x11111111; MSC_TXFIFO = first*0x11111111;
@ -231,8 +244,20 @@ static void mmc_buffer(const struct mmcclk *clk,
wait_fifo_empty(); wait_fifo_empty();
wait_shifted(clk); wait_shifted(clk);
/*
* Since the transfer (of nominally 4095 bytes) is not done yet, the
* MMC controller will hold the bus at the last value sent. It's now
* safe to switch from GPIO to function.
*/
PDFUNS = mask; PDFUNS = mask;
/*
* Send the pattern with DMA. Note that we still have to send the first
* pattern, since the static state we begin from may not have been
* present long enough.
*/
DCS(DMA) = DCS(DMA) =
(1 << 31) | /* no descriptor */ (1 << 31) | /* no descriptor */
1; /* enable transfer */ 1; /* enable transfer */
@ -241,6 +266,14 @@ static void mmc_buffer(const struct mmcclk *clk,
wait_fifo_empty(); wait_fifo_empty();
wait_shifted(clk); wait_shifted(clk);
/*
* We're done. As far as the MMC controller is concerned, the transfer
* is still not finished (i.e., we haven't sent 4095 bytes) and will
* therefore just hold the bus. We can now return the bus to GPIO.
* This form of handover also prevents the MMC controller from sending
* a CRC, which may confuse the recipient of the pattern.
*/
} }
@ -277,6 +310,8 @@ static int dma_pattern(const struct mmcclk *clk,
dma_init(); dma_init();
/* Initial static state: the first pattern. */
PDFUNS = UBB_CMD; PDFUNS = UBB_CMD;
PDDATC = ~((buf[0] >> 4) << 10) & mask; PDDATC = ~((buf[0] >> 4) << 10) & mask;
PDDATS = (buf[0] >> 4) << 10; PDDATS = (buf[0] >> 4) << 10;
@ -284,6 +319,8 @@ static int dma_pattern(const struct mmcclk *clk,
send_buffer(clk, buf, rounded, mask); send_buffer(clk, buf, rounded, mask);
/* Final static state: the last pattern. */
PDDATC = ~((buf[(rounded >> 1)-1] & 0xf) << 10) & mask; PDDATC = ~((buf[(rounded >> 1)-1] & 0xf) << 10) & mask;
PDDATS = (buf[(rounded >> 1)-1] & 0xf) << 10; PDDATS = (buf[(rounded >> 1)-1] & 0xf) << 10;