HI DAVID
I am trying to configure UART-DMA yet I cannot do so far.
Could you help me to resolve my problem? I am not sure concerning to interruption value.
In intention to help for better understanding of my problem I divide this message into three sesions.
(A) my Check list.
(B) References
(C) My code.
Thanks for your help in advance.
(A)
1.- UART3 configuration to 9600 bps using TTYD
Uart_serie3 = fopen("ttyd:", BSP_DEFAULT_IO_OPEN_MODE);
if (Uart_serie3==NULL)
{
printf("ERROR ");
}
else{
write(Uart_serie3,(pointer)"Ready 3",7);
fflush(Uart_serie3);
}
2.- Interrupt-function asociation.
_int_install_isr(32, dam0_isr,buffer_TUART3.buffer);
interrupcion 32 es del DMA
I tried using following configuration but does not work
_int_install_isr(INT_UART3_RX_TX, dam0_isr,buffer_TUART3.buffer);
3.- I made the TCD configuration followin intructions on AN2998-1.pdf page 10 table 4.20, as well as two references from towergeeks
4.- To activate the configuration I did the following.
configure_TCD();
Enable_channel_0_1(); transmission reception channels ON
DMA_on(1); CHANNEL 1 ON
(B) REFERENCES
https://community.freescale.com/thread/117204
https://community.freescale.com/message/106758#106758
AN2998-1.pdf PAGE 10 TABLE 4.20 transfer control descriptors
Document Number: K60P100M100SF2RM Rev. 6, Nov 2011
(C)
#include "main.h"
//BUFFERS for Tx and Rx in UART3 to be used by DMA
struct _uart_buf
{
int index;
char buffer[64];
} buffer_RUART3,buffer_TUART3;
//pointer to UART 5 and 3
MQX_FILE_PTR Uart_serie5=NULL;
MQX_FILE_PTR Uart_serie3=NULL;
/* function for UART-DMA interruption*/
void dam0_isr(pointer user_DMAisr_ptr)
{
static unsigned char cnt=0;
DMA_INT = 0x1; // clear dma int flag
cnt++;
memset(buffer_TUART3.buffer,cnt,64);
DMA_TCD0_SADDR = (unsigned long)&buffer_TUART3.buffer[0];
DMA_ERQ |= (1 << 0);//
DMA_TCD1_DADDR = (unsigned long)&buffer_RUART3.buffer[0];
DMA_ERQ |= (1 << 1);//
}
/* turn on channels DMAmux 0 and 1 Tx and Rx for UART3*/
void Enable_channel_0_1(void)
{
/* Configure DMAMux for Channel 0 */
DMAMUX_CHCFG0 = 9; //receive UART3_TX
DMAMUX_CHCFG0 |= DMAMUX_CHCFG_ENBL_MASK;//Enable DMA channel
DMA_ERQ |= (1 << 0);// inicia START
/* Configure DMAMux for Channel 1 */
DMAMUX_CHCFG1 = 8; // transmitte UART3_TX
DMAMUX_CHCFG1 |= DMAMUX_CHCFG_ENBL_MASK;//Enable DMA channel
DMA_ERQ |= (1 << 1);// inicia START
}
/* TCD configuration based on AN2998-1.pdf page 10 table 4.20 transfer control descriptors
* and the Document Number: K60P100M100SF2RM Rev. 6, Nov 2011 */
void configure_TCD (void)
{
DMAMUX_CHCFG0 = 0; //channel 0 turn off
/* Configure DMA Channel 0 TCD */
DMA_TCD0_SADDR = ((uint_32)&UART3_D);/* data UART3_D, 0x4006D007 UART3 address*/
DMA_TCD0_ATTR = (DMA_ATTR_SMOD(0x0) /* Source Modulo, feature disabled */
| DMA_ATTR_SSIZE(0x0) /* Source Size = 0x0 -> 8-bit transfers */
| DMA_ATTR_DMOD(0x0)); /* Destination Modulo, feature disabled */
// | DMA_ATTR_DSIZE=(0x0)); /* Destination Size = 0x2 -> 32-bit transfers */
DMA_TCD0_SOFF = 0; /* Source addr offset = 0x0, el incremento lo dejo a cero porque la direccion es fija */
DMA_TCD0_NBYTES_MLNO = 0x4; /* Transfer 4 bytes per channel activation */
DMA_TCD0_SLAST = DMA_SLAST(0x0); /* Do not adjust SADDR upon channel completion */
DMA_TCD0_DADDR = ((uint_32)&buffer_RUART3.buffer[0]); /* Destination Address = BUFFER DE RECEPCION */
DMA_TCD1_CITER_ELINKNO = 0;
DMA_TCD1_CITER_ELINKNO = 0x1; /* Current Iter Count -> 1 "NBYTES" transfer */
DMA_TCD1_DOFF = 0x1; /* Destination addr offset = 0x1, AQUI SI INCREMENTO PARA QUE LO ALMACENE EN EL BUFFER DE RECEPCION */
DMA_TCD1_DLASTSGA = 0x0; /* Do not adjust DADDR upon channel completion */
DMA_TCD1_BITER_ELINKNO = 0;
DMA_TCD1_BITER_ELINKNO = 0x1; /* TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) */
DMA_TCD1_CSR = 0;
DMA_TCD1_CSR |= DMA_CSR_INTMAJOR_MASK; /* Enable an interrupt when major iteration count completes.*/
DMA_TCD1_CSR |= DMA_CSR_DREQ_MASK; /* If this bit is set when the channel completes a major loop, the eDMA clears the
corresponding DMAERQ, disabling the transfer request.*/
DMA_TCD1_CSR |= 1 << 255; // ACTIVA EL START
NVICISER0 |= 1 << 0 ;// enable interrupt NVICISERn = 1 << m, where n = 0/32, m = 0% 32 dma interrupt 32
NVICICPR0 |= 1 << 0;
DMAMUX_CHCFG1 = 0;
/* Configure DMA Channel 1 TCD */
DMA_TCD1_SADDR = ((uint_32)&buffer_TUART3.buffer[0]);/* Source Addr = address of command var */
DMA_TCD1_ATTR = (DMA_ATTR_SMOD(0x0) /* Source Modulo, feature disabled */
| DMA_ATTR_SSIZE(0x0) /* Source Size = 0x0 -> 8-bit transfers */
| DMA_ATTR_DMOD(0x0)); /* Destination Modulo, feature disabled */
// | DMA_ATTR_DSIZE=(0x2)); /* Destination Size = 0x2 -> 32-bit transfers */
DMA_TCD1_SOFF = 1; /* Source addr offset = 0x1, increment */
DMA_TCD1_NBYTES_MLNO = 0x4; /* Transfer 4 bytes per channel activation */
DMA_TCD1_SLAST = 0x0; /* Do not adjust SADDR upon channel completion */
DMA_TCD1_DADDR = ((uint_32)&UART3_D);/* Dest Addr = UART3_D Command Word Register 0x4006D007*/
DMA_TCD1_CITER_ELINKNO = 0;
DMA_TCD1_CITER_ELINKNO = 0x1; /* Current Iter Count -> 1 "NBYTES" transfer */
DMA_TCD1_DOFF = 0x1; /* Destination addr offset = 0x1, increment */
DMA_TCD1_DLASTSGA = 0x0; /* Do not adjust DADDR upon channel completion */
DMA_TCD1_BITER_ELINKNO = 0;
DMA_TCD1_BITER_ELINKNO = 0x1; /* TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) */
DMA_TCD1_CSR = 0;
DMA_TCD1_CSR |= DMA_CSR_INTMAJOR_MASK;
DMA_TCD1_CSR |= DMA_CSR_DREQ_MASK;
DMA_TCD1_CSR |= 1 << 255;
NVICISER0 |= 1 << 0 ;// enable interrupt NVICISERn = 1 << m, where n = 0/32, m = 0% 32 dma interrupt 32
NVICICPR0 |= 1 << 0;
}
void DMA_off(int DMA_CHn)
{
DMA_ERQ &= ~(1 << DMA_CHn); /* stop; The ERQ register provides a bit map for the 16 implemented channels to enable the request signal for each channel. */
}
void DMA_on(int DMA_CHn)
{
DMA_ERQ |= (1 << DMA_CHn); /* start The ERQ register provides a bit map for the 16 implemented channels to enable the request signal for each channel. */
}
/* Parametros tomados de recomendaciones de twr geeks
* https://community.freescale.com/thread/117204
* https://community.freescale.com/message/106758#106758 */
void UART_config()
{
/* no configurar la UART en modo interrupcion !!!! */
UART3_C2 &= ~(UART_C2_TE_MASK | UART_C2_RE_MASK);
UART3_C5 &= ~(UART_C5_TDMAS_MASK | UART_C5_RDMAS_MASK);
UART3_C5 |= UART_C5_TDMAS_MASK;
UART3_C5 |= UART_C5_RDMAS_MASK;
UART3_C2 = (1 << 7) | (1 << 5) | (1 << 2) ;// allow income, interrupt, it allows the receiver to
UART3_C5 = (1 << 7) | (1 << 5) ;// allow the recipient, hair interrupt generates a DMA request
UART3_C1 |= 1 << 7 ;// use loopback mode
UART3_C2 |= UART_C2_TE_MASK; //| UART_C2_RE_MASK);
SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;
SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;
// Set FIFO water marks (not used in default 'legacy' port configuration)
UART3_TWFIFO = UART_TWFIFO_TXWATER(0);
UART3_RWFIFO = UART_RWFIFO_RXWATER(1);
}
void DMA_config()
{
configure_TCD();
Enable_channel_0_1();
}
TASK_TEMPLATE_STRUCT MQX_template_list[] =
{
/* Task number, Entry point, Stack, Pri, String, Auto? */
{MAIN_TASK, Main_task, 2000, 9, "main", MQX_AUTO_START_TASK},
{0, 0, 0, 0, 0, 0, }
};
/*TASK*-----------------------------------------------------------------
*
* Function Name : Main_task
* Comments :
* This task initializes MFS and starts SHELL.
*
*END------------------------------------------------------------------*/
void Main_task(uint_32 initial_data)
{
short int i;
//MY_ISR_STRUCT_PTR isr_ptr=NULL;
rtcs_init();
Uart_serie3 = fopen("ttyd:", BSP_DEFAULT_IO_OPEN_MODE);
if (Uart_serie3==NULL)
{
printf("ERROR no se pudo abrir el dispositivo serial 3");
}
else{
write(Uart_serie3,(pointer)"Ready 3",7);
fflush(Uart_serie3);
}
Uart_serie5 = fopen("ittyf:", BSP_DEFAULT_IO_OPEN_MODE);
if (Uart_serie5==NULL)
{
printf("ERROR no se pudo abrir el dispositivo serial 5");
}
else{
write(Uart_serie5,(pointer)"Ready 5",7);
fflush(Uart_serie5);
}
_int_install_isr(32, dam0_isr,buffer_TUART3.buffer);
UART_config();
DMA_config();
DMA_on(1);
for (i = 0; i <64; i ++)
{
buffer_TUART3.buffer[i] = 'A';
}
buffer_TUART3.index = 1;
buffer_RUART3.index = 0;
UART3_C2 |= 1 << 3; /* Activa la recepcion de mensajes */
fflush(Uart_serie3);
for (;;)
{
_time_delay_ticks(1000);
for (i = 0; i <64; i ++)
{
write(Uart_serie3,(pointer)&buffer_TUART3.buffer[i],1);
}
write(Uart_serie3,"\r\n",2);
}
fflush(Uart_serie3);
close(Uart_serie3);
fflush(Uart_serie5);
close(Uart_serie5);
DMA_off(0);
DMA_off(1);
_mqx_exit(0);
}