This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software: Code Composer Studio
I use TMS570LS3137 ic. I want to use this chip sci communication with DMA as slave. The DMA source code is based on the link ( https://e2e.ti.com/support/microcontrollers/hercules/f/312/t/807027?tisearch=e2e-sitesearch&keymatch=tms570lc3137%2520sci%2520with%2520dma )
The system action
1. SCI communication action
- Rx(receive) always on and connected with Tx(transmit) line : So when the Tx data send, Rx data get.
- Tx(transmit) act is controlled by gpio. When bit is set, tx act.
2. Commucation setting(example)
- Sending data size : 20 bytes
- Preiod : 20ms
- After receiving the data, Chip send response same size data to master.
- Dma Test setting -
1. DMA setting receive and transmit - DMA_CH0 as Tx, DMA_CH1 as Rx (It follow the link source code)
2. Enable the interrupt (BTC) with halcogen, and Set Enable interrupt when receving. - dmaEnableInterrupt(DMA_CH1, BTC);
3. In the interrupt, there are two actions,
(1) Data correct - when the dma is started with sci communication start
1) dmadisable
2) DmaReset : dmaREG->GCTRL = 1U;
3) Resetting DMA Tx
4) SCI Tx on
5) somedelay
6) DMAenable
7) wait tx finish : while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);
8) dmaDisable
9) some delay - because communication is more slower than MCU
10) SCI Tx off
11) DmaReset : dmaREG->GCTRL = 1U;
12) Setting DMA Rx
13) DMA enable
(2) Data fail - when the dma is started while sci communication
1) DMAdisable
2) wait some delay
3) DMAReset : dmaREG->GCTRL = 1U; (Because i don't know where the dma point is located.)
4) Setting DMA Rx
5) DMAenable
Then, I just want to dma with No reset and Re setting. (In fail case, there is no way to act without DMA reset, but in tx action - I think it is possible action without DMA Reset)
I test sci act without DMA Reset in "Data correct" as followes
(1) Data correct - when the dma is started with sci communication start
1) dmadisable
2) SCI Rx DMA interrupt diasble
3) SCI Tx on
4) some delay
5) DMAenable
6) wait tx finish : while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);
7) dmaDisable
8) some delay - because communication is more slower than MCU
9) SCI Tx off
11) SCI Rx DMA interrupt diasble
12) DMA enable
Then, firmware is stopped in 5) - while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);
I think Rx dma is act when TX dma transmittion. Would you guide me how i can solve this problem?
Hello Minwoo,
I am sorry I am not very clear about your settings. Can you please upload your CCS project?
Hello QJ Wang,
I cannot upload CCS project because there the other functions are used in our company. So, I just upload about DMA actions related in previous question.
Actions as followes,
1. In main setting "sci_receive_with_dma_init()" funcion is used (in notification.c)
2. dmaBTCAInterrupt is occurred when sci communication finish. (in sys_dma.c)
3. dmaGroupANotification is started <- in this function include the action in previous quesiton(in notification.c)
- here are two case actions.
(1) sci start in correct timing (in "if" state)
(2) sci start in incorrect timing (in "else" state)
Regards,
Minwoo
Hello QJ Wang,
I test more SCI with DMA.
First, I set DMA as followes, (just run receive)
uint32 sciTxData, sciRxData;
int i;
g_dmaCTRL g_dmaCTRLPKT1, g_dmaCTRLPKT2;
/*Initialize SCI*/
sciInit();
/*Assign DMA request SCI transmit to Channel 0*/
dmaReqAssign(DMA_CH0, 31);
/*Assign DMA request SCI receive to Channel 1*/
dmaReqAssign(DMA_CH1, 30);
sciTxData = ((uint32_t)(&(sciREG->TD)) + 3);
sciRxData = ((uint32_t)(&(sciREG->RD)) + 3);
/*Configure control packet for Channel 0*/
g_dmaCTRLPKT1.SADD = (uint32_t)TX_DATA; /* source address */
g_dmaCTRLPKT1.DADD = sciTxData; /* destination address */
g_dmaCTRLPKT1.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT1.FRCNT = PROTOCOL_SIZE; /* frame count */
g_dmaCTRLPKT1.ELCNT = 1; /* element count */
g_dmaCTRLPKT1.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT1.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT1.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT1.FRSOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT1.PORTASGN = 4;
g_dmaCTRLPKT1.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT1.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT1.TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_ON; /* autoinit */
/*Configure control packet for Channel 1*/
g_dmaCTRLPKT2.SADD = sciRxData; /* source address */
g_dmaCTRLPKT2.DADD = (uint32_t)RX_DATA; /* destination addr ss */
g_dmaCTRLPKT2.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT2.FRCNT = PROTOCOL_SIZE; /* frame count */
g_dmaCTRLPKT2.ELCNT = 1; /* element count */
g_dmaCTRLPKT2.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT2.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT2.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT2.FRSOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT2.PORTASGN = 4;
g_dmaCTRLPKT2.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT2.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT2.TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT2.ADDMODERD = ADDR_FIXED; /* address mode read */
g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1; /* address mode write */
g_dmaCTRLPKT2.AUTOINIT = AUTOINIT_ON; /* autoinit */
/*Set control packet for channel 0 and 1*/
dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT1);
dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT2);
/*Set dma channel 0 and 1 to trigger on hardware request*/
dmaSetChEnable(DMA_CH0, DMA_HW);
dmaSetChEnable(DMA_CH1, DMA_HW);
/*Enable SCI Receive DMA Request*/
sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
dmaEnableInterrupt(DMA_CH1, BTC);
Next in the interrupt i do transfer like this way,
/*tansfer enable*/
dmaDisable();
gioSetBit(gioPORTB, 5u, 1u);
sciREG->CLEARINT = 0xffffffff;
sciREG->SETINT = SCI_SET_TX_DMA;
/*delay berfore transmit*/
int k = 0;
for(k =0; k < 1000; k++)
{
__nop();
}
dmaEnable();
while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);
dmaDisable();
/*Delay to send last byte*/
for(k =0; k < 1000; k++)
{
__nop();
}
gioSetBit(gioPORTB, 5u, 0u);
sciREG->CLEARINT = 0xffffffff;
sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
dmaEnable();
In this test, it can read alright data(receive is well). but, transmit data is not act. I don't know why transmit not act.
Receive DMA not stopped when sciREG->SETINT is cleared?
-----------------------------------------
I confirm that
sciREG->CLEARINT = 0xffffffff;
sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
is changed
dmaReset(); -> dma reset
sci_communication_with_dma_init(); -> dma re setting with first step
then act well
Would you explain why transmit DMA not act before initialize?
Regards,
Minwoo
Hello Minwoo,
sciREG->CLEARINT = 0xffffffff;
sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
The first instruction clears all the enabled interrupts and RX DMA/TX DMA bits. the 2nd instruction sets the RX DMA only. TX DMA is disabled.
Hello, QJ Wang
Sci with DMA is act as slave.
The code is act in DMA Interrupt function. (I think design of our board is connect Rx/Tx line and Rx always act.)
The code action concept like this,
1. DMAInterrupt - sci receive finish.
2. Rx disable/Tx enable
3. Send data
4. Tx disable/ Rx enable
5. Wait next data(repeat 1~5)
dmaDisable();
/*tansfer enable*/
gioSetBit(gioPORTB, 5u, 1u);
sciREG->CLEARINT = 0xffffffff;
sciREG->SETINT = SCI_SET_TX_DMA;
/*delay berfore transmit*/
int k = 0;
for(k =0; k < 1000; k++)
{
__nop();
}
dmaEnable();
while(dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE);
/*block to send next block frame data*/
dmaDisable();
/*Delay to send last byte*/
for(k =0; k < 1000; k++)
{
__nop();
}
/*Rx enable after Transmit*/
gioSetBit(gioPORTB, 5u, 0u);
sciREG->CLEARINT = 0xffffffff;
sciREG->SETINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
dmaEnable();
The green line is enable Tx/ disable Rx, The red line is enable Rx/ disable Tx.
Then, Rx act well, Tx is not act.
I read the data sheet as SCI_SET_RX_DMA -> Rx DMA request, and SCI_SET_TX_DMA -> Tx DMA request.
My questions are,
1. Could I know why this problem is occurred?
2. Is it impossible DMA trigger(DMA start and stop timing) by SCI_SET_RX_DMA/SCI_SET_TX_DMA?
Regards,
Minwoo
Hello Minwoo,
Please refer to this app note for using SCI DMA to TX/RX data: