Other Parts Discussed in Thread: MSP430G2553, SYSBIOS
Dear all,
I want to each 0.3µs to change GPIO high or low.
So how to create a timer on RTOS and period about 0.3µs?
Thanks.
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.
Dear all,
I want to each 0.3µs to change GPIO high or low.
So how to create a timer on RTOS and period about 0.3µs?
Thanks.
Hi Zheng,
I agree with David, if this is your only requirement an RTOS adds significant overhead you don't need.
See this example code for toggling a GPIO using a timer interrupt (non RTOS) on MSP430F55x: https://dev.ti.com/tirex/explore/node?node=A__AOV7.th6jm.8lJ4fI8h9Hg__msp430ware__IOGqZri__LATEST
Best Regards,
Brandon Fisher
Hi All,
You mean that can not create period about 0.3µs on TI-RTOS with MSP430F5529?
If I want to create, you suggest use non RTOS system? such like above example?
Thanks.
The resolution of RTOS events isn't any better than its tick rate. Which is never that fast.
The tick rate is a balance between the time resolution required and the time required to service every tick. Which includes saving the current state (all registers), finding the next task to run, and restoring that tasks state. Set the tick rate too high and you have no time left for the tasks.
I wouldn't use a tick rate greater than 1KHz on a MSP430.
Hi David,
Thanks for your suggest.
But If I want to control light that need produce different waveform to change light color.
The waveform like on below picture.
On TI-RTOS can create or not? If can, how should I do?
Thanks.
Twiddle GPIO outputs in the usual way. No RTOS required. Do you require an RTOS for some other reason or are you just assuming that an RTOS is the way to do this?
With a 20MHz MCLK you have 50ns resolution on delays. Generating exact times will require using assembly language. You could do it in C but the delays would then be compiler dependent. Not the delays themselves as __delay_cycles() is fine but the rest of the code to toggle the output.
Hi David,
We require an TI-RTOS because our project start form RTOS and keep running more than 1 year ago.
Now we add new light sensor that need produce different waveform to control.
So I want to know the MSP430F5529 on RTOS that has ability to make it?
About 800kHz PWM and after each cycle need to change next cycle's duty.
I don't find any document to describe speed limit on RTOS system.
Thanks.
Hi Zheng,
If you do need an RTOS based solution there is still TI-RTOS for MSP430, but its not supported any longer: http://downloads.ti.com/dsps/dsps_public_sw/sdo_sb/targetcontent/tirtos/index.html
There are also many 3rd party RTOS options for MSP430 listed here: https://www.osrtos.com/
Best Regards,
Brandon Fisher
Hi All,
Can I use PWM + DMA to produce those waveform on TI-RTOS system?
If can, how should I do?
Thanks.
Hi Zheng,
Are you trying to change the PWM Duty Cycle or the Frequency?
The TI-RTOS User's Guide (found at C:/ti/tirtos_msp43x_<VERSION_NUMBER>/docs/Users_Guide.pdf by default on windows) section 5.9 gives the relevant API calls for PWM. As well as the steps for setup and configuration.
If you are just trying the change the light intensity you can do that with PWM_setDuty() after initial setup. I don't see any support to do that via the DMA though, so you would have to update in software, which might not exactly meet your update requirements.
Also, based on the description of the PWM Parameters structure, the PWM driver only supports integer values for PWM period in microseconds, so you might need to get creative there as well.
Best Regards,
Brandon Fisher
Hi Brandon,
1. Yes. I want to change PWM Duty after each pulse.
2. According your suggest that DMA not support PWM. Can I use SPI+DMA to produce above special waveform? I want to control the LED that interface like ws2812b neopixels.. If this method can make it, how should I setting on TI-RTOS system?
Thanks.
A quick search (if I could do it...) turns up code on Github for the MSP430 and WS2812.
Can I use SPI+DMA to produce above special waveform?
The Github project which David linked is:
a. For a MSP430G2553 rather than a MSP430F5529 and so would require porting to allow for peripheral differences
b. Doesn't use DMA. The code disables interrupts generating the SPI waveform
Found https://github.com/hoihu/WS2812 which runs on the TI MSP430 5529 launchpad and uses SPI+DMA.
Hi Chester,
Thanks for your suggestion.
But I want to base on TI-RTOS system. Those examples are on NonOS.
I use SPI API, but it will stop on SPI_transfer(spi_master, &spiTransaction) API.
How should I solve it?
---------------------------
In .cfg:
var hwiParams = new halHwi.Params();
/* DMA Hwi for the SPIUSCI driver */
hwiParams.arg = 0;
halHwi.create(50, "&MSP_EXP430F5529LP_isrDMA", hwiParams);
------------------------------
My Code:
/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>
/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
//#include <ti/drivers/SDSPI.h>
#include <ti/drivers/SPI.h>
/* Board Header file */
#include "Board.h"
#include "driverlib.h"
#define TASKSTACKSIZE 2048
Task_Struct spi_master_taskStruct;
Char spi_master_taskStack[TASKSTACKSIZE];
Void spi_master_taskFxn(UArg arg0, UArg arg1)
{
SPI_Handle spi_master;
SPI_Params spi_master_Params;
/* Create I2C for usage */
SPI_Params_init(&spi_master_Params);
spi_master_Params.transferMode = SPI_MODE_CALLBACK;
spi_master_Params.mode = SPI_MASTER;
spi_master_Params.bitRate = 1000000,
spi_master_Params.dataSize = 16;
//spi_master_Params.frameFormat = SPI_POL0_PHA0;
spi_master = SPI_open(Board_SPI0, &spi_master_Params);
if (spi_master == NULL) System_abort("Error Initializing SPI\n");
else System_printf("SPI Initialized!\n");
System_flush();
uint8_t txBuffer[16] = {0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,
0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0};
SPI_Transaction spiTransaction;
spiTransaction.txBuf = txBuffer;
spiTransaction.rxBuf = NULL;
spiTransaction.count = 16;
while(1) {
SPI_transfer(spi_master, &spiTransaction);
System_printf("SPI Bus transfer\n");
System_flush();
}
}
void main (void)
{
/* Call board init functions */
Board_initGeneral();
Board_initGPIO();
Board_initSPI();
//Construct heartBeat Task thread
Task_Params taskParams;
Task_Params_init(&taskParams);
//i2c master
taskParams.arg0 = 1000;
taskParams.stackSize = TASKSTACKSIZE;
taskParams.stack = &spi_master_taskStack;
Task_construct(&spi_master_taskStruct, (Task_FuncPtr)spi_master_taskFxn, &taskParams, NULL);
/* Start BIOS */
BIOS_start();
}
Hi Chester,
Thanks for your suggestion.
But I want to base on TI-RTOS system. Those examples are on NonOS.
I use SPI API, but it will stop on SPI_transfer(spi_master, &spiTransaction) API.
How should I solve it?
---------------------------
In .cfg:
var hwiParams = new halHwi.Params();
/* DMA Hwi for the SPIUSCI driver */
hwiParams.arg = 0;
halHwi.create(50, "&MSP_EXP430F5529LP_isrDMA", hwiParams);
------------------------------
My Code:
/* XDCtools Header files */ #include <xdc/std.h> #include <xdc/runtime/System.h> /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> /* TI-RTOS Header files */ #include <ti/drivers/GPIO.h> //#include <ti/drivers/SDSPI.h> #include <ti/drivers/SPI.h> /* Board Header file */ #include "Board.h" #include "driverlib.h" #define TASKSTACKSIZE 2048 Task_Struct spi_master_taskStruct; Char spi_master_taskStack[TASKSTACKSIZE]; Void spi_master_taskFxn(UArg arg0, UArg arg1) { SPI_Handle spi_master; SPI_Params spi_master_Params; /* Create I2C for usage */ SPI_Params_init(&spi_master_Params); spi_master_Params.transferMode = SPI_MODE_CALLBACK; spi_master_Params.mode = SPI_MASTER; spi_master_Params.bitRate = 1000000, spi_master_Params.dataSize = 16; //spi_master_Params.frameFormat = SPI_POL0_PHA0; spi_master = SPI_open(Board_SPI0, &spi_master_Params); if (spi_master == NULL) System_abort("Error Initializing SPI\n"); else System_printf("SPI Initialized!\n"); System_flush(); uint8_t txBuffer[16] = {0x1, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x1, 0x1, 0x0, 0x1, 0x1, 0x1, 0x0}; SPI_Transaction spiTransaction; spiTransaction.txBuf = txBuffer; spiTransaction.rxBuf = NULL; spiTransaction.count = 16; while(1) { SPI_transfer(spi_master, &spiTransaction); System_printf("SPI Bus transfer\n"); System_flush(); } } void main (void) { /* Call board init functions */ Board_initGeneral(); Board_initGPIO(); Board_initSPI(); //Construct heartBeat Task thread Task_Params taskParams; Task_Params_init(&taskParams); //i2c master taskParams.arg0 = 1000; taskParams.stackSize = TASKSTACKSIZE; taskParams.stack = &spi_master_taskStack; Task_construct(&spi_master_taskStruct, (Task_FuncPtr)spi_master_taskFxn, &taskParams, NULL); /* Start BIOS */ BIOS_start(); }
Hi Zheng,
Do you never see any traffic on your SPI Output?
If you set a breakpoint on your System_printf() call do you ever hit it?
I do see you have a call to Board_initSPI() I assume this is based off of the MSP_EXP430F5529LP_initSPI(); api?
Best Regards,
Brandon Fisher
Hi Brandon,
1. Do you never see any traffic on your SPI Output? >>> No. The SPI clock and SPI MOSI pin are not output any data.
2. If you set a breakpoint on your System_printf() call do you ever hit it? >>> No. It will stay SPI_transfer(spi_master, &spiTransaction);
3. Yes. #define Board_initSPI MSP_EXP430F5529LP_initSPI
Thanks.
Hi Zheng,
Can you try changing
spi_master_Params.transferMode = SPI_MODE_CALLBACK;
to
spi_master_Params.transferMode = SPI_MODE_BLOCKING;
Per the TI-RTOS User's Guide:
Best Regards,
Brandon Fisher
Hi Brandon,
I change to SPI_MODE_BLOCKING that will be ok. The system will not stay SPI_transfer(spi_master, &spiTransaction).
Can't setting SPI_MODE_CALLBACK is RTOS limitation, right?
Thanks.
Hi Zheng,
Can't setting SPI_MODE_CALLBACK is RTOS limitation, right?
I can't find anything that documents that as a known limitation in TI-RTOS, but the structure of your code as it is seems better suited to blocking mode. You while(1) loop would try to initiate multiple SPI transfers as its currently written if you use callback mode.
In Callback mode you must also have a defined callback function. Per the TI-RTOS User's Guide:
I believe this parameter will default to NULL if not defined. I'm not sure what exact behavior would result from using this in Callback mode with a NULL function pointer, but seeing your code hanging isn't out of the realm of possibility.
Best Regards,
Brandon Fisher
**Attention** This is a public forum