Hi Team,
My customer want to add SPI master function to project zero[TI-RTOS], but failed. His code is showed as follows:
1.The original SPI master demo:
/*
* Handshake - Set Board_SPI_MASTER_READY high to indicate master is ready
* to run. Wait Board_SPI_SLAVE_READY to be high.
*/
GPIO_write(Board_SPI_MASTER_READY, 1);
while (GPIO_read(Board_SPI_SLAVE_READY) == 0) {}
/* Handshake complete; now configure interrupt on Board_SPI_SLAVE_READY */
GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
GPIO_setCallback(Board_SPI_SLAVE_READY, slaveReadyFxn);
GPIO_enableInt(Board_SPI_SLAVE_READY);
/*
* Create synchronization semaphore; the master will wait on this semaphore
* until the slave is ready.
*/
status = sem_init(&masterSem, 0, 0);
if (status != 0) {
Display_printf(display, 0, 0, "Error creating masterSem\n");
while(1);
}
/* Open SPI as master (default) */
SPI_Params_init(&spiParams);
spiParams.frameFormat = SPI_POL0_PHA1;
spiParams.bitRate = 4000000;
masterSpi = SPI_open(Board_SPI_MASTER, &spiParams);
if (masterSpi == NULL) {
Display_printf(display, 0, 0, "Error initializing master SPI\n");
while (1);
}
else {
Display_printf(display, 0, 0, "Master SPI initialized\n");
}
/*
* Master has opened Board_SPI_MASTER; set Board_SPI_MASTER_READY high to
* inform the slave.
*/
GPIO_write(Board_SPI_MASTER_READY, 0);
/* Copy message to transmit buffer */
strncpy((char *) masterTxBuffer, MASTER_MSG, SPI_MSG_LENGTH);
for (i = 0; i < MAX_LOOP; i++) {
/*
* Wait until slave is ready for transfer; slave will pull
* Board_SPI_SLAVE_READY low.
*/
sem_wait(&masterSem);
/* Initialize master SPI transaction structure */
masterTxBuffer[sizeof(MASTER_MSG) - 1] = (i % 10) + '0';
memset((void *) masterRxBuffer, 0, SPI_MSG_LENGTH);
transaction.count = SPI_MSG_LENGTH;
transaction.txBuf = (void *) masterTxBuffer;
transaction.rxBuf = (void *) masterRxBuffer;
/* Toggle user LED, indicating a SPI transfer is in progress */
GPIO_toggle(Board_GPIO_LED1);
/* Perform SPI transfer */
transferOK = SPI_transfer(masterSpi, &transaction);
if (transferOK) {
Display_printf(display, 0, 0, "Master received: %s", masterRxBuffer);
}
else {
Display_printf(display, 0, 0, "Unsuccessful master SPI transfer");
}
/* Sleep for a bit before starting the next SPI transfer */
sleep(3);
}
SPI_close(masterSpi);
/* Example complete - set pins to a known state */
GPIO_disableInt(Board_SPI_SLAVE_READY);
GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_write(Board_SPI_MASTER_READY, 0);
Display_printf(display, 0, 0, "\nDone");
Display_printf(display, 0, 0, "count= %d", count);
return (NULL);
}
/*
* ======== mainThread ========
*/
void *mainThread(void *arg0)
{
pthread_t thread0;
pthread_attr_t attrs;
struct sched_param priParam;
int retc;
int detachState;
/* Call driver init functions. */
Display_init();
GPIO_init();
SPI_init();
/* Configure the LED pins */
GPIO_setConfig(Board_GPIO_LED0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
GPIO_setConfig(Board_GPIO_LED1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
/* Open the display for output */
display = Display_open(Display_Type_UART, NULL);
if (display == NULL) {
/* Failed to open display driver */
while (1);
}
/* Turn on user LED */
GPIO_write(Board_GPIO_LED0, Board_GPIO_LED_ON);
Display_printf(display, 0, 0, "Starting the SPI master example");
Display_printf(display, 0, 0, "This example requires external wires to be "
"connected to the header pins. Please see the Board.html for details.\n");
/* Create application threads */
pthread_attr_init(&attrs);
detachState = PTHREAD_CREATE_DETACHED;
/* Set priority and stack size attributes */
retc = pthread_attr_setdetachstate(&attrs, detachState);
if (retc != 0) {
/* pthread_attr_setdetachstate() failed */
while (1);
}
retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
if (retc != 0) {
/* pthread_attr_setstacksize() failed */
while (1);
}
/* Create master thread */
priParam.sched_priority = 1;
pthread_attr_setschedparam(&attrs, &priParam);
retc = pthread_create(&thread0, &attrs, masterThread, NULL);
if (retc != 0) {
/* pthread_create() failed */
while (1);
}
return (NULL);
}
/***********************************************************************************/
2、The demo porting to project zero, the change is mostly about modifying sem function to Semaphore function:
static void Spimaster_taskFxn(UArg a0, UArg a1)
{
SPI_Handle masterSpi;
SPI_Params spiParams;
SPI_Transaction transaction;
uint32_t i;
bool transferOK;
int32_t status;
bool isSuccessful;
/*
* Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY are GPIO pins connected
* between the master & slave. These pins are used to synchronize
* the master & slave applications via a small 'handshake'. The pins
* are later used to synchronize transfers & ensure the master will not
* start a transfer until the slave is ready. These pins behave
* differently between spimaster & spislave examples:
*
* spimaster example:
* * Board_SPI_MASTER_READY is configured as an output pin. During the
* 'handshake' this pin is changed from low to high output. This
* notifies the slave the master is ready to run the application.
* Afterwards, the pin is used by the master to notify the slave it
* has opened Board_SPI_MASTER. When Board_SPI_MASTER is opened, this
* pin will be pulled low.
*
* * Board_SPI_SLAVE_READY is configured as an input pin. During the
* 'handshake' this pin is read & a high value will indicate the slave
* ready to run the application. Afterwards, a falling edge interrupt
* will be configured on this pin. When the slave is ready to perform
* a transfer, it will pull this pin low.
*
* Below we set Board_SPI_MASTER_READY & Board_SPI_SLAVE_READY initial
* conditions for the 'handshake'.
*/
GPIO_init();
SPI_init();
GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_INPUT);
/*
* Handshake - Set Board_SPI_MASTER_READY high to indicate master is ready
* to run. Wait Board_SPI_SLAVE_READY to be high.
*/
GPIO_write(Board_SPI_MASTER_READY, 1);
Log_info0("Board_SPI_MASTER_READY\n");
while (GPIO_read(Board_SPI_SLAVE_READY) == 0) { Log_info0("wait Board_SPI_SLAVE_READY\n");}
/* Handshake complete; now configure interrupt on Board_SPI_SLAVE_READY */
GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
GPIO_setCallback(Board_SPI_SLAVE_READY, slaveReadyFxn);
GPIO_enableInt(Board_SPI_SLAVE_READY);
/*
* Create synchronization semaphore; the master will wait on this semaphore
* until the slave is ready.
*/
/* Open SPI as master (default) */
Semaphore_Params_init(&semParams);
sem = Semaphore_create(0, &semParams, NULL); // allocate memory
if (sem == NULL) // check if the returned handle is valid
{
Log_info0("Error creating masterSem\n");
// System_abort("Semaphore could not be created");
}
spiParams.frameFormat = SPI_POL0_PHA1;
spiParams.bitRate = 4000000;
masterSpi = SPI_open(Board_SPI_MASTER, &spiParams);
if (masterSpi == NULL) {
Log_info0("Error initializing master SPI\n");
//Display_printf(display, 0, 0, "Error initializing master SPI\n");
while (1);
}
else {
Log_info0("Master SPI initialized\n");
//Display_printf(display, 0, 0, "Master SPI initialized\n");
}
/*
* Master has opened Board_SPI_MASTER; set Board_SPI_MASTER_READY high to
* inform the slave.
*/
GPIO_write(Board_SPI_MASTER_READY, 0);
/* Copy message to transmit buffer */
strncpy((char *) masterTxBuffer, MASTER_MSG, SPI_MSG_LENGTH);
/*
* Wait until slave is ready for transfer; slave will pull
* Board_SPI_SLAVE_READY low.
*/
/*
if (isSuccessful)
{
//System_printf("Semaphore was posted");
Log_info0("Semaphore was posted\n");
}
else{
// System_printf("Semaphore timed out");
Log_info0("Semaphore timed out\n");
}
*/
for (i = 0; i < MAX_LOOP; i++) {
// while (GPIO_read(Board_SPI_SLAVE_READY) == 1) { Log_info0("wait Board_SPI_SLAVE\n");}
Semaphore_pend(sem, BIOS_WAIT_FOREVER);
/* Initialize master SPI transaction structure */
masterTxBuffer[sizeof(MASTER_MSG) - 1] = (i % 10) + '0';
memset((void *) masterRxBuffer, 0, SPI_MSG_LENGTH);
transaction.count = SPI_MSG_LENGTH;
transaction.txBuf = (void *) masterTxBuffer;
transaction.rxBuf = (void *) masterRxBuffer;
/* Toggle user LED, indicating a SPI transfer is in progress */
GPIO_toggle(Board_GPIO_LED1);
/* Perform SPI transfer */
transferOK = SPI_transfer(masterSpi, &transaction);
if (transferOK) {
Log_info1( "Master received: %s", masterRxBuffer);
}
else {
Log_info0( "Unsuccessful master SPI transfer");
}
/* Sleep for a bit before starting the next SPI transfer */
// sleep(3);
Task_sleep(3000);
}
SPI_close(masterSpi);
/* Example complete - set pins to a known state */
GPIO_disableInt(Board_SPI_SLAVE_READY);
GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_write(Board_SPI_MASTER_READY, 0);
Log_info0("\nDone");
return ;
}
/***main.c:*********/
ProjectZero_createTask();
/*********project.zero.c*********/
void ProjectZero_createTask(void)
{
Task_Params taskParams;
// Configure task
Task_Params_init(&taskParams);
taskParams.stack = przTaskStack;
taskParams.stackSize = PRZ_TASK_STACK_SIZE;
taskParams.priority = PRZ_TASK_PRIORITY;
Task_construct(&przTask, Spimaster_taskFxn, &taskParams, NULL);
}
static void Spimaster_taskFxn(UArg a0, UArg a1)
{
SPI_Handle masterSpi;
SPI_Params spiParams;
SPI_Transaction transaction;
uint32_t i;
bool transferOK;
int32_t status;
GPIO_init();
SPI_init();
GPIO_setConfig(Board_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_INPUT);
GPIO_write(Board_SPI_MASTER_READY, 1);
Log_info0("Board_SPI_MASTER_READY\n");
while (GPIO_read(Board_SPI_SLAVE_READY) == 0) { Log_info0("wait Board_SPI_SLAVE_READY\n");}
/* Handshake complete; now configure interrupt on Board_SPI_SLAVE_READY */
GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_IN_PU | GPIO_CFG_IN_INT_FALLING);
GPIO_setCallback(Board_SPI_SLAVE_READY, slaveReadyFxn);
GPIO_enableInt(Board_SPI_SLAVE_READY);
/*
* Create synchronization semaphore; the master will wait on this semaphore
* until the slave is ready.
*/
/* Open SPI as master (default) */
//Semaphore_Params_init(&semParams);
sem = Semaphore_create(0, NULL, Error_IGNORE); // allocate memory
if (sem == NULL) // check if the returned handle is valid
{
Log_info0("Error creating masterSem\n");
// System_abort("Semaphore could not be created");
}
spiParams.frameFormat = SPI_POL0_PHA1;
spiParams.bitRate = 4000000;
masterSpi = SPI_open(Board_SPI_MASTER, &spiParams);
if (masterSpi == NULL) {
Log_info0("Error initializing master SPI\n");
//Display_printf(display, 0, 0, "Error initializing master SPI\n");
while (1);
}
else {
Log_info0("Master SPI initialized\n");
//Display_printf(display, 0, 0, "Master SPI initialized\n");
}
/*
* Master has opened Board_SPI_MASTER; set Board_SPI_MASTER_READY high to
* inform the slave.
*/
GPIO_write(Board_SPI_MASTER_READY, 0);
/* Copy message to transmit buffer */
strncpy((char *) masterTxBuffer, MASTER_MSG, SPI_MSG_LENGTH);
/*
* Wait until slave is ready for transfer; slave will pull
* Board_SPI_SLAVE_READY low.
*/
/*
if (isSuccessful)
{
//System_printf("Semaphore was posted");
Log_info0("Semaphore was posted\n");
}
else{
// System_printf("Semaphore timed out");
Log_info0("Semaphore timed out\n");
}
*/
for (i = 0; i < MAX_LOOP; i++) {
// while (GPIO_read(Board_SPI_SLAVE_READY) == 1) { Log_info0("wait Board_SPI_SLAVE\n");}
Semaphore_pend(sem, BIOS_WAIT_FOREVER);
/* Initialize master SPI transaction structure */
masterTxBuffer[sizeof(MASTER_MSG) - 1] = (i % 10) + '0';
memset((void *) masterRxBuffer, 0, SPI_MSG_LENGTH);
transaction.count = SPI_MSG_LENGTH;
transaction.txBuf = (void *) masterTxBuffer;
transaction.rxBuf = (void *) masterRxBuffer;
/* Toggle user LED, indicating a SPI transfer is in progress */
GPIO_toggle(Board_GPIO_LED1);
/* Perform SPI transfer */
transferOK = SPI_transfer(masterSpi, &transaction);
if (transferOK) {
Log_info1( "Master received: %s", masterRxBuffer);
}
else {
Log_info0( "Unsuccessful master SPI transfer");
}
/* Sleep for a bit before starting the next SPI transfer */
// sleep(3);
Task_sleep(3000);
}
SPI_close(masterSpi);
/* Example complete - set pins to a known state */
GPIO_disableInt(Board_SPI_SLAVE_READY);
GPIO_setConfig(Board_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_write(Board_SPI_MASTER_READY, 0);
Log_info0("\nDone");
return ;
}
3.He has two board downloaded spimaster & spislave respectively, and they worked fine. But after adding the spimaster to project_zero, the communication is unsuccessful. The only difference is spimaster uses posix while project_zero uses TI RTOS semaphore------Semaphore_create,Semaphore_pend,Semaphore_post. The modified code can not send data or receive data, any advice?
Best regards,
Viki