主题中讨论的其他器件: MSP430FR5969
我要尝试做的是、我使用寄存器级别(非基于 RTOS)对 MSP430FR5969进行了编程、并使用 TI-RTOS 对另一个 MCU - CC3235S 进行了编程。
我的目标是将数据从 MSP430 (主器件)传输到 CC3235S (从器件)、并从 CC3235S 接收数据。
我在 spimaster 和 spislave 示例中使用的相同方法是
第一个握手,然后准备主器件的 SPI,然后准备从器件的 SPI,当从器件指示 SPI_TRANSLT()值为 true 时,我从 MSP430发送数据。
但是,在使 SPI_TRANSF()正常后,由于数据传输 不正确,SPI 事务未正确进行。
我请求 TI 团队为我提供帮助。
代码-
MSP430
#include "driverlib.h"
#include <msp430.h>
int i,j;
char packet[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x7, 0x08, 0x09, 0x0A, 0x0B , 0x0C, 0x0D, 0x0E, 0x0F};
//char packet[] ={ 'Hello' , 'From', 'Tushar', 'Rathore', 'SAC'};
unsigned char position = 0;
char data = "HELLO ";
//char TxDATA[] ={ 'Hello' , 'From', 'Tushar', 'Rathore', 'SAC'};
int main(void)
{
WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer
FRCTL0 = FRCTLPW | NWAITS_1;
PM5CTL0 &= ~LOCKLPM5; // take out GPIO from LPM
// ----- Setup Button and LED
P1DIR |= BIT0; //P1.0 is set as output
P1OUT &= ~BIT0; //P1.0 is set at LOW
P4DIR |= BIT6; //P4.6 is set as output
P4OUT &= ~BIT6; //P4.6 is set at LOW
P1REN |= BIT1; //Internal Resistor enable @ P1.1
P1OUT |= BIT1; //Pull Up Resistor
P1IE |= BIT1; //Interrupt Enabled
P1IFG &= ~BIT1; //Interrupt Flag cleared
P1IES |= BIT1; //Interrupt Edge Selection HtoL
P1DIR |= BIT4; //P1.4 is set as output
P1OUT &= ~BIT4; //P1.4 is set at LOW
/* P3DIR &= ~BIT4; //P3.4 is set as input
P3REN |= BIT4; //Internal Resistor enable @ P3.4
P3OUT |= BIT4; //Pull Up Resistor
P3IE |= BIT4; //Interrupt Enabled
P3IFG &= ~BIT4; //Interrupt Flag cleared
P3IES &= ~BIT4; //Interrupt Edge Selection LtoH
*/
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P3,GPIO_PIN4);
GPIO_enableInterrupt(GPIO_PORT_P3,GPIO_PIN4); //Interrupt Enabled.
GPIO_clearInterrupt(GPIO_PORT_P3,GPIO_PIN4); //Interrupt Cleared.
GPIO_selectInterruptEdge(GPIO_PORT_P3,GPIO_PIN4,GPIO_HIGH_TO_LOW_TRANSITION); //Interrupt Edge Selection HtoL
// ----- Setup Clock
CSCTL0 = CSKEY; //CSKEY password. Must always be written with A5h
CSCTL1 = DCORSEL ; //DCO range select
CSCTL1 = DCOFSEL_0; //DCO frequency select
CSCTL2 = SELS__DCOCLK ; //Selects the SMCLK source
CSCTL3 = DIVS__1 ; // SMCLK Source Divider f(SMCLK)/1
CSCTL0_H = 0;
// ----- Setup SPI
UCB0CTLW0 |= UCSWRST ; // Unlock software reset
UCB0CTLW0 |=UCSTEM ;
UCB0CTLW0 |= UCSSEL__SMCLK; // SMCLK as clock source
UCB0CTLW0 |= UCSYNC; // Synchronous - SPI Mode
UCB0CTLW0 |= UCMODE_2; //
UCB0CTLW0 |= UCMST; // SPI Master Mode
UCB0CTLW0 &= ~UC7BIT; // 8 BIT Mode
UCB0CTLW0 |= UCMSB; // MSB First
UCB0CTLW0 |= UCCKPL; // Clock Polarity = 1
UCB0CTLW0 &= ~ UCCKPH; // Clock Phase = 0
UCB0BRW = 0x0010; // SMCLK/10
P1SEL1 |= BIT6; // P1.6 as MOSI Pin
P1SEL0 &= ~BIT6;
P1SEL1 |= BIT7; // P1.7 as MISO Pin
P1SEL0 &= ~BIT7;
P2SEL1 |= BIT2; // P2.2 as SCLK Pin
P2SEL0 &= ~BIT2;
UCB0CTLW0 &= ~UCSWRST ; // Lock software reset
UCB0IE |= UCTXIE; // Transmit interrupt enable
UCB0IFG &= ~UCTXIFG; // Clear Transmit interrupt flag
UCB0IE |= UCRXIE; // Transmit interrupt enable
UCB0IFG &= ~UCRXIFG; // Clear Transmit interrupt flag
while(!(GPIO_getInputPinValue(GPIO_PORT_P3,GPIO_PIN4))){}
GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN4);
GPIO_setOutputHighOnPin(GPIO_PORT_P1,GPIO_PIN0); //LED
// Handshake done
/*
for(i=0; i<100; i++){
while(GPIO_getInputPinValue(GPIO_PORT_P3,GPIO_PIN4)==1){}
// Slave is ready for transfer (wait for low)
if(UCTXIFG){
UCB0TXBUF = data ;
}
while(!UCRXIFG){}
for(j=0; j==1000; j++){}
P4OUT ^= BIT6; //Toggle the output @ P4.6
}
*/
__enable_interrupt();
while(1){}
}
#pragma vector = PORT3_VECTOR
__interrupt void PORT_3(void){
// Slave is ready for transfer (wait for low)
UCB0TXBUF = packet[i] ;
i++;
P1OUT ^= BIT0; //Toggle the output @ P1.0 (transfer completed)
P3IFG &= ~BIT4; //Interrupt Flag cleared
}
CC3235S
/* RTOS header files */
#include <ti/sysbios/BIOS.h>
#include <ti/drivers/Board.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
/* POSIX Header files */
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/SPI.h>
#include <ti/display/Display.h>
/* Driver configuration */
#include "ti_drivers_config.h"
#define THREADSTACKSIZE (1024)
#define SPI_MSG_LENGTH (30)
#define SLAVE_MSG ("Hello from Slave, msg#: ")
#define MAX_LOOP (10)
static Display_Handle display;
bool transferStatus;
sem_t slaveSem;
unsigned char slaveRxBuffer[SPI_MSG_LENGTH];
unsigned char slaveTxBuffer[SPI_MSG_LENGTH];
void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction);
void main(void)
{
SPI_Handle slaveSpi;
SPI_Params spiParams;
SPI_Transaction transaction;
uint32_t i;
bool transferOK;
int32_t status;
Board_init();
Display_init();
GPIO_init();
SPI_init();
display = Display_open(Display_Type_UART, NULL);
if (display == NULL) {
/* Failed to open display driver */
while (1);
}
Display_printf(display, 0, 0, "Starting the SPI slave example");
GPIO_setConfig(CONFIG_SPI_SLAVE_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_setConfig(CONFIG_SPI_MASTER_READY, GPIO_CFG_INPUT);
/*
* Handshake - Set CONFIG_SPI_SLAVE_READY high to indicate slave is ready
* to run. Wait for CONFIG_SPI_MASTER_READY to be high.
*/
GPIO_write(CONFIG_SPI_SLAVE_READY, 1);
while (GPIO_read(CONFIG_SPI_MASTER_READY) == 0) {}
Display_printf(display, 0, 0, "Handshake done !!");
status = sem_init(&slaveSem, 0, 0);
if (status != 0) {
Display_printf(display, 0, 0, "Error creating slaveSem\n");
while(1);
}
SPI_Params_init(&spiParams);
spiParams.frameFormat = SPI_POL1_PHA0;
spiParams.mode = SPI_SLAVE;
spiParams.transferCallbackFxn = transferCompleteFxn;
spiParams.transferMode = SPI_MODE_CALLBACK;
slaveSpi = SPI_open(CONFIG_SPI_SLAVE, &spiParams);
if (slaveSpi == NULL) {
Display_printf(display, 0, 0, "Error initializing slave SPI\n");
while (1);
}
else {
Display_printf(display, 0, 0, "Slave SPI initialized\n");
}
/* Copy message to transmit buffer */
//strncpy((char *) slaveTxBuffer, SLAVE_MSG, SPI_MSG_LENGTH);
for (i = 0; i < MAX_LOOP; i++) {
/* Initialize slave SPI transaction structure */
//slaveTxBuffer[sizeof(SLAVE_MSG) - 1] = (i % 10) + '0';
memset((void *) slaveRxBuffer, 0, SPI_MSG_LENGTH);
transaction.count = SPI_MSG_LENGTH;
//transaction.txBuf = (void *) slaveTxBuffer;
transaction.rxBuf = (void *) slaveRxBuffer;
/* Toggle on user LED, indicating a SPI transfer is in progress */
GPIO_toggle(CONFIG_GPIO_LED_1);
/*
* Setup SPI transfer; CONFIG_SPI_SLAVE_READY will be set to notify
* master the slave is ready.
*/
transferOK = SPI_transfer(slaveSpi, &transaction);
if (transferOK) {
Display_printf(display, 0, 0, "Transfer OK : Ready to receive ");
GPIO_write(CONFIG_SPI_SLAVE_READY, 0);
Display_printf(display, 0, 0, "sem_wait");
sem_wait(&slaveSem);
// callback function will be called
GPIO_write(CONFIG_SPI_SLAVE_READY, 1);
if (transferStatus == false) {
Display_printf(display, 0, 0, "SPI transfer failed!");
}
else {
Display_printf(display, 0, 0, "Slave received: %s",
slaveRxBuffer);
}
}
else {
Display_printf(display, 0, 0, "Unsuccessful slave SPI transfer");
}
}
SPI_close(slaveSpi);
/* Example complete - set pins to a known state */
GPIO_setConfig(CONFIG_SPI_MASTER_READY, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW);
GPIO_write(CONFIG_SPI_SLAVE_READY, 0);
Display_printf(display, 0, 0, "\nDone");
return (NULL);
}
void transferCompleteFxn(SPI_Handle handle, SPI_Transaction *transaction)
{
Display_printf(display, 0, 0, "callback fcn called : sem_post");
if (transaction->status != SPI_TRANSFER_COMPLETED) {
transferStatus = false;
}
else {
transferStatus = true;
}
sem_post(&slaveSem);
}
从器件侧的结果-
开始 SPI 从器件示例
握手完成!!
从器件 SPI 已初始化
传输正常:准备接收
SEM_WAIT
SPI 传输失败!
从器件 SPI 传输失败
从器件 SPI 传输失败
从器件 SPI 传输失败
从器件 SPI 传输失败
从器件 SPI 传输失败
从器件 SPI 传输失败
从器件 SPI 传输失败
从器件 SPI 传输失败
从器件 SPI 传输失败
完成