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.

TM4C123GH6PZ: Can DMA use for SD card read

Part Number: TM4C123GH6PZ


Hi,

In my project I want to use DMA for reading data from the SD card.I was checking for some examples regarding this but didn't get any information. If anyone done this please guide me how I can use DMA for SD card read. 

The SD card have SSI interface with the microcontroller.

Thank you,

Alphy

  • Hello Alphy,

    We don't have any examples to do so. The SD card examples make use of a third party fatfs library to handle the SD card operations and that does not include any DMA handling. In theory it may be possible to edit the physical interface in a file like mmc-dk-tm4c123g.c but that is not something that we are supporting on our end.

  • Hi,

    Thank you for your quick reply. I have tried to edit the  mmc-dk-tm4c123g.c  file and the changes done on the library are given below.

       // Enable the uDMA controller at the system level.  Enable it to continue
        // to run while the processor is in sleep.
        //
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
    
        //
        // Enable the uDMA controller error interrupt.  This interrupt will occur
        // if there is a bus error during a transfer.
        //
        //ROM_IntEnable(INT_UDMAERR);
    
        //
        // Enable the uDMA controller.
        //
        ROM_uDMAEnable();
    
        //
        // Point at the control table to use for channel control structures.
        //
        ROM_uDMAControlBaseSet(ui8ControlTable);

    static
    void power_on (void)
    {
        /*
         * This doesn't really turn the power on, but initializes the
         * SSI port and pins needed to talk to the card.
         */
    			
        /* Enable the peripherals used to drive the SDC on SSI */
        ROM_SysCtlPeripheralEnable(SDC_SSI_SYSCTL_PERIPH);
        ROM_SysCtlPeripheralEnable(SDC_GPIO_SYSCTL_PERIPH);
    
        /*
         * Configure the appropriate pins to be SSI instead of GPIO. The FSS (CS)
         * signal is directly driven to ensure that we can hold it low through a
         * complete transaction with the SD card.
         */
        ROM_GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK);
        ROM_GPIOPinTypeGPIOOutput(SDC_GPIO_PORT_BASE, SDC_SSI_FSS);
    
        /*
         * Set the SSI output pins to 4MA drive strength and engage the
         * pull-up on the receive line.
         */
        MAP_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_RX, GPIO_STRENGTH_4MA,
                             GPIO_PIN_TYPE_STD_WPU);
        MAP_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_CLK | SDC_SSI_TX | SDC_SSI_FSS,
                             GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
    
        /* Configure the SSI0 port */
        ROM_SSIConfigSetExpClk(SDC_SSI_BASE, ROM_SysCtlClockGet(),
                               SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8);
        ROM_SSIEnable(SDC_SSI_BASE);
    /*Test*/
    		uDMAChannelDisable(UDMA_CHANNEL_SSI0RX);
    
    		/*UDMAChannelAssign is very important, as you saw each DMA
        		chanel has alot of triggers so you need this to decide wich one, in this case it's UDMA_CHANNEL_SSI0RX*/
    		
    		uDMAChannelAssign(UDMA_CHANNEL_SSI0RX);
    
    		uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI0RX, UDMA_ATTR_ALL);
    
    
    		uDMAChannelControlSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    		UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_NONE | UDMA_ARB_1);
    
    
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    		UDMA_MODE_BASIC,(void *)(SSI0_BASE + SSI_O_DR),
                                       g_ui32RxBufA, sizeof(g_ui32RxBufA));;
    
    		SSIDMAEnable(SSI0_BASE, SSI_DMA_RX);
    /* End of Test*/
    
        /* Set DI and CS high and apply more than 74 pulses to SCLK for the card */
        /* to be able to accept a native command. */
        send_initial_clock_train();
    
        PowerFlag = 1;
    }
    static
    BYTE rcvr_spi (void)
    {
        uint32_t ui32RcvDat;
    
        ROM_SSIDataPut(SDC_SSI_BASE, 0xFF); /* write dummy data */
    
    //    ROM_SSIDataGet(SDC_SSI_BASE, &ui32RcvDat); /* read data frm rx fifo */
    //		ROM_SSIIntStatus(SSI0_BASE, 1);
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    		UDMA_MODE_BASIC,(void *)(SSI0_BASE + SSI_O_DR),
    g_ui32RxBufA, sizeof(g_ui32RxBufA)); 
    return (BYTE)ui32RcvDat; 
    }

    The above mentioned are the changes done on the  mmc-dk-tm4c123g.c  file.

    (void *)(SSI0_BASE + SSI_O_DR) step giving an error that SSI_O_DR identifier undefined. How to solve this issue.

    I am using polling method for DMA.Is the above changes are ok or I have to do any other changes for reading from the SD card.

    Thank you,
    Alphy

  • Hello Alphy,

    Alphy Ouseph said:
    (void *)(SSI0_BASE + SSI_O_DR) step giving an error that SSI_O_DR identifier undefined. How to solve this issue.

    You need to include the header with that definition, so #include "inc/hw_ssi.h" should have all you need. If that isn't enough then check the includes in your main code too.

  • Hi,

    I have included the header and the error got resolved. Now I am able to run my code.

     The rcvr_spi function always return zero. The ROM_uDMAChannelModeGet function not returning UDMA_MODE_STOP.

    I am using polling method for DMA. Is there any issue with DMA initialization? Is any other steps need to add for making the DMA work?

    The changes I have done on my mmc-dk-tm4c123g.c  file is given below,

    static
    void power_on (void)
    {
        /*
         * This doesn't really turn the power on, but initializes the
         * SSI port and pins needed to talk to the card.
         */
    			
        /* Enable the peripherals used to drive the SDC on SSI */
        ROM_SysCtlPeripheralEnable(SDC_SSI_SYSCTL_PERIPH);
        ROM_SysCtlPeripheralEnable(SDC_GPIO_SYSCTL_PERIPH);
    
        /*
         * Configure the appropriate pins to be SSI instead of GPIO. The FSS (CS)
         * signal is directly driven to ensure that we can hold it low through a
         * complete transaction with the SD card.
         */
        ROM_GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK);
        ROM_GPIOPinTypeGPIOOutput(SDC_GPIO_PORT_BASE, SDC_SSI_FSS);
    
        /*
         * Set the SSI output pins to 4MA drive strength and engage the
         * pull-up on the receive line.
         */
        MAP_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_RX, GPIO_STRENGTH_4MA,
                             GPIO_PIN_TYPE_STD_WPU);
        MAP_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_CLK | SDC_SSI_TX | SDC_SSI_FSS,
                             GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
    
        /* Configure the SSI0 port */
        ROM_SSIConfigSetExpClk(SDC_SSI_BASE, ROM_SysCtlClockGet(),
                               SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8);
        ROM_SSIEnable(SDC_SSI_BASE);
    /*Test*/
    		ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
    
        //
        // Enable the uDMA controller error interrupt.  This interrupt will occur
        // if there is a bus error during a transfer.
        //
        ROM_IntEnable(INT_UDMAERR);
    
        //
        // Enable the uDMA controller.
        //
        ROM_uDMAEnable();
    
        //
        // Point at the control table to use for channel control structures.
        //
        ROM_uDMAControlBaseSet(ui8ControlTable);
    		
    		uDMAChannelDisable(UDMA_CHANNEL_SSI0RX);
    
    		/*UDMAChannelAssign is very important, as you saw each DMA
        		chanel has alot of triggers so you need this to decide wich one, in this case it's UDMA_CHANNEL_SSI0RX*/
    		
    		uDMAChannelAssign(UDMA_CHANNEL_SSI0RX);
    
    		uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI0RX, UDMA_ATTR_ALL);
    
    
    		uDMAChannelControlSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    		UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_1);
    
    
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    		UDMA_MODE_BASIC,(void *)(SSI0_BASE + SSI_O_DR),
                                       g_ui32RxBufA, sizeof(g_ui32RxBufA));
    
    		SSIDMAEnable(SSI0_BASE, SSI_DMA_RX);
    		
    
    /* End of Test*/
    
        /* Set DI and CS high and apply more than 74 pulses to SCLK for the card */
        /* to be able to accept a native command. */
        send_initial_clock_train();
    
        PowerFlag = 1;
    }
    static
    BYTE rcvr_spi (void)
    {
        uint32_t ui32RcvDat, ui32Mode;
    	
        ROM_SSIDataPut(SDC_SSI_BASE, 0xFF); /* write dummy data */
    
    //    ROM_SSIDataGet(SDC_SSI_BASE, &ui32RcvDat); /* read data frm rx fifo */
    //		ROM_SSIIntStatus(SSI0_BASE, 1);
    	  ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT);
    	 if(ui32Mode == UDMA_MODE_STOP)
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    			UDMA_MODE_BASIC,(void *)(SSI0_BASE + SSI_O_DR),g_ui32RxBufA, sizeof(g_ui32RxBufA));
    		ui32RcvDat = g_ui32RxBufA[0];
        return (BYTE)ui32RcvDat;
    }

    Thank you,

    Alphy

  • Greetings,

    Our small tech group admires your 'trailblazing" efforts in the "shot-gun" marriage of SD Card & MCU's µDMA.

    You noted that, "No such examples" existed - might that have been "deliberate?"

    The SPI FIFO is extremely small sized - does that not "conflict" w/the µDMA's 1024 transaction capacity?   (i.e. necessary µDMA "calling overhead" must be (endlessly) repeated - likely eroding µDMA's efficiency!)

    Such warrants your consideration - does it not?

    Arrived today a (somewhat) similar posting (w/EPI SD Ram transacting w/the MCU's SPI via µDMA.)    Perhaps beneficial - worth your read... 

    e2e.ti.com/.../897931

  • Hi,

    Once again thank you so much for your quick reply.

    As you mentioned, The SPI FIFO is extremely small sized - does that not "conflict" w/the µDMA's 1024 transaction capacity?   (i.e. necessary µDMA "calling overhead" must be (endlessly) repeated - likely eroding µDMA's efficiency!). But in my program the arbitration size is 8 only. is it make any problem? 

    ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT); function not returning UDMA_MODE_STOP what may be the problem?

    I changed the program from polling method to interrupt. The program is not going to the SSI interrupt handler function.What may be the reason.how to solve it?

    The given below is the new modified code,

    static
    void power_on (void)
    {
    	
        /*
         * This doesn't really turn the power on, but initializes the
         * SSI port and pins needed to talk to the card.
         */
    			
        /* Enable the peripherals used to drive the SDC on SSI */
        ROM_SysCtlPeripheralEnable(SDC_SSI_SYSCTL_PERIPH);
        ROM_SysCtlPeripheralEnable(SDC_GPIO_SYSCTL_PERIPH);
    
        /*
         * Configure the appropriate pins to be SSI instead of GPIO. The FSS (CS)
         * signal is directly driven to ensure that we can hold it low through a
         * complete transaction with the SD card.
         */
        ROM_GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK);
        ROM_GPIOPinTypeGPIOOutput(SDC_GPIO_PORT_BASE, SDC_SSI_FSS);
    
        /*
         * Set the SSI output pins to 4MA drive strength and engage the
         * pull-up on the receive line.
         */
        MAP_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_RX, GPIO_STRENGTH_4MA,
                             GPIO_PIN_TYPE_STD_WPU);
        MAP_GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_CLK | SDC_SSI_TX | SDC_SSI_FSS,
                             GPIO_STRENGTH_4MA, GPIO_PIN_TYPE_STD);
    
        /* Configure the SSI0 port */
        ROM_SSIConfigSetExpClk(SDC_SSI_BASE, ROM_SysCtlClockGet(),
                               SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8);
    //		SSIEnable(SSI0_BASE);
    
    	/* Clear SSI0 RX Buffer */
    	while (ROM_SSIDataGetNonBlocking(SSI0_BASE, &g_ui32RxBufA[0])) {}											 
        ROM_SSIEnable(SDC_SSI_BASE);
    		ROM_SSIIntEnable(SSI0_BASE,SSI_DMARX);
    /*Test*/
    		ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
        ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
    
        //
        // Enable the uDMA controller error interrupt.  This interrupt will occur
        // if there is a bus error during a transfer.
        //
        ROM_IntEnable(INT_UDMAERR);
    
        //
        // Enable the uDMA controller.
        //
        ROM_uDMAEnable();
    		//
    	// Enable the uDMA interface for both TX and RX channels.
    	//
    		ROM_SSIDMAEnable(SSI0_BASE, SSI_DMA_RX);
        //
        // Point at the control table to use for channel control structures.
        //
        ROM_uDMAControlBaseSet(ui8ControlTable);
    //		uDMAChannelDisable(UDMA_CHANNEL_SSI0RX);
    
    		/*UDMAChannelAssign is very important, as you saw each DMA
        		chanel has alot of triggers so you need this to decide wich one, in this case it's UDMA_CHANNEL_SSI0RX*/
    		
    		uDMAChannelAssign(UDMA_CHANNEL_SSI0RX);
    
    		uDMAChannelAttributeDisable(UDMA_CHANNEL_SSI0RX, UDMA_ATTR_ALTSELECT |
                                        UDMA_ATTR_HIGH_PRIORITY |
                                        UDMA_ATTR_REQMASK);
    
    
    		uDMAChannelControlSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    		UDMA_SIZE_32 | UDMA_SRC_INC_NONE | UDMA_DST_INC_32 | UDMA_ARB_8);
    
    
    		uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    		UDMA_MODE_BASIC,(void *)(SSI0_BASE + SSI_O_DR),
                                       g_ui32RxBufA, sizeof(g_ui32RxBufA));;
    		ROM_SSIIntEnable(SDC_SSI_BASE, SSI_DMARX);
    //		SSIDMAEnable(SDC_SSI_BASE, SSI_DMA_RX);
    		//
    		// Enable the SSI0 peripheral interrupts.
    		//
    		ROM_IntEnable(INT_SSI0);
    		
    	
    /* End of Test*/
    
        /* Set DI and CS high and apply more than 74 pulses to SCLK for the card */
        /* to be able to accept a native command. */
        send_initial_clock_train();
    
        PowerFlag = 1;
    }
    void
    SSI0_Handler(void)
    {
    	uint32_t ui32Status;
    	uint32_t ui32Mode;
    
    	ui32Status = ROM_SSIIntStatus(SDC_SSI_BASE, 1);        //will return the cause of interrupt(SSITX or SSIRX interrupt )
    
    	ROM_SSIIntClear(SDC_SSI_BASE, ui32Status);
    
    	ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT);
    
    //	if(ui32Mode == UDMA_MODE_STOP)
    //	{
    			uDMAChannelTransferSet(UDMA_CHANNEL_SSI0RX | UDMA_PRI_SELECT,
    			UDMA_MODE_BASIC,(void *)(SSI0_BASE + SSI_O_DR),
    																		 g_ui32RxBufA, sizeof(g_ui32RxBufA));
    	//}
    }
    

    Please help me to these issues.

    Thank you,

    Alphy

  • Thank you - our outsider group would love to be able to guide/assist - yet we are (once again) "Over our heads" in that regard.    On multiple occasions vendor agents (w/great inside knowledge of their devices) have noted that, "Short, Choppy µDMA transfers fail to achieve optimum µDMA results!"    And that's to be expected - is it not?

    Thinking aloud - might some other means of transfer be explored - which enables a far greater (thus more efficient) µDMA transfer size?    (i.e. perhaps a small "CPLD" could achieve the transfer from SD Card to MCU's (or other) Sram.   In that manner - freed from the 8 or 16 byte limit - µDMA transfers could be improved ... (at least in theory ... maybe.)

    Have you stated your objective in employing the µDMA?    The other post we referenced noted that user's goal of, "Having the code run "core diminished or (even) free."    Other than that specific benefit - it is hard to note  your expectations - driving your µDMA interest..   Again - the absence of (any) existing code (may) indicate that the vendor did not believe such usage made great sense...

  • Hello Alphy,

    Alright so first off... the SD card is set for 8 byte transfers:

        /* Configure the SSI0 port */
        ROM_SSIConfigSetExpClk(SDC_SSI_BASE, ROM_SysCtlClockGet(),
                               SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 400000, 8);

    So given that, setting the the uDMA size to 32 bytes is not correct, it should be UDMA_SIZE_8.

    Based on this, UDMA_DST_INC_32 should probably be changed to UDMA_DST_INC_8 too.

    Regarding UDMA_ARB_8 and other arbitration values, it depends how you intend to use the DMA... 

    From the D/S: Each channel also has a configurable arbitration size. The arbitration size is the number of items that are transferred in a burst before the μDMA controller re-arbitrates for channel priority. Using the arbitration size, it is possible to control exactly how many items are transferred to or from a peripheral each time it makes a μDMA service request.

    So what this means is you would decide how much data you want to read out per uDMA transfer. If you have a lot of data, like the SD card should, then you probably want to set this to be 1024. Once you reach that amount, you will have to reconfigure the uDMA channel whether using the same one or a secondary channel in the event of ping pong mode.

    Another point is that interrupt or not, I believe you still need 

    SSIDMAEnable(SSI0_BASE, SSI_DMA_RX);

    Make sure to also have this for interrupts:

        //
        // Enable interrupts to the processor.
        //
        ROM_IntMasterEnable();

    See where those adjustments get you and we can move from there.

  • Hi,

    Thank you so much for both you people replies.

    Have you stated your objective in employing the µDMA?  The objective is to run a motor for 1 millisecond for one RPM value. The text file stored inside the SD card have different RPM values.My aim was to run the motor for one millisecond and before finishing 1 millisecond fetch next RPM value from the SD card. But unable to finish reading within the 1 millisecond.I thought to use array to store all the data read from the SD card, but there is limitation in RAM size. So finally I thought to use µDMA for reading data from SD card and use the core for running motor.

    On multiple occasions vendor agents (w/great inside knowledge of their devices) have noted that, "Short, Choppy µDMA transfers fail to achieve optimum µDMA results!"    And that's to be expected - is it not?Yes that is there in my consideration.  

     I have changed the UDMA_DST_INC_32 to UDMA_DST_INC_8. The interrupt part you mentioned was already implemented. But still it is not going to interrupt.

    Instead of ROM_SSIIntEnable(SSI0_BASE,SSI_DMARX); if I am using ROM_SSIIntEnable(SSI0_BASE,SSI_RXFF); then control is going to the isr. Is there any issue with µDMA configuration?

    Thank you,

    Alphy

  • Hello again & thank you,   (Few here answer (necessary) questions w/the care & detail you've shown)

    Let's examine your response in (even) deeper detail:

    Alphy Ouseph said:
    ... objective is to run a motor for 1 millisecond for one RPM value.

    This response (very) nicely illustrates the value of, "Questioning Poster Requests."   Our small tech firm has produced various Motor Controllers (for BLDC, Brushed, Stepper etc.) for the past ten years.   Motors - especially when "Driving a Load" - encounter "Inertia" - and that inertia PREVENTS most motors from responding (to control commands) w/in 1mS!   (Depending upon the load - even a 50mS response time may be hard to meet!   Such holds true for most all motors we've encountered - but for novel & lightly loaded Piezo Motors.)    Thus - you may have chosen an, "Unreachable Objective" - & that may, "Free you from the added time/effort required to "marry" the µDMA to the SPI Module."

    Alphy Ouseph said:
    ... text file stored inside the SD card have different RPM values.

    Have you not increased processing demands by employing a "Human Readable" text file?    Would not binary values (i.e. two bytes) provide 65K motor speeds - which may be passed far faster & easier than "text data?"    Again - the "design decision" (may) deserve examination/re-think.

    Most all of our firm's Motor Controllers enable, "Motion Profiles" - which allow:

    • Acceleration (variable) from Stopped to Speed #1
    • Timed duration w/in speed #1 (motor current & RPM tightly measured & controlled)
    • Acceleration or Decelleration to Speed #2
    • Timed duration w/in speed #2  (motor current & RPM tightly measured & controlled)
    • this continues for up to 32 distinct motion profiles  (more available upon special order)

    Note that "None of the Above" is actively stored w/in an (inefficient) Text File.   Users simply enter "decimal data" (via a serial, terminal program) - which IS a text file - and that data is efficiently converted from text & then stored w/in external, non-volatile, Serial Flash (8 pin) Memory.

    You may benefit from noting (just one) of our firm's "Inertia Wheels."   Clearly - even one of our 10KW Motor Controllers would be unable to "bump the RPM" @ 1mS intervals!   Being able to "Test/Verify" our Motor Controller's ability to successfully Control (even) large loads - (even) prior to delivery - provides a HUGE Competitive Advantage...

    Do note that "you too" may be able to implement such a key "Motor Load/Test" - and in that manner - "unlock" the "Real-World response requirements" of your system!    (highly unlikely to match your (somehow chosen) 1mS control rate...)

  • Hello Alphy,

    Alphy Ouseph said:
    Have you stated your objective in employing the µDMA?  The objective is to run a motor for 1 millisecond for one RPM value. The text file stored inside the SD card have different RPM values.My aim was to run the motor for one millisecond and before finishing 1 millisecond fetch next RPM value from the SD card. But unable to finish reading within the 1 millisecond.I thought to use array to store all the data read from the SD card, but there is limitation in RAM size. So finally I thought to use µDMA for reading data from SD card and use the core for running motor.

    In addition to cb1's commentary here about that this isn't even physically possible - I am not sure how much uDMA would help here. You are also probably limited by the time of transmission over SPI and access to the SD card too - how long is your SPI communication alone? Do you need these bytes real time, as in, read one byte and then in 1 ms have the next byte or can you build a buffer of bytes to allow for lag? How many bytes of data? How much of a gap time wise are you seeing? uDMA is most helpful with running in the background and doing large transfers etc. Is there other pieces of software bottle necking this read time or is the SD card operation all that is running?

    I have a lot of doubt this is a worthwhile endeavor as well - on top of cb1's very valid doubts that the motor can even respond well. I can attest that his firm has extensive experience with motors, please read his feedback closely...

  • Hi,

    Sorry for the late reply. Your well explained reply make me to think about lot of things. Thank you so much for your quick replies.

     Our small tech firm has produced various Motor Controllers (for BLDC, Brushed, Stepper etc.) for the past ten years.   Motors - especially when "Driving a Load" - encounter "Inertia" - and that inertia PREVENTS most motors from responding (to control commands) w/in 1mS!   (Depending upon the load - even a 50mS response time may be hard to meet!   Such holds true for most all motors we've encountered - but for novel & lightly loaded Piezo Motors.)    Thus - you may have chosen an, "Unreachable Objective" - & that may, "Free you from the added time/effort required to "marry" the µDMA to the SPI Module."

    I am using a Panasonic minas a6 series AC servo motor.I am running the motor using Timer PWM. The motor was running perfectly with given RPM values.  

    Have you not increased processing demands by employing a "Human Readable" text file?    Would not binary values (i.e. two bytes) provide 65K motor speeds - which may be passed far faster & easier than "text data?"    Again - the "design decision" (may) deserve examination/re-think.

    Could you please let me know apart from the text file format which file format can increase the processing speed?

     Do you need these bytes real time, as in, read one byte and then in 1 ms have the next byte or can you build a buffer of bytes to allow for lag? How many bytes of data? How much of a gap time wise are you seeing? 

    I will read one data(maximum size is 3 bytes) then start running the motor  and then again start fetching the new data.But around 2ms gap I am seeing..

    Thank you,

    Alphy

  • Diminishing returns Greetings,

    Alphy Ouseph said:
    I am using a Panasonic minas a6 series AC servo motor.I am running the motor using Timer PWM. The motor was running perfectly with given RPM values.  

    Pardon - but nothing in the above describes the, "Quest for 1mS Motor Speed Updates" - nor does it "Venture into the "REALITY" of the Motor as a component - driving a "Real-World" LOAD!    (which must comply w/the laws of Inertia!)    As your motor was "Running Perfectly" - we are, "Unable to grasp what (further) you seek!"

    Alphy Ouseph said:
    Could you please let me know apart from the text file format which file format can increase the processing speed?

    As earlier stated - TWO Binary Bytes enable ~64K Speed Settings.   Your SD-Card logic seems inconsistent:

    • you seek fast SD Card response
    • yet you store key/critical data in "Human Readable" (i.e. Text Format)

    That's "self-defeating" - is it not?   Human readable format (always) slows & adds complexity to data transfer - Not our choice!

  • Hello Alphy,

    Alphy Ouseph said:
    I will read one data(maximum size is 3 bytes) then start running the motor  and then again start fetching the new data.But around 2ms gap I am seeing..

    Have you monitored the SPI transfer time for this? How long does it take just on SPI lines to handle this piece?

    If you are doing this, how do you envision uDMA helping? This sounds very active... I don't see uDMA offers you any advantages here... SSI and SD card protocol are likely far more of a bottle neck and I am not clear how you expect uDMA to cut this all down by 2ms.

  • Hi,

    Once again thank you for quick reply.

    "Quest for 1mS Motor Speed Updates" - nor does it "Venture into the "REALITY" of the Motor as a component - driving a "Real-World" LOAD!    (which must comply w/the laws of Inertia!)    As your motor was "Running Perfectly" - we are, "Unable to grasp what (further) you seek!"

    I am using the motor for pumping fluid. My objective was to use uDMA for reading data from SD card and use core for running the motor. 

    Have you monitored the SPI transfer time for this? How long does it take just on SPI lines to handle this piece?

    Sorry because of lock down I am not able to go office so I don't have logical analyser to check the transfer time. I have tested the data read and motor running timing with 1ms timer interrupt.

    If you are doing this, how do you envision uDMA helping? This sounds very active... I don't see uDMA offers you any advantages here... SSI and SD card protocol are likely far more of a bottle neck and I am not clear how you expect uDMA to cut this all down by 2ms.

    The data fetch from SD card tooks more time than what I expected. So I thought to use UDMA for SD card and controller interface and use core for motor running. 

    Thank you, 

    Alphy 

  • Hello,

    Alphy Ouseph said:
     I have tested the data read and motor running timing with 1ms timer interrupt.

    But, "Why 1mS?"   Can your "Fluid Circulatory System" (really) and effectively support and/or "benefit" from such a frequency?    What experimentation have you performed to confirm (any) benefits resulting from 1mS rate?

    We've no clue as to the extent of your fluid system and/or its limitations or sensitivities.   We have observed that many such (properly designed/developed) systems perform optimally (and last longest) when pump rates, capacities & fluid flows all are to "specification!"    We remain (very much) in the dark - as regards your system & your design choices...

  • Hi,

    Thank you so much for your quick response.

    I have calculated the flow rate for different speed of motor(not tested with 1mS). While testing the firmware I was not able to achieve the 1mS that's why I thought to use uDMA. My first objective was to make the firmware properly with 1mS, then only I can check the motor for 1mS.

    Thank you,

    Alphy

  • My friend,

    Pardon - both vendor agent & my group have noted that (any) benefits stemming from µDMA use are unlikely.   Might it be time to "move on?"

    In your study of pumps:  (centrifugal, positive displacement, air operated diaphragm...) you surely took notice of, "Your pump's operating curve."    Ideally you should operate at/around the pump's optimal efficiency point.

    Use of both a pressure gauge and/or flow-meter boost your grasp of where the pump is operating w/in its curve.   

    The "MCU -> Motor -> Pump" control serves as one (of many) items which require attention.   It is suspected that (further) review of your pump's operating curve will, "Free you from the 1mS (and only 1mS) fixation...

    Your use of text w/in the SD Card - earlier noted - both "slows & adds complexity" to your motor control processing.

  • Hi,

    Thank you again for quick responses.

    I will check all those points you have mentioned.Thanks for all the help!

    Thank you,

    Alphy