Hallo, Ich benutze das XMC4500 Relax Kit inkl. XMC-Lib und versuche seit Tagen folgendes umzusetzen: 4 UART TX Outputs, welche mit Hilfe von DMA jeweils ein eigenes uint8_t Array parallel, also gleichzeitig senden. Nach Vertiefen ins Datenblatt, sowie in die USIC und DMA Kapitel, kam ich zu folgendem Ansatz: U0C0 für TX1 Output, U0C1 für TX2 Output, U1C0 für TX3 Output, U1C1 für TX4 Output Soweit so gut. Gleichzeitiges Sender der Arraybuffer unter Verwendung von nur TX1 und TX3 funktioniert wunderbar, ebenfalls von TX2 und TX4. Bei Verwendung von allen 4 TX, bzw. TX1 & TX2 oder TX3 & TX4, gibt es einen "Streit" zwischen den Channels des betreffenden USIC Moduls. Meine Frage lautet nun: Kann das überhaupt so funktionieren wie ich es versuche, oder können beide Channels eines USIC Moduls nicht gleichzeitig? Code reiche ich gerne bei Bedarf nach. Vielen Dank, Felix
Alle 4 Arrays sind mit gleichen Daten gefüllt. Mit einer durchgehenden Zahlenfolge von 0 bis 99. Mein Code:
1 | #define BUFFER_LENGTH 100
|
2 | |
3 | volatile uint8_t DMXBufferU0C0[BUFFER_LENGTH]; |
4 | volatile uint8_t DMXBufferU0C1[BUFFER_LENGTH]; |
5 | volatile uint8_t DMXBufferU1C0[BUFFER_LENGTH]; |
6 | volatile uint8_t DMXBufferU1C1[BUFFER_LENGTH]; |
7 | |
8 | static XMC_UART_CH_CONFIG_t uart_config = |
9 | {
|
10 | .baudrate = 250000U, |
11 | .oversampling = 16U, |
12 | .data_bits = 8U, |
13 | .frame_length = 8U, |
14 | .stop_bits = 2U, |
15 | .parity_mode = XMC_USIC_CH_PARITY_MODE_NONE |
16 | } ; |
17 | |
18 | static XMC_DMA_CH_CONFIG_t U0C0_DMAChConfig = |
19 | {
|
20 | .dst_addr = (uint32_t)&(XMC_UART0_CH0->TBUF[0]), |
21 | .src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8, |
22 | .dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8, |
23 | .src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, |
24 | .dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE, |
25 | .src_burst_length = XMC_DMA_CH_BURST_LENGTH_8, |
26 | .dst_burst_length = XMC_DMA_CH_BURST_LENGTH_1, |
27 | .transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_M2P_DMA, |
28 | .transfer_type = XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK, |
29 | .dst_handshaking = XMC_DMA_CH_DST_HANDSHAKING_HARDWARE, |
30 | .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC0_SR0_0, |
31 | .enable_interrupt = true |
32 | };
|
33 | |
34 | static XMC_DMA_CH_CONFIG_t U0C1_DMAChConfig = |
35 | {
|
36 | .dst_addr = (uint32_t)&(XMC_UART0_CH1->TBUF[0]), |
37 | .src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8, |
38 | .dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8, |
39 | .src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, |
40 | .dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE, |
41 | .src_burst_length = XMC_DMA_CH_BURST_LENGTH_8, |
42 | .dst_burst_length = XMC_DMA_CH_BURST_LENGTH_1, |
43 | .transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_M2P_DMA, |
44 | .transfer_type = XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK, |
45 | .dst_handshaking = XMC_DMA_CH_DST_HANDSHAKING_HARDWARE, |
46 | .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC0_SR0_1, |
47 | .enable_interrupt = true |
48 | };
|
49 | |
50 | static XMC_DMA_CH_CONFIG_t U1C0_DMAChConfig = |
51 | {
|
52 | .dst_addr = (uint32_t)&(XMC_UART1_CH0->TBUF[0]), |
53 | .src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8, |
54 | .dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8, |
55 | .src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, |
56 | .dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE, |
57 | .src_burst_length = XMC_DMA_CH_BURST_LENGTH_8, |
58 | .dst_burst_length = XMC_DMA_CH_BURST_LENGTH_1, |
59 | .transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_M2P_DMA, |
60 | .transfer_type = XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK, |
61 | .dst_handshaking = XMC_DMA_CH_DST_HANDSHAKING_HARDWARE, |
62 | .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR0_4, |
63 | .enable_interrupt = true |
64 | };
|
65 | |
66 | static XMC_DMA_CH_CONFIG_t U1C1_DMAChConfig = |
67 | {
|
68 | .dst_addr = (uint32_t)&(XMC_UART1_CH1->TBUF[0]), |
69 | .src_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8, |
70 | .dst_transfer_width = XMC_DMA_CH_TRANSFER_WIDTH_8, |
71 | .src_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_INCREMENT, |
72 | .dst_address_count_mode = XMC_DMA_CH_ADDRESS_COUNT_MODE_NO_CHANGE, |
73 | .src_burst_length = XMC_DMA_CH_BURST_LENGTH_8, |
74 | .dst_burst_length = XMC_DMA_CH_BURST_LENGTH_1, |
75 | .transfer_flow = XMC_DMA_CH_TRANSFER_FLOW_M2P_DMA, |
76 | .transfer_type = XMC_DMA_CH_TRANSFER_TYPE_SINGLE_BLOCK, |
77 | .dst_handshaking = XMC_DMA_CH_DST_HANDSHAKING_HARDWARE, |
78 | .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR0_5, |
79 | .enable_interrupt = true |
80 | };
|
81 | |
82 | void GPDMA0_0_IRQHandler(void) |
83 | {
|
84 | const uint8_t U0C0DMAChannel = 0; |
85 | const uint8_t U0C1DMAChannel = 1; |
86 | const uint8_t U1C0DMAChannel = 2; |
87 | const uint8_t U1C1DMAChannel = 3; |
88 | |
89 | // Check DMA0.0 transfer complete
|
90 | if (XMC_DMA_CH_GetEventStatus(XMC_DMA0, U0C0DMAChannel) == XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE) |
91 | {
|
92 | XMC_DMA_CH_ClearEventStatus(XMC_DMA0, U0C0DMAChannel, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE); |
93 | printf("U0C0 DMA Done!\n"); |
94 | }
|
95 | |
96 | // Check DMA0.1 transfer complete
|
97 | if (XMC_DMA_CH_GetEventStatus(XMC_DMA0, U0C1DMAChannel) == XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE) |
98 | {
|
99 | XMC_DMA_CH_ClearEventStatus(XMC_DMA0, U0C1DMAChannel, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE); |
100 | printf("U0C1 DMA Done!\n"); |
101 | }
|
102 | |
103 | // Check DMA0.2 transfer complete
|
104 | if (XMC_DMA_CH_GetEventStatus(XMC_DMA0, U1C0DMAChannel) == XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE) |
105 | {
|
106 | XMC_DMA_CH_ClearEventStatus(XMC_DMA0, U1C0DMAChannel, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE); |
107 | printf("U1C0 DMA Done!\n"); |
108 | }
|
109 | |
110 | // Check DMA0.3 transfer complete
|
111 | if (XMC_DMA_CH_GetEventStatus(XMC_DMA0, U1C1DMAChannel) == XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE) |
112 | {
|
113 | XMC_DMA_CH_ClearEventStatus(XMC_DMA0, U1C1DMAChannel, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE); |
114 | printf("U1C1 DMA Done!\n"); |
115 | }
|
116 | }
|
117 | |
118 | void DMATEST(void) |
119 | {
|
120 | uint8_t n = 0; |
121 | |
122 | for (n = 0; n < BUFFER_LENGTH; n++) |
123 | {
|
124 | DMXBufferU0C0[n] = n; |
125 | DMXBufferU0C1[n] = n; |
126 | DMXBufferU1C0[n] = n; |
127 | DMXBufferU1C1[n] = n; |
128 | }
|
129 | |
130 | // Init General Purpose DMA 0
|
131 | XMC_DMA_Init(XMC_DMA0); |
132 | |
133 | //////////////////////////////////////////////////////////////////////
|
134 | initUARTDMA(DMXBufferU0C0, XMC_USIC0_CH0, 0, &U0C0_DMAChConfig, P1_5); |
135 | initUARTDMA(DMXBufferU0C1, XMC_USIC0_CH1, 1, &U0C1_DMAChConfig, P2_5); |
136 | initUARTDMA(DMXBufferU1C0, XMC_USIC1_CH0, 2, &U1C0_DMAChConfig, P0_5); |
137 | initUARTDMA(DMXBufferU1C1, XMC_USIC1_CH1, 3, &U1C1_DMAChConfig, P0_1); |
138 | //////////////////////////////////////////////////////////////////////
|
139 | }
|
140 | |
141 | void initUARTDMA(uint8_t *Buffer, XMC_USIC_CH_t *USICChannel, uint8_t DMAChannel, XMC_DMA_CH_CONFIG_t *DMAChannelConfig, const XMC_GPIO_PORT_t *Port, const uint8_t Pin) |
142 | {
|
143 | // Init GPDMA0 using specified DMA config
|
144 | XMC_DMA_CH_Init(XMC_DMA0, DMAChannel, DMAChannelConfig); |
145 | |
146 | // Enable GPDMA channel event BLOCK_TRANSFER_COMPLETE
|
147 | XMC_DMA_CH_EnableEvent(XMC_DMA0, DMAChannel, XMC_DMA_CH_EVENT_BLOCK_TRANSFER_COMPLETE); |
148 | |
149 | // Route interrupt vector to the handler routine and enable DMA event handling
|
150 | BSP_IntVectSet(GPDMA0_0_IRQn, GPDMA0_0_IRQHandler); |
151 | NVIC_SetPriority(GPDMA0_0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 63, 0)); |
152 | NVIC_EnableIRQ(GPDMA0_0_IRQn); |
153 | |
154 | // Init UART Channel
|
155 | XMC_UART_CH_Init(USICChannel, &uart_config); |
156 | |
157 | // Enable UART Event
|
158 | XMC_UART_CH_EnableEvent(USICChannel, XMC_UART_CH_EVENT_TRANSMIT_BUFFER); |
159 | XMC_USIC_CH_SetInterruptNodePointer(USICChannel, XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER, 0); |
160 | |
161 | // Start UART Channel
|
162 | XMC_UART_CH_Start(USICChannel); |
163 | |
164 | // Make DMA ready
|
165 | XMC_USIC_CH_TriggerServiceRequest(USICChannel, 0); |
166 | |
167 | // Configure TX
|
168 | XMC_GPIO_SetMode(Port, Pin, XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2); |
169 | XMC_DMA_CH_SetBlockSize(XMC_DMA0, DMAChannel, BUFFER_LENGTH); |
170 | XMC_DMA_CH_SetSourceAddress(XMC_DMA0, DMAChannel, (uint32_t)Buffer); |
171 | |
172 | // Enable DMA Channel
|
173 | XMC_DMA_CH_Enable(XMC_DMA0, DMAChannel); |
174 | }
|
Die Lösung lag darin, dass in so einem Fall für die Channels unterschiedliche Service Request Numbers verwendet werden müssen: Funktioniert falsch: ====================
1 | U0C0 struct: .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC0_SR0_0 |
2 | U0C1 struct: .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC0_SR0_1 |
3 | U1C0 struct; .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR0_4 |
4 | U1C0 struct; .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR0_5 |
Funktioniert richtig: =====================
1 | U0C0 struct: .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC0_SR0_0 |
2 | U0C1 struct: .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC0_SR1_2 |
3 | U1C0 struct; .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR0_1 |
4 | U1C0 struct; .dst_peripheral_request = DMA0_PERIPHERAL_REQUEST_USIC1_SR1_3 |
Analog dazu müssen auch die XMC_USIC_CH_SetInterruptNodePointer() und XMC_USIC_CH_TriggerServiceRequest() entsprechend mit SR Number 0 oder 1 aufgerufen werden.
Hey, I am working with a dog motor. I wanted to send a 8bytes data via uart. could you help me with it ?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.