cc2538 SPI 数据传输问题

Other Parts Discussed in Thread: CC2538

我的project 是用CC2538作为处理器,读取MEMS sensor 的数据。原理是这样的:

CC2538首先发送一组数据到MEMS通过MOSI线,然后MEMS返回一组数据通过MISO线。

我想用TI的driver library 编程,我修改了他的example 代码,


#include <stdbool.h>
#include <stdint.h>
#include "hw_memmap.h"
#include "hw_ioc.h"
#include "gpio.h"
#include "ioc.h"
#include "ssi.h"
#include "uart.h"
#include "sys_ctrl.h"
#include "uartstdio.h"
#include "sensor.h"



//! This example shows how to configure the SSI0 as SPI Master.  The code will
//! send three characters on the master Tx then polls the receive FIFO until
//! 3 characters are received on the master Rx.
//!
//! This example uses the following peripherals and I/O signals.  You must
//! review these and change as needed for your own board:
//! - SSI0 peripheral
//! - GPIO Port A peripheral (for SSI0 pins)
//! - SSI0Clk - PA2
//! - SSI0Fss - PA3
//! - SSI0Rx  - PA4
//! - SSI0Tx  - PA5
//!
//! The following UART signals are configured only for displaying console
//! messages for this example.  These are not required for operation of SSI0.
//! - UART0 peripheral
//! - GPIO Port A peripheral (for UART0 pins)
//! - UART0RX - PA0
//! - UART0TX - PA1
//!
//! This example uses the following interrupt handlers.  To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - None.
//
//*****************************************************************************
                                                       
                                                        //  --------- --|------------------
#define EXAMPLE_PIN_SSI_CLK             GPIO_PIN_2   
#define EXAMPLE_PIN_SSI_FSS             GPIO_PIN_3    
#define EXAMPLE_PIN_SSI_RX              GPIO_PIN_4    
#define EXAMPLE_PIN_SSI_TX              GPIO_PIN_5     
#define EXAMPLE_GPIO_SSI_BASE           GPIO_A_BASE
    
#define EXAMPLE_PIN_UART_RXD            GPIO_PIN_0
#define EXAMPLE_PIN_UART_TXD            GPIO_PIN_1
#define EXAMPLE_GPIO_UART_BASE          GPIO_A_BASE

#define ADRESS_WORD_GYRO                (1 << 0)
#define ZERO_VECTOR                     (1 << 0)

//*****************************************************************************
//
// This function sets up UART0 to be used for a console to display information
// as the example is running.
//
//*****************************************************************************
void
InitConsole(void)
{
    //
    // Map UART signals to the correct GPIO pins and configure them as
    // hardware controlled.
    //
    IOCPinConfigPeriphOutput(EXAMPLE_GPIO_UART_BASE, EXAMPLE_PIN_UART_TXD,
                             IOC_MUX_OUT_SEL_UART0_TXD);
    GPIOPinTypeUARTOutput(EXAMPLE_GPIO_UART_BASE, EXAMPLE_PIN_UART_TXD);
    
    IOCPinConfigPeriphInput(EXAMPLE_GPIO_UART_BASE, EXAMPLE_PIN_UART_RXD,
                            IOC_UARTRXD_UART0);
    GPIOPinTypeUARTInput(EXAMPLE_GPIO_UART_BASE, EXAMPLE_PIN_UART_RXD);
     
    //
    // Initialize the UART (UART0) for console I/O.
    //
    UARTStdioInit(0);
}

//*****************************************************************************
//
// Configure SSI0 in master Freescale (SPI) mode.  This example will send out
// 3 bytes of data, then wait for 3 bytes of data to come in.  This will all be
// done using the polling method.
//
//*****************************************************************************


int
main(void)
{


    // Set the clocking to run directly from the external crystal/oscillator.
    // (no ext 32k osc, no internal osc)
    //
    SysCtrlClockSet(false, false, SYS_CTRL_SYSDIV_32MHZ);

    //
    // Set IO clock to the same as system clock
    //
    SysCtrlIOClockSet(SYS_CTRL_SYSDIV_32MHZ);
   
    //
    // Set up the serial console to use for displaying messages.  This is
    // just for this example program and is not needed for SSI operation.
    //
    InitConsole();
    
    //
    // Display the setup on the console.
    //
 //
    // The SSI0 peripheral must be enabled for use.
    
    //*************  Step 1 ******************** P123

    SysCtrlPeripheralEnable(SYS_CTRL_PERIPH_SSI0);

    //
    // Disable SSI function before configuring module
    //
    SSIDisable(SSI0_BASE);

    //
    // Set IO clock as SSI clock source
    //
    SSIClockSourceSet(SSI0_BASE, SSI_CLOCK_PIOSC);

    //
    // For this example SSI0 is used with PA2-PA5.  The actual port and pins
    // used may be different on your part, consult the data sheet for more
    // information.  GPIO port A needs to be enabled so these pins can be used.
    // TODO: change this to whichever GPIO port you are using.
    //
    // Configure the pin muxing for SSI0 functions on port A2, A3, A4, and A5.
    // This step is not necessary if your part does not support pin muxing.
    // TODO: change this to select the port/pin you are using.
    //

    IOCPinConfigPeriphOutput(EXAMPLE_GPIO_SSI_BASE, EXAMPLE_PIN_SSI_CLK,
                             IOC_MUX_OUT_SEL_SSI0_CLKOUT);    

    IOCPinConfigPeriphOutput(EXAMPLE_GPIO_SSI_BASE, EXAMPLE_PIN_SSI_FSS,
                             IOC_MUX_OUT_SEL_SSI0_FSSOUT);
    
    IOCPinConfigPeriphOutput(EXAMPLE_GPIO_SSI_BASE, EXAMPLE_PIN_SSI_TX,
                             IOC_MUX_OUT_SEL_SSI0_TXD);    
    
    IOCPinConfigPeriphInput(EXAMPLE_GPIO_SSI_BASE, EXAMPLE_PIN_SSI_RX,
                            IOC_SSIRXD_SSI0);    
    //
    // Configure the GPIO settings for the SSI pins.  This function also gives
    // control of these pins to the SSI hardware.  Consult the data sheet to
    // see which functions are allocated per pin.
    // The pins are assigned as follows:
    //      PA5 - SSI0Tx
    //      PA4 - SSI0Rx
    //      PA3 - SSI0Fss
    //      PA2 - SSI0CLK
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypeSSI(EXAMPLE_GPIO_SSI_BASE, EXAMPLE_PIN_SSI_CLK |
                   EXAMPLE_PIN_SSI_FSS | EXAMPLE_PIN_SSI_RX |
                   EXAMPLE_PIN_SSI_TX);

    //
    // Configure SSI module to Motorola/Freescale SPI mode 1:
    // Polarity  = 0, SCK steady state is high
    // Phase     = 0, Data changed on first and captured on second clock edge
    // Word size = 16 bits
    //
    SSIConfigSetExpClk(SSI0_BASE, SysCtrlIOClockGet(), SSI_FRF_MOTO_MODE_0,
                       SSI_MODE_MASTER, 115200, 8);
    
    //
    // Enable the SSI0 module.
    //
    SSIEnable(SSI0_BASE);

    //
    // Read any residual data from the SSI port.  This makes sure the receive
    // FIFOs are empty, so we don't read any unwanted junk.  This is done here
    // because the SPI SSI mode is full-duplex, which allows you to send and
    // receive at the same time.  The SSIDataGetNonBlocking function returns
    // "true" when data was returned, and "false" when no data was returned.
    // The "non-blocking" function checks if there is any data in the receive
    // FIFO and does not "hang" if there isn't.
    
   UARTprintf("****************OUTPUT**************\n");

   
  while(1){
     SSIDataPut (SSI0_BASE, ADRESS_WORD_GYRO);
     SSIDataPut (SSI0_BASE, 0x0001);
     SSIDataGet (SSI0_BASE, &i);
     UARTprintf("  RECEIVE",&i);
    SSIDataPut (SSI0_BASE, ADRESS_WORD_GYRO);
    SSIDataGet (SSI0_BASE, &i);
 
    UARTprintf("  HI\n\n",&i);
      
    //
    // Display indication that the SSI is transmitting data.
    //
   //UARTprintf("Sent:\n  ",*(uint32_t*) pui32Data);
   }

}