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.

MSP432P401R: SPI and DMA

Part Number: MSP432P401R
Other Parts Discussed in Thread: DAC161S055

Hello,

I want to transfer some data from RAM to one of the SPI interfaces, which is connected to a DAC.

The DAC expects 24 bits without de-asserting the CS line in between. Currently I generate the CS line manually with a GPIO pin.

To speed up the whole process, I want to use a DMA  transfer. I have worked on the given SPI and DMA template but everytime I am getting nothing for running this exsmple. I expect that DMA should be triggered by SPI for every one byte and data should be shifted from one memory location to mentioned destination memoey location.

My question (before starting to dig into the DMA documentation in more depth):

- What is reason that I am getting nothing for output (I think spi is unable to trigger the DMA)  ??

-As DAC does not have any memory resister , what can be destination memory address ?? (As data is always being stored in MSP432 but I am not understanding how to find that destination memory address)

Any hint and help is very welcome!

  • What is "nothing"? No SPI activity? DAC output doesn't change?

    What DAC? What Example?

    For a Tx, the DMA target should be the USCI transmit buffer (e.g. &UCB0TXBUF) and the trigger the interrupt flag (e.g. UCTXIFG). Keep in mind that the DMA will finish before the transaction is done.

    Unsolicited: For short (3-byte) transactions over a fast SPI (most of TI's SPI DACs are pretty fast) DMA will overall slow things down.
  • Hi Bruce,

    I refered following example in my above asked question: (''dma_eusci_spi_loopback '' ). I tested this example just to make sure to see that either DMA is working properly and how it is transferring data from one memory location to other. By using break point, I checked the destination register (which is mentioned as buffer in example) but its all entries remained zero always. What I expect that this destination memory location should get data from source memory location(mentioned as a buffer too), That's why I assumed that may be DMA is not being triggered by SPI.

    In my task, I want to speed up SPI (i think it help me to save some time up to 10 usec).
    For transmission, I have trasnmitter buffer which has three bytes but my problem is about destination memory location. I got suggestion here by one TI expert that I should store SPI transmission buffer values in one variable and use it as a destination memory address but this will be the same buffer which is a tranmitter buffer (I have DAC161S055 and it needs one byte command and 2-bytes data and I have divided them in the form of three single bytes and transferring them with SPI protocol in the form of one single byte in one turn . I have attached code below too) but I think DAC output is detination memory location and I do not know where output is being storedt.

    Note: Just to see code behaviour, I defined one buffer ''test'' as a destination memory location to see either DMA is transferring something but this buffer entries remain zero also always.


    SpiTxBuffer[0] = 0x08;
    SpiTxBuffer[1] = *((uint8_t*)(&DacValueDigits) + 1);
    SpiTxBuffer[2] = *((uint8_t*)(&DacValueDigits));


    MAP_DMA_setChannelControl(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
    UDMA_MODE_BASIC, SpiTxBuffer,
    (void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),test
    1);
    MAP_DMA_setChannelControl(DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer(DMA_CH1_EUSCIB0RX0 | UDMA_PRI_SELECT,
    UDMA_MODE_BASIC,
    test,
    1);
  • Did you install the jumper wires as described (graphically) at the top of the program? Those form a physical loopback from USCI B0 to B1

    As Chris explained in the other thread, you can't set any registers in the DAC device. All you can do is send data (with an appropriate command) and ask the DAC to store something. How this is done is described in the DAC data sheet.

    To send the data you (or the DMA) store into the SPI transmit buffer (MAP_SPI_getTransmitBufferAddressForDMA()) and the SPI sends the data to the DAC for you.
  • Hi Bruce,

    Yes I did that jumper connection and I tried again today and this example is working fine now.
    I want to extend it for my project and I habe only one SPi channel. Is it necessary to use two DMA channels for one SPI ??

    Because according to driver library, there should be one channel for one complete transfer.
  • If you Never plan to receive anything from the DAC, you don't need to use a DMA channel on the receive side. (Indeed, you don't even need to connect the SOMI pin.) Bytes will still be stored in the RXBUF, but they'll be ignored.
  • I want to move step by step.One more question about connection now, do i need to make physical connection for my project ?  I think no because i just need master transmission and reception.

    Can you please draw or just give me hint if I want to use just one channel of DMA.

    Many thanks. Because i am beginner in embedded system and may be ask very basic questions too.

  • You mentioned at the beginning that you had it working without the DMA. The DMA has no effect on the wiring, so I don't think you need to change anything.
  • Hi Bruce,

    I have one more question. Before, I was transferring data through SPI manually. How much, I have understood DMA working, now I do not need that manullay tranfer. DMA will do all this transfer ,is it ??

    then why I need interrupr flag of SPI (UCTXIFG ) ?? Please have a look on my code too :


    /* Setup the TX transfer characteristics & buffers */
    MAP_DMA_setChannelControl(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);
    MAP_DMA_setChannelTransfer(DMA_CH0_EUSCIB0TX0 | UDMA_PRI_SELECT,
    UDMA_MODE_AUTO, &SpiTxBuffer,
    (void *) MAP_SPI_getTransmitBufferAddressForDMA(EUSCI_B0_BASE),
    8);

    /* Assigning/Enabling Interrupts */
    MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
    MAP_DMA_enableInterrupt(INT_DMA_INT1);


    SpiTxBuffer[0] = 0x08;
    SpiTxBuffer[1] = *((uint8_t*)(&DacValueDigits) + 1);
    SpiTxBuffer[2] = *((uint8_t*)(&DacValueDigits));
    //SpiTxBufferSize = sizeof(SpiTxBuffer)/sizeof(SpiTxBuffer[0]);
    //SpiTxBufferPos = 0;

    MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, GPIO_PIN7);

    MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P6, GPIO_PIN0);
    //SPI_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT);

    MAP_DMA_enableChannel(0);

    void DMA_INT1_IRQHandler(void)
    {

    isrCounter++;

    MAP_DMA_clearInterruptFlag(0);

    /* Disable the interrupt to allow execution */
    MAP_Interrupt_disableInterrupt(INT_DMA_INT1);
    MAP_DMA_disableInterrupt(INT_DMA_INT1);
    }
  • I'm not sure I understand the question. You don't want this:

    > //SPI_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT);

    since the UCTXIFG is what is driving the DMA, so you don't want to mess with it.
  • HI bruce,

    I just want to ask you that when DMA will operate with SPI then DMA will transfer the all data in specified location but it will be triggered by SPI every time. (is it the real concept of DMA too ??)

    As before, I was using SPI interrrupt to transfer 3 bytes of data (MCU to DAC). My idea is that then I do not need to enable the interrupt of SPI anymore because now DMA is doing all transfer for me. (Please check the follwing code which is defined for above mentioned interrupt )

    void EUSCIB0_IRQHandler(void)
    {
    if(SPI_getInterruptStatus(EUSCI_B0_BASE,EUSCI_B_SPI_TRANSMIT_INTERRUPT))
    {
    if( SpiTxBufferSize > 0 )
    {
    //SPI_clearInterruptFlag(EUSCI_B0_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT);
    SPI_transmitData(EUSCI_B0_BASE,SpiTxBuffer[SpiTxBufferPos]);
    SpiTxBufferPos++;
    SpiTxBufferSize--;
    }
    else
    {

    SpiTxBufferPos = 0;
    SpiTxBufferSize = 0;
    SPI_disableInterrupt(EUSCI_B0_BASE, EUSCI_B_SPI_TRANSMIT_INTERRUPT);

    }
    }
    }
  • The DMA replaces this ISR -- it triggers from the UCTXIFG, it transmits one byte each time, and it stops after it runs out of bytes (=3 in your case).

    You shouldn't enable this ISR (you can remove it if you want) since it will just interfere with the DMA.
  • Hi Bruce,

    I am trying to use DMA scatter gather mode for my project now because I think it will help me more. After reading documents, I set up my code but I think I am making mistake in somewhere DMA Interrupt handler.

    As, I am not interested to receive data from slave side, is it necessary for me to transfer data  &EUSCI_B1_SPI->RXBUF to any other folder ?? because I want to write 3-byte data and in one task I can transfer maximum 1-byte data. what I did according to my understanding ,i defined source address addition.For that please check following code:

    DMA_ControlTable spiDacDmaSeq[TX_TASKS] =
    {
        /* Task1, Dummy read RX buffer to clear IFG
        DMA_TaskStructEntry(1, UDMA_SIZE_8,
                    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
                    UDMA_DST_INC_NONE, &dummyRX,
                    UDMA_ARB_4, (UDMA_MODE_MEM_SCATTER_GATHER+UDMA_MODE_ALT_SELECT)),*/
        /* Task2, Clear Chip select P6.2
        DMA_TaskStructEntry(1, UDMA_SIZE_8,
                    UDMA_SRC_INC_NONE, &outputLow,
                    UDMA_DST_INC_NONE, &P6->OUT,
                    UDMA_ARB_4, (UDMA_MODE_MEM_SCATTER_GATHER+UDMA_MODE_ALT_SELECT)),*/
        /* Task3, load TX buffer to initiate SPI */
        DMA_TaskStructEntry(1, UDMA_SIZE_8,
                    UDMA_SRC_INC_NONE, &SpiTxBuffer[0],
                    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
                    UDMA_ARB_4, (UDMA_MODE_PER_SCATTER_GATHER+UDMA_MODE_ALT_SELECT)),
        /* Task4, Dummy read RX buffer to clear IFG, wait for RXIFG trigger
        DMA_TaskStructEntry(1, UDMA_SIZE_8,
                    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
                    UDMA_DST_INC_NONE, &dummyRX,
                    UDMA_ARB_4, (UDMA_MODE_MEM_SCATTER_GATHER+UDMA_MODE_ALT_SELECT)),
        /* Task 5, load TX buffer to initiate SPI */
        DMA_TaskStructEntry(1, UDMA_SIZE_8,
                    UDMA_SRC_INC_NONE, &SpiTxBuffer[1],
                    UDMA_DST_INC_8, &EUSCI_B1_SPI->TXBUF,
                    UDMA_ARB_4, (UDMA_MODE_PER_SCATTER_GATHER+UDMA_MODE_ALT_SELECT)),
        /*
         * Task 6, Dummy read RX buffer to clear IFG
         * This delay ensures that the chip select happens after the last byte is transmitted
    
        DMA_TaskStructEntry(1, UDMA_SIZE_8,
                    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
                    UDMA_DST_INC_NONE, &dummyRX,
                    UDMA_ARB_4, (UDMA_MODE_MEM_SCATTER_GATHER+UDMA_MODE_ALT_SELECT)),
         /* Task 7, load TX buffer to initiate SPI */
       DMA_TaskStructEntry(1, UDMA_SIZE_8,
                     UDMA_SRC_INC_NONE, &SpiTxBuffer[2],
                     UDMA_DST_INC_16, &EUSCI_B1_SPI->TXBUF,
                     UDMA_ARB_4, (UDMA_MODE_BASIC))
         /* Task 8, set GPIO, chip select
        DMA_TaskStructEntry(1, UDMA_SIZE_8,
                    UDMA_SRC_INC_NONE, &DAC_CS,
                    UDMA_DST_INC_NONE, &P6->OUT,
                    UDMA_ARB_4, UDMA_MODE_BASIC)*/
    };
    
  • I defer to the Driverlib Wizards on this one. I am familiar with scatter/gather, but not the Driverlib model for it.
    -------------------------------
    If you don't care about the Rx data, you don't need to move it anywhere. The Rx side will overrun, but you can ignore it.
  • As Bruce has already mentioned, you do not need to move the Rx data.  If you have seen the example in the SDK, then you will see that the RX is used to identify that the last byte has been transmitted and this is used to make sure that the chip select is not released until after.  This requires that the receive interrupt be used as the trigger and the RX be serviced inorder to clear the DMA trigger (IFG) for the next received byte. 

    Something to bear in mind with the eUSCI spi.  The Transmit trigger to the DMA (IFG) means that the transmit buffer is empty and that the contents have been moved to the shift register.  It does not mean that the data was actually sent.  The RX IFG will indicate that data was actually sent.  If you were to setup the DMA to trigger on the Transmit IFG then you have a problem of knowing when to release the chip select

    In you code that you provided, there is a place where you increment the destination register, but the destination is the Transmit buffer.  This will not work because you will end up somewhere in the peripheral space and may even overwrite the peripheral configuration. - edit - this is actually a don't care because the size is '1'.

    Regards,
    Chris

  • Good morning Chris,

    Thank you for detail explanation. As, I am controlling chip select manually which I have defined in my code so I do not need to pay attention to chip select . I am using channel 0 and its triggering source is eUSCI_B0_TX0 (Using eUSCI_B0 module). In scatter-gather mode , what I need to consider just following parameters: (Please make me correct here ,if something is missing)
    1) task table (code mentioned below)
    2) one dma channel ( channel 0 defined)
    3) one dma interrupt (MAP_DMA_assignInterrupt(DMA_INT1, 0))

    I have following questions :

    1) how to assign channel number ?? ( I did like that (MAP_DMA_assignChannel(DMA_CH0_EUSCIB0TX0)) )
    2) how to declare scatter-gather mode command ?? ( I did like that DMA_setChannelScatterGather(DMA_CH0_EUSCIB0TX0,TX_TASKS,(void*)&spiDacDmaSeq,1))

    On debugging this code, SCLk remained zero and it indicates that SPI is unable to trigger dma and moreover I defined one dummyRX ( for counter check to see if DMA is working or not ) but it is not getting any value to too.

    ************************************************************************************
    /* DMA Control Table*/
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN(controlTable, 1024)
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment=1024
    #elif defined(__GNUC__)
    __attribute__ ((aligned (1024)))
    #elif defined(__CC_ARM)
    __align(1024)
    #endif
    #define TX_TASKS 6
    uint8_t controlTable[16];

    ********************Task List**********************

    DMA_ControlTable spiDacDmaSeq[TX_TASKS] =
    {
    /*Task1, Dummy read RX buffer to clear IFG */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_4, (UDMA_MODE_MEM_SCATTER_GATHER)),
    /* Task3, load TX buffer to initiate SPI */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &SpiTxBuffer[0],
    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
    UDMA_ARB_4, (UDMA_MODE_PER_SCATTER_GATHER)),
    /* Task4, Dummy read RX buffer to clear IFG, wait for RXIFG trigger */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_4, (UDMA_MODE_MEM_SCATTER_GATHER)),
    /* Task 5, load TX buffer to initiate SPI */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &SpiTxBuffer[1],
    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
    UDMA_ARB_4, (UDMA_MODE_PER_SCATTER_GATHER)),
    /*
    * Task 6, Dummy read RX buffer to clear IFG
    * This delay ensures that the chip select happens after the last byte is transmitted
    */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_4, (UDMA_MODE_MEM_SCATTER_GATHER)),
    /* Task 7, load TX buffer to initiate SPI */
    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &SpiTxBuffer[2],
    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
    UDMA_ARB_4, (UDMA_MODE_AUTO)),

    };

    **********************************main code******************
    MAP_DMA_assignChannel(DMA_CH0_EUSCIB0TX0);
    MAP_DMA_assignInterrupt(DMA_INT1, 0);
    MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
    MAP_Interrupt_disableSleepOnIsrExit();
    ********************************************************************
    MAP_DMA_setChannelScatterGather(DMA_CH0_EUSCIB0TX0,TX_TASKS,(void*)&spiDacDmaSeq,1);
    MAP_DMA_enableChannel(DMA_CH0_EUSCIB0TX0);

    SPI_enableInterrupt(EUSCI_B0_BASE, EUSCI_A_SPI_RECEIVE_INTERRUPT);
  • (1) You have assigned the channel correctly, however, you are using the channel assignment variable in the context of enable Channel API which will not work.  Please refer to the API guide to understand the correct values.

    "This function assigns a peripheral mapping to a DMA channel. It is used to select which peripheral is used for a DMA channel. The parameter mapping should be one of the macros named UDMA_CHn_tttt from the header file dma.h. For example, to assign DMA channel 0 to the eUSCI AO RX channel, the parameter should be the macro UDMA_CH1_EUSCIA0RX."

    (2)  The configuration of the scatter-gather mode is done with the API you highlight.  After this is done, then you would enable the channel.  In your specific situation, if you are triggering off of the Transmit from the eUSCI, then please note that the TX IFG is set immediately after the eUSCI is configured.  This is because the buffer is empty after initialization.  Again, you are not enabling the channel because you are using the wrong parameter.  

    I would highly recommend looking at the example mentioned previously.  Please note the order of operation and syntax.  Again, do not enable the SPI interrupt.  By definition of the DMA it will trigger via the appropriate signal.

    Regards,

    Chris

  • Hi Chris,

    Thanks for your explantation, I throughly understand the recommended example and tried to implement it in my case. According to my understanding ,it should work but on debugging this , MOSI and SIMO are not moving still and resulting same result which I have before. It would be great if you just have a look on my code because I think that I am having issues somewhere SPI_Interrupt (may be). many thanks for your support throughout my theses .
    /*********************** Configuring DMA module *****************************************/
    MAP_DMA_enableModule();
    MAP_DMA_setControlBase(controlTable);
    MAP_DMA_assignChannel(DMA_CH0_EUSCIB0TX0);
    MAP_DMA_assignInterrupt(DMA_INT1, 0);


    /****************************declaration*****************/

    MAP_DMA_setChannelScatterGather(DMA_CH0_EUSCIB0TX0,TX_TASKS,(void*)&spiDacDmaSeq[0],0);
    MAP_DMA_clearInterruptFlag(DMA_CH0_EUSCIB0TX0 & 0x0F);
    MAP_DMA_enableChannel(0);
    EUSCI_B0_SPI->IFG |= EUSCI_B_IFG_RXIFG0;

    SPI_enableInterrupt(EUSCI_B0_BASE, EUSCI_B_SPI_RECEIVE_INTERRUPT); /* main SPI interrupt */
    /* Assigning/Enabling Interrupts*/
    MAP_DMA_enableInterrupt(INT_DMA_INT1);
    MAP_Interrupt_enableInterrupt(INT_DMA_INT1);
    MAP_Interrupt_disableSleepOnIsrExit();
    **************************task list********************
    DMA_ControlTable spiDacDmaSeq[TX_TASKS] =
    {
    /*Task1, Dummy read RX buffer to clear IFG */

    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_1, (UDMA_MODE_MEM_SCATTER_GATHER)),

    /* Task3, load TX buffer to initiate SPI */

    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &SpiTxBuffer[0],
    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
    UDMA_ARB_1, (UDMA_MODE_PER_SCATTER_GATHER)),

    /* Task4, Dummy read RX buffer to clear IFG, wait for RXIFG trigger */

    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_1, (UDMA_MODE_MEM_SCATTER_GATHER)),

    /* Task 5, load TX buffer to initiate SPI */

    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &SpiTxBuffer[1],
    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
    UDMA_ARB_1, (UDMA_MODE_PER_SCATTER_GATHER)),
    /*
    * Task 6, Dummy read RX buffer to clear IFG

    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &EUSCI_B1_SPI->RXBUF,
    UDMA_DST_INC_NONE, &dummyRX,
    UDMA_ARB_1, (UDMA_MODE_MEM_SCATTER_GATHER)),

    /* Task 7, load TX buffer to initiate SPI */

    DMA_TaskStructEntry(1, UDMA_SIZE_8,
    UDMA_SRC_INC_NONE, &SpiTxBuffer[2],
    UDMA_DST_INC_NONE, &EUSCI_B1_SPI->TXBUF,
    UDMA_ARB_1, (UDMA_MODE_AUTO)),

    };
  • In this snippet you have provided there are a couple of things that do not make sense:
    (1) The trigger is the eUSCI TX IFG, however, it appears that you are reading from the receive buffer based upon this trigger. The TX IFG which is used to trigger the DMA only indicates that the data has moved from the transmit buffer into the transmit shift register and no actual data has been received. The SPI clock will not become active until there is data in the transmit shift register to actually shift out.
    (2) The eUSCI RX inerrupt is enabled. From the code provided, I am not sure how this is handled. This would suggest that an ISR is being serviced an potentially reading the data from the RX buffer while the DMA is also servicing the RX buffer.
    (3) Using the scatter-gather method does not appear to provide any benefit. It would be more straight forward to just use the basic mode to load the TX buffer when TXIFG trigger occurs.

    Since you are not concerned about the chip select, maybe a better example would be the spi loop-back so you only need to trigger on the TX and simply move data to the TX-buffer.
    dev.ti.com/.../

    Chris
  • Thank you Chris and Bruce, I have solved DMA problem. I used scather gather technique which helped me to speed up spi and am able to save 10us time. I got the similar result with spi-loop back technique also. Once again , thank you so much for your support througout my theses. :)

    regards,
    Hasan

**Attention** This is a public forum