You are on page 1of 20

NuMicro® PDMA

A Leading MCU Platform Provider

June 2016
Agenda
• PDMA Features
• PDMA Block Diagram
• PDMA Function Descriptions
• CRC Function Descriptions
• Functions and Sample Code in BSP
• Sample Code

2
Features (PDMA)
• Up to 9 channels of PDMA (Channel 0 ~ 8)
–Memory-to-Memory (Word alignment transfer length)
–Memory-to-Peripheral (Word/Half-word/byte alignment transfer length
and data width)
–Peripheral-to-Memory (Word/Half-word/byte alignment transfer length
and data width)
• Word boundary address.
• One word buffer.
• Two kinds of address direction for src. and dest.
– Increment
– Fixed 3
Features (CRC)
• Four common polynomials, CRC-CCITT, CRC-8, CRC-16 and
CRC-32.
• Programmable seed value.
• Programmable Order Reverse/1’s Complement setting for
input data and CRC checksum.
• Supports CPU PIO mode or DMA transfer mode.
–Support 8/16/32-bit of data width in CPU PIO mode.
–Support byte alignment transfer length in DMA transfer mode.
4
PDMA Block Diagram

5
Memory-to-Memory - Revised
PDMA_SARx PDMA_BCRx AHBCLK
Source Addr. Byte Counter PDMA engine clock
(word alignment) PDMA_GCRCSR
0x55555555
PDMA channel clock
SAD_SEL 0x12345678 PDMA_PDSSRx
Source Addr. Direction
Channel service setting
Fixed or Incremental Source
PDMA PDMACEN
Enable PDMA
Controller TRIG_EN
Channel x Start PDMA data
transfer
PDMA_DARx
Destination Addr. 0x55555555
(word alignment) 0x12345678
DAD_SEL
Dest. Addr. Direction
Destination
Fixed or Incremental
MODE_SEL(00b)
Memory-to-Memory
Memory 6
Memory-to-Peripheral - Revised AHBCLK
PDMACEN PDMA engine clock
Enable PDMA PDMA_GCRCSR
TRIG_EN PDMA channel clock
Start PDMA data PDMA_PDSSRx
transfer Channel service setting
PDMA_SARx SAD_SEL PDMA_DARx
Source Addr. Source Addr. Direction Destination Addr. DAD_SEL
(word alignment) Fixed or Incremental (word alignment) Dest. Addr. Direction
Fixed or Incremental
PDMA_BCRx
Byte Counter
AA 55 12 34
CD AB EF 78
PDMA
Source Controller Destination
AA
55
Channel x
MODE_SEL(10b)
Memory-to-Peripheral
APB_TWS Peripheral
Memory 00b = One word
01b = One byte
10b = half word
7
Peripheral-to-Memory - Revised AHBCLK
PDMACEN
Enable PDMA PDMA engine clock
TRIG_EN PDMA_GCRCSR
Start PDMA data PDMA channel clock
transfer PDMA_PDSSRx
PDMA_DARx DAD_SEL Channel service setting
Destination Addr. Dest. Addr. Direction PDMA_SARx
Source Addr. SAD_SEL
(word alignment) Fixed or Incremental
(word alignment) Source Addr. Direction
Fixed or Incremental
PDMA_BCRx
Byte Counter
AA 55

PDMA
Destination Controller Source
AA
55
Channel x
MODE_SEL(01b)
Peripheral-to-Memory
APB_TWS Peripheral
Memory 00b = One word
01b = One byte
10b = half word
8
PDMA Interrupt
• BLKD_IF: Block Transfer Done Flag
- After PDMA transferred all of the byte count number which indicated
in PDMA_BCRx register, the BLKD flag will be set (PDMA_ISRx[1]).
• TABORT_IF: Read/Write Target Abort Flag
- If bus ERROR response received, TABORT_IF (PDMA_ISRx[0]) will be set.
- Write “1” to TABORT_IF bit and TABORT_IF will be cleared.
- Sets PDMA Software reset bit ([SW_RST]) to “1”. It will reset the
PDMA channel. This bit will self-cleared after few clock.
- Set [PDMACEN] and [Trig_EN] bits to “1”. It will start PDMA function
again.
9
CRC Block Diagram
Slave Wrapper CRC Checksum Reg

CRC CTL
Reg

CRC Seed
Reg
CCITT
AHB BUS

MUX
D Q Checksum
B3 CRC-8
MUX Reverse /
MUX

MUX
B2 In Data
B1 Reverse/ 1's COMP
B0 1's COMP CRC-16
Bus Master

CRC-32
CRC CTL

CRC BM
z
FSM
Control

10
CRC Procedure
CRCCCITT
CRC-8
CRC_MODE(CRC_CTL[31:30])
CRC-16
CRCCEN(CRC_CTL[0])
Reverse CRC-32
EX: 0XDD7B0F2E
CPU PIO Mode CPU DMA Mode
=> 0x74F0DEBB Operating mode

WDATA_RVS WDATA_RVS
CHECKSUM_RVS CHECKSUM_RVS
WDATA_COM 1’s complement CHECKSUM_COM
CHECKSUM_COM WDATA_COM House: please
CRC_SEED CRC_SEED
CPUWDLEN Initial CRC seed Source Address to revise from
CRC_DMASAR
Byte Count to
original ppt -
CRC_DMABCR
Modified
Set CRC_RST = 1 Select write data length
Set TRIG_EN = 1

Write Data to
CRC_WDATA CRC_BLKD_IF

Get Checksum from Get Checksum from


CRC_CHECKSUM CRC_CHECKSUM
11
Sample Code Path

NUC029xEEBSPv3.00.001

NuMicro NUC029 Series


Document Driver Reference Guide

SampleCode

StdDriver

SPI_PDMA_Loopback

SPI_PDMA_Loopback.uvproj
KEIL

12
Functions and Sample Code in BSP
• \SampleCode\StdDriver
- UART_PDMA
- SPI_PDMA_Loopback
- PDMA

13
Functions and Sample Code in BSP
• spi.c
- uint32_t SPI_Open (SPI_T *spi, uint32_t u32MasterSlave, uint32_t u32SPIMode,
uint32_t u32DataWidth, uint32_t u32BusClock)
//This function make SPI module be ready to transfer
SpiLoopTest_WithPDMA();

• PDMA.h
- PDMA_Open((1 << SPI_MASTER_TX_DMA_CH) | (1 << SPI_MASTER_RX_DMA_CH) |
(1 << SPI_SLAVE_RX_DMA_CH) | (1 << SPI_SLAVE_TX_DMA_CH));
 /* Enable PDMA channels */
- pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 *
SPI_MASTER_TX_DMA_CH));
14
SPI-PDMA Sample Code
int main (void)
{ ……
/* Configure SPI0 as a master, SPI clock rate 2 MHz,
clock idle low, 32-bit transaction, drive output on falling clock edge and latch input on rising edge. */
SPI_Open(SPI0, SPI_MASTER, SPI_MODE_0, 32, 2000000);

/* Enable the automatic hardware slave select function. Select the SPI0_SS0 pin and configure as low-
active. */
SPI_EnableAutoSS(SPI0, SPI_SS, SPI_SS_ACTIVE_LOW);

/* Configure SPI1 as a slave, clock idle low, 32-bit transaction, drive output on falling clock edge and
latch input on rising edge. */
/* Configure SPI1 as a low level active device. */
SPI_Open(SPI1, SPI_SLAVE, SPI_MODE_0, 32, NULL);

/* Enable FIFO mode */


SPI1->CNTRL |= SPI_CNTRL_FIFO_Msk;
15
……
SPI – PDMA Sample Code
• /* Source data initiation */

• for(u32DataCount = 0; u32DataCount < TEST_COUNT; u32DataCount++)

• {

• g_au32MasterToSlaveTestPattern[u32DataCount] = 0x55000000 | (u32DataCount + 1);

• g_au32SlaveToMasterTestPattern[u32DataCount] = 0xAA000000 | (u32DataCount + 1);

• }

• /* Enable PDMA channels */

• PDMA_Open((1 << SPI_MASTER_TX_DMA_CH) | (1 << SPI_MASTER_RX_DMA_CH) | (1 << SPI_SLAVE_RX_DMA_CH) | (1 <<


SPI_SLAVE_TX_DMA_CH));

• /* SPI master PDMA TX channel configuration */

• /* Set transfer width (32 bits) and transfer count */

• PDMA_SetTransferCnt(SPI_MASTER_TX_DMA_CH, PDMA_WIDTH_32, TEST_COUNT);

• /* Set source/destination address and attributes */

• PDMA_SetTransferAddr(SPI_MASTER_TX_DMA_CH, (uint32_t)g_au32MasterToSlaveTestPattern, PDMA_SAR_INC, (uint32_t)&SPI0->TX,


PDMA_DAR_FIX);

• /* Set request source. */

• PDMA_SetTransferMode(SPI_MASTER_TX_DMA_CH, PDMA_SPI0_TX, FALSE, 0);

• /* Set Memory-to-Peripheral mode */

• pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * SPI_MASTER_TX_DMA_CH));


16
• pdma->CSR = (pdma->CSR & (~PDMA_CSR_MODE_SEL_Msk)) | (0x2<<PDMA_CSR_MODE_SEL_Pos);
SPI – PDMA Sample Code
/* SPI master PDMA RX channel configuration */
/* Set transfer width (32 bits) and transfer count */
PDMA_SetTransferCnt(SPI_MASTER_RX_DMA_CH, PDMA_WIDTH_32, TEST_COUNT);

/* Set source/destination address and attributes */


PDMA_SetTransferAddr(SPI_MASTER_RX_DMA_CH, (uint32_t)&SPI0->RX, PDMA_SAR_FIX, (uint32_t)g_au32MasterRxBuffer, PDMA_DAR_INC);

/* Set request source. */


PDMA_SetTransferMode(SPI_MASTER_RX_DMA_CH, PDMA_SPI0_RX, FALSE, 0);

/* Set Peripheral-to-Memory mode */


pdma = (PDMA_T *)((uint32_t) PDMA0_BASE + (0x100 * SPI_MASTER_RX_DMA_CH));
pdma->CSR = (pdma->CSR & (~PDMA_CSR_MODE_SEL_Msk)) | (0x1<<PDMA_CSR_MODE_SEL_Pos);
/* Trigger PDMA */
PDMA_Trigger(SPI_SLAVE_RX_DMA_CH);
PDMA_Trigger(SPI_SLAVE_TX_DMA_CH);
PDMA_Trigger(SPI_MASTER_TX_DMA_CH);
PDMA_Trigger(SPI_MASTER_RX_DMA_CH);
/* Enable SPI slave DMA function */
SPI_TRIGGER_RX_PDMA(SPI1);
SPI_TRIGGER_TX_PDMA(SPI1);
/* Enable SPI master DMA function */ 17
SPI – PDMA Sample Code
/* Check Master RX DMA transfer done interrupt flag */
while((PDMA_GET_CH_INT_STS(SPI_MASTER_RX_DMA_CH) & PDMA_ISR_BLKD_IF_Msk)==0);

/* Clear the transfer done interrupt flag */


PDMA_CLR_CH_INT_FLAG(SPI_MASTER_RX_DMA_CH, PDMA_ISR_BLKD_IF_Msk);

/* Check Master TX DMA transfer done interrupt flag */


while((PDMA_GET_CH_INT_STS(SPI_MASTER_TX_DMA_CH) & PDMA_ISR_BLKD_IF_Msk)==0);

/* Clear the transfer done interrupt flag */


PDMA_CLR_CH_INT_FLAG(SPI_MASTER_TX_DMA_CH, PDMA_ISR_BLKD_IF_Msk);

/* Check Slave TX DMA transfer done interrupt flag */


while((PDMA_GET_CH_INT_STS(SPI_SLAVE_TX_DMA_CH) & PDMA_ISR_BLKD_IF_Msk)==0);

/* Clear the transfer done interrupt flag */


PDMA_CLR_CH_INT_FLAG(SPI_SLAVE_TX_DMA_CH, PDMA_ISR_BLKD_IF_Msk);

/* Check Slave RX DMA transfer done interrupt flag */


while((PDMA_GET_CH_INT_STS(SPI_SLAVE_RX_DMA_CH) & PDMA_ISR_BLKD_IF_Msk)==0);

/* Clear the transfer done interrupt flag */


PDMA_CLR_CH_INT_FLAG(SPI_SLAVE_RX_DMA_CH, PDMA_ISR_BLKD_IF_Msk);
i32Err = 0;

18
SPI – PDMA Sample Code
/* Check the transfer data */
for(u32DataCount=0; u32DataCount<TEST_COUNT; u32DataCount++)
{
if(g_au32MasterToSlaveTestPattern[u32DataCount] != g_au32SlaveRxBuffer[u32DataCount]){
i32Err = 1;
break;
}
if(g_au32SlaveToMasterTestPattern[u32DataCount] != g_au32MasterRxBuffer[u32DataCount]){
i32Err = 1;
break;
}
}

/* Disable PDMA peripheral clock */


CLK->AHBCLK &= ~CLK_AHBCLK_PDMA_EN_Msk;
if(i32Err)
{
printf("[FAIL]\n");
}
else
19
{
Thank you!

You might also like