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.

spi double dma tcp send

Other Parts Discussed in Thread: CC3200SDK, CC3200

Hi  do you have an example about how to use pingpang dma get data and send data via wifi to sta.

  • 您现在使用的是CC3200?SDK安装文件夹内的 CC3200SDK_1.4.0\cc3200-sdk\example\udma 例程是 pingpang模式,您可以参考一下
  • 我用spi的双·DMA收取数据,然后在AP模式下,用TCP发出去,一调用sl_send程序就耗死了,不知道发生了什么。

  • //*****************************************************************************
    //
    // Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
    //
    //
    // Redistribution and use in source and binary forms, with or without
    // modification, are permitted provided that the following conditions
    // are met:
    //
    // Redistributions of source code must retain the above copyright
    // notice, this list of conditions and the following disclaimer.
    //
    // Redistributions in binary form must reproduce the above copyright
    // notice, this list of conditions and the following disclaimer in the
    // documentation and/or other materials provided with the
    // distribution.
    //
    // Neither the name of Texas Instruments Incorporated nor the names of
    // its contributors may be used to endorse or promote products derived
    // from this software without specific prior written permission.
    //
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    //
    //*****************************************************************************


    //*****************************************************************************
    //
    // Application Name - Getting started with WLAN AP
    // Application Overview - This application aims to exhibit the CC3200 device as
    // AP. Developers/users can refer the function or re-use
    // them while writing new application.
    //
    //*****************************************************************************


    //****************************************************************************
    //
    //! \addtogroup getting_started_ap
    //! @{
    //
    //****************************************************************************
    #if 1
    #include <stdlib.h>
    #include <string.h>

    // Simplelink includes
    #include "simplelink.h"

    // driverlib includes
    #include "hw_types.h"
    #include "hw_ints.h"
    #include "rom.h"
    #include "rom_map.h"
    #include "interrupt.h"
    #include "prcm.h"
    #include "utils.h"

    // free_rtos/ti-rtos includes
    #include "osi.h"


    // common interface includes
    #include "common.h"
    #ifndef NOTERM
    #include "uart_if.h"
    #endif
    #include "pinmux.h"


    #include "spi.h"
    #include "rom.h"
    #include "rom_map.h"
    #include "hw_types.h"
    #include "hw_memmap.h"
    #include "spi_common.h"


    #define APP_NAME "WLAN AP"
    #define APPLICATION_VERSION "1.4.0"
    #define OSI_STACK_SIZE 2048


    //
    // Values for below macros shall be modified for setting the 'Ping' properties
    //
    #define PING_INTERVAL 1000 /* In msecs */
    #define PING_TIMEOUT 3000 /* In msecs */
    #define PING_PKT_SIZE 20 /* In bytes */
    #define NO_OF_ATTEMPTS 3
    #define PING_FLAG 0

    #define IP_ADDR 0xc0a80064 /* 192.168.0.100 */
    #define PORT_NUM 5001
    #define BUF_SIZE 1400
    #define TCP_PACKET_COUNT 1000

    #define MASTER_MODE 0

    #define SPI_IF_BIT_RATE 500000
    #define TR_BUFF_SIZE 100


    // Application specific status/error codes
    typedef enum{
    // Choosing -0x7D0 to avoid overlap w/ host-driver's error codes
    SOCKET_CREATE_ERROR = -0x7D0,
    LAN_CONNECTION_FAILED = SOCKET_CREATE_ERROR -1,
    CLIENT_CONNECTION_FAILED = LAN_CONNECTION_FAILED - 1,
    DEVICE_NOT_IN_STATION_MODE = CLIENT_CONNECTION_FAILED - 1,
    BIND_ERROR = DEVICE_NOT_IN_STATION_MODE - 1,
    LISTEN_ERROR = BIND_ERROR -1,
    SOCKET_OPT_ERROR = LISTEN_ERROR -1,
    CONNECT_ERROR = SOCKET_OPT_ERROR -1,
    ACCEPT_ERROR = CONNECT_ERROR - 1,
    SEND_ERROR = ACCEPT_ERROR -1,
    RECV_ERROR = SEND_ERROR -1,
    SOCKET_CLOSE_ERROR = RECV_ERROR -1,
    //DEVICE_NOT_IN_STATION_MODE = SOCKET_CLOSE_ERROR - 1,
    STATUS_CODE_MAX = -0xBB8
    }e_AppStatusCodes;

    //*****************************************************************************
    // GLOBAL VARIABLES -- Start
    //*****************************************************************************
    unsigned char g_ulStatus = 0;
    unsigned long g_ulStaIp = 0;
    unsigned long g_ulPingPacketsRecv = 0;
    unsigned long g_uiGatewayIP = 0;


    static unsigned char g_ucTxBuff[TR_BUFF_SIZE];
    static unsigned char g_ucRxBufA[DMA_SIZE];
    static unsigned char g_ucRxBufB[DMA_SIZE];
    static unsigned char g_ucRxBufA_tmp[DMA_SIZE];
    static unsigned char g_ucRxBufB_tmp[DMA_SIZE];
    static unsigned char ucTxBuffNdx;
    static unsigned char ucRxBuffNdx;

    #define MASTER_MSG "This is CC3200 SPI Master Application\n\r"
    #define SLAVE_MSG "This is CC3200 SPI Slave Application\n\r"

    #define DHCP_START_IP SL_IPV4_VAL(192,168,0,100) /* DHCP start IP address */
    #define DHCP_END_IP SL_IPV4_VAL(192,168,0,200) /* DHCP End IP address */

    #define IP_LEASE_TIME 3600


    unsigned long g_ulGatewayIP = 0; //Network Gateway IP address
    unsigned char g_ucConnectionSSID[SSID_LEN_MAX+1]; //Connection SSID
    unsigned char g_ucConnectionBSSID[BSSID_LEN_MAX]; //Connection BSSID
    unsigned long g_ulDestinationIp = IP_ADDR;
    unsigned int g_uiPortNum = PORT_NUM;
    volatile unsigned long g_ulPacketCount = TCP_PACKET_COUNT;
    unsigned char g_ucConnectionStatus = 0;
    unsigned char g_ucSimplelinkstarted = 0;
    unsigned long g_ulIpAddr = 0;
    char g_cBsdBuf[BUF_SIZE];

    unsigned long ulRecvData;
    int iNewSockID;

    #if defined(gcc)
    extern void (* const g_pfnVectors[])(void);
    #endif
    #if defined(ewarm)
    extern uVectorEntry __vector_table;
    #endif
    //*****************************************************************************
    // GLOBAL VARIABLES -- End
    //*****************************************************************************



    //****************************************************************************
    // LOCAL FUNCTION PROTOTYPES
    //****************************************************************************
    static int PingTest(unsigned long ulIpAddr);
    static long ConfigureSimpleLinkToDefaultState();
    static void InitializeAppVariables();
    static int GetSsidName(char *pcSsidName, unsigned int uiMaxLen);
    int issendA=0;
    int issendB=0;

    static uint8_t rx_buffer_tmp[DMA_SIZE];
    uint8_t rx_buffer[DMA_SIZE];


    #ifdef USE_FREERTOS
    //*****************************************************************************
    // FreeRTOS User Hook Functions enabled in FreeRTOSConfig.h
    //*****************************************************************************

    //*****************************************************************************
    //
    //! \brief Application defined hook (or callback) function - assert
    //!
    //! \param[in] pcFile - Pointer to the File Name
    //! \param[in] ulLine - Line Number
    //!
    //! \return none
    //!
    //*****************************************************************************
    void
    vAssertCalled( const char *pcFile, unsigned long ulLine )
    {
    //Handle Assert here
    while(1)
    {
    }
    }

    //*****************************************************************************
    //
    //! \brief Application defined idle task hook
    //!
    //! \param none
    //!
    //! \return none
    //!
    //*****************************************************************************
    void
    vApplicationIdleHook( void)
    {
    //Handle Idle Hook for Profiling, Power Management etc
    }

    //*****************************************************************************
    //
    //! \brief Application defined malloc failed hook
    //!
    //! \param none
    //!
    //! \return none
    //!
    //*****************************************************************************
    void vApplicationMallocFailedHook()
    {
    //Handle Memory Allocation Errors
    while(1)
    {
    }
    }

    //*****************************************************************************
    //
    //! \brief Application defined stack overflow hook
    //!
    //! \param none
    //!
    //! \return none
    //!
    //*****************************************************************************
    void vApplicationStackOverflowHook(OsiTaskHandle *pxTask,
    signed char *pcTaskName)
    {
    //Handle FreeRTOS Stack Overflow
    while(1)
    {
    }
    }
    #endif //USE_FREERTOS


    //*****************************************************************************
    // SimpleLink Asynchronous Event Handlers -- Start
    //*****************************************************************************


    //*****************************************************************************
    //
    //! On Successful completion of Wlan Connect, This function triggers Connection
    //! status to be set.
    //!
    //! \param pSlWlanEvent pointer indicating Event type
    //!
    //! \return None
    //!
    //*****************************************************************************
    void SimpleLinkWlanEventHandler(SlWlanEvent_t *pSlWlanEvent)
    {
    switch(pSlWlanEvent->Event)
    {
    case SL_WLAN_CONNECT_EVENT:
    {
    SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);

    //
    // Information about the connected AP (like name, MAC etc) will be
    // available in 'slWlanConnectAsyncResponse_t'-Applications
    // can use it if required
    //
    // slWlanConnectAsyncResponse_t *pEventData = NULL;
    // pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected;
    //
    //
    }
    break;

    case SL_WLAN_DISCONNECT_EVENT:
    {
    slWlanConnectAsyncResponse_t* pEventData = NULL;

    CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
    CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_AQUIRED);

    pEventData = &pSlWlanEvent->EventData.STAandP2PModeDisconnected;

    // If the user has initiated 'Disconnect' request,
    //'reason_code' is SL_WLAN_DISCONNECT_USER_INITIATED_DISCONNECTION
    if(SL_WLAN_DISCONNECT_USER_INITIATED_DISCONNECTION == pEventData->reason_code)
    {
    UART_PRINT("Device disconnected from the AP on application's "
    "request \n\r");
    }
    else
    {
    UART_PRINT("Device disconnected from the AP on an ERROR..!! \n\r");
    }

    }
    break;

    case SL_WLAN_STA_CONNECTED_EVENT:
    {
    // when device is in AP mode and any client connects to device cc3xxx
    SET_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);

    //
    // Information about the connected client (like SSID, MAC etc) will be
    // available in 'slPeerInfoAsyncResponse_t' - Applications
    // can use it if required
    //
    // slPeerInfoAsyncResponse_t *pEventData = NULL;
    // pEventData = &pSlWlanEvent->EventData.APModeStaConnected;
    //

    }
    break;

    case SL_WLAN_STA_DISCONNECTED_EVENT:
    {
    // when client disconnects from device (AP)
    CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_CONNECTION);
    CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);

    //
    // Information about the connected client (like SSID, MAC etc) will
    // be available in 'slPeerInfoAsyncResponse_t' - Applications
    // can use it if required
    //
    // slPeerInfoAsyncResponse_t *pEventData = NULL;
    // pEventData = &pSlWlanEvent->EventData.APModestaDisconnected;
    //
    }
    break;

    default:
    {
    UART_PRINT("[WLAN EVENT] Unexpected event \n\r");
    }
    break;
    }
    }

    //*****************************************************************************
    //
    //! \brief This function handles network events such as IP acquisition, IP
    //! leased, IP released etc.
    //!
    //! \param[in] pNetAppEvent - Pointer to NetApp Event Info
    //!
    //! \return None
    //!
    //*****************************************************************************
    void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
    {
    switch(pNetAppEvent->Event)
    {
    case SL_NETAPP_IPV4_IPACQUIRED_EVENT:
    case SL_NETAPP_IPV6_IPACQUIRED_EVENT:
    {
    SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_AQUIRED);
    }
    break;

    case SL_NETAPP_IP_LEASED_EVENT:
    {
    SET_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);

    g_ulStaIp = (pNetAppEvent)->EventData.ipLeased.ip_address;

    UART_PRINT("[NETAPP EVENT] IP Leased to Client: IP=%d.%d.%d.%d , ",
    SL_IPV4_BYTE(g_ulStaIp,3), SL_IPV4_BYTE(g_ulStaIp,2),
    SL_IPV4_BYTE(g_ulStaIp,1), SL_IPV4_BYTE(g_ulStaIp,0));
    }
    break;

    case SL_NETAPP_IP_RELEASED_EVENT:
    {
    CLR_STATUS_BIT(g_ulStatus, STATUS_BIT_IP_LEASED);

    UART_PRINT("[NETAPP EVENT] IP Released for Client: IP=%d.%d.%d.%d , ",
    SL_IPV4_BYTE(g_ulStaIp,3), SL_IPV4_BYTE(g_ulStaIp,2),
    SL_IPV4_BYTE(g_ulStaIp,1), SL_IPV4_BYTE(g_ulStaIp,0));

    }
    break;

    default:
    {
    UART_PRINT("[NETAPP EVENT] Unexpected event [0x%x] \n\r",
    pNetAppEvent->Event);
    }
    break;
    }
    }


    //*****************************************************************************
    //
    //! \brief This function handles HTTP server events
    //!
    //! \param[in] pServerEvent - Contains the relevant event information
    //! \param[in] pServerResponse - Should be filled by the user with the
    //! relevant response information
    //!
    //! \return None
    //!
    //****************************************************************************
    void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent,
    SlHttpServerResponse_t *pHttpResponse)
    {
    // Unused in this application
    }

    //*****************************************************************************
    //
    //! \brief This function handles General Events
    //!
    //! \param[in] pDevEvent - Pointer to General Event Info
    //!
    //! \return None
    //!
    //*****************************************************************************
    void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
    {
    //
    // Most of the general errors are not FATAL are are to be handled
    // appropriately by the application
    //
    UART_PRINT("[GENERAL EVENT] - ID=[%d] Sender=[%d]\n\n",
    pDevEvent->EventData.deviceEvent.status,
    pDevEvent->EventData.deviceEvent.sender);
    }


    //*****************************************************************************
    //
    //! This function handles socket events indication
    //!
    //! \param[in] pSock - Pointer to Socket Event Info
    //!
    //! \return None
    //!
    //*****************************************************************************
    void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
    {
    //
    // This application doesn't work w/ socket - Events are not expected
    //
    switch( pSock->Event )
    {
    case SL_SOCKET_TX_FAILED_EVENT:
    switch( pSock->socketAsyncEvent.SockTxFailData.status)
    {
    case SL_ECLOSE:
    UART_PRINT("[SOCK ERROR] - close socket (%d) operation "
    "failed to transmit all queued packets\n\n",
    pSock->socketAsyncEvent.SockTxFailData.sd);
    break;
    default:
    UART_PRINT("[SOCK ERROR] - TX FAILED : socket %d , reason "
    "(%d) \n\n",
    pSock->socketAsyncEvent.SockTxFailData.sd, pSock->socketAsyncEvent.SockTxFailData.status);
    break;
    }
    break;

    default:
    UART_PRINT("[SOCK EVENT] - Unexpected Event [%x0x]\n\n",pSock->Event);
    break;
    }

    }

    //*****************************************************************************
    //
    //! \brief This function handles ping report events
    //!
    //! \param[in] pPingReport - Ping report statistics
    //!
    //! \return None
    //
    //****************************************************************************
    void SimpleLinkPingReport(SlPingReport_t *pPingReport)
    {
    SET_STATUS_BIT(g_ulStatus, STATUS_BIT_PING_DONE);
    g_ulPingPacketsRecv = pPingReport->PacketsReceived;
    }

    //*****************************************************************************
    // SimpleLink Asynchronous Event Handlers -- End
    //*****************************************************************************


    //****************************************************************************
    //
    //! \brief This function initializes the application variables
    //!
    //! \param[in] None
    //!
    //! \return None
    //
    //****************************************************************************
    static void InitializeAppVariables()
    {
    g_ulStatus = 0;
    g_ulStaIp = 0;
    g_ulPingPacketsRecv = 0;
    g_uiGatewayIP = 0;
    }

    //*****************************************************************************
    //! \brief This function puts the device in its default state. It:
    //! - Set the mode to STATION
    //! - Configures connection policy to Auto and AutoSmartConfig
    //! - Deletes all the stored profiles
    //! - Enables DHCP
    //! - Disables Scan policy
    //! - Sets Tx power to maximum
    //! - Sets power policy to normal
    //! - Unregister mDNS services
    //! - Remove all filters
    //!
    //! \param none
    //! \return On success, zero is returned. On error, negative is returned
    //*****************************************************************************
    static long ConfigureSimpleLinkToDefaultState()
    {
    SlVersionFull ver = {0};
    _WlanRxFilterOperationCommandBuff_t RxFilterIdMask = {0};

    unsigned char ucVal = 1;
    unsigned char ucConfigOpt = 0;
    unsigned char ucConfigLen = 0;
    unsigned char ucPower = 0;

    long lRetVal = -1;
    long lMode = -1;

    lMode = sl_Start(0, 0, 0);
    ASSERT_ON_ERROR(lMode);

    // If the device is not in station-mode, try configuring it in station-mode
    if (ROLE_STA != lMode)
    {
    if (ROLE_AP == lMode)
    {
    // If the device is in AP mode, we need to wait for this event
    // before doing anything
    while(!IS_IP_ACQUIRED(g_ulStatus))
    {
    #ifndef SL_PLATFORM_MULTI_THREADED
    _SlNonOsMainLoopTask();
    #endif
    }
    }

    // Switch to STA role and restart
    lRetVal = sl_WlanSetMode(ROLE_STA);
    ASSERT_ON_ERROR(lRetVal);

    lRetVal = sl_Stop(0xFF);
    ASSERT_ON_ERROR(lRetVal);

    lRetVal = sl_Start(0, 0, 0);
    ASSERT_ON_ERROR(lRetVal);

    // Check if the device is in station again
    if (ROLE_STA != lRetVal)
    {
    // We don't want to proceed if the device is not coming up in STA-mode
    return DEVICE_NOT_IN_STATION_MODE;
    }
    }

    // Get the device's version-information
    ucConfigOpt = SL_DEVICE_GENERAL_VERSION;
    ucConfigLen = sizeof(ver);
    lRetVal = sl_DevGet(SL_DEVICE_GENERAL_CONFIGURATION, &ucConfigOpt,
    &ucConfigLen, (unsigned char *)(&ver));
    ASSERT_ON_ERROR(lRetVal);

    UART_PRINT("Host Driver Version: %s\n\r",SL_DRIVER_VERSION);
    UART_PRINT("Build Version %d.%d.%d.%d.31.%d.%d.%d.%d.%d.%d.%d.%d\n\r",
    ver.NwpVersion[0],ver.NwpVersion[1],ver.NwpVersion[2],ver.NwpVersion[3],
    ver.ChipFwAndPhyVersion.FwVersion[0],ver.ChipFwAndPhyVersion.FwVersion[1],
    ver.ChipFwAndPhyVersion.FwVersion[2],ver.ChipFwAndPhyVersion.FwVersion[3],
    ver.ChipFwAndPhyVersion.PhyVersion[0],ver.ChipFwAndPhyVersion.PhyVersion[1],
    ver.ChipFwAndPhyVersion.PhyVersion[2],ver.ChipFwAndPhyVersion.PhyVersion[3]);

    // Set connection policy to Auto + SmartConfig
    // (Device's default connection policy)
    lRetVal = sl_WlanPolicySet(SL_POLICY_CONNECTION,
    SL_CONNECTION_POLICY(1, 0, 0, 0, 1), NULL, 0);
    ASSERT_ON_ERROR(lRetVal);

    // Remove all profiles
    lRetVal = sl_WlanProfileDel(0xFF);
    ASSERT_ON_ERROR(lRetVal);



    //
    // Device in station-mode. Disconnect previous connection if any
    // The function returns 0 if 'Disconnected done', negative number if already
    // disconnected Wait for 'disconnection' event if 0 is returned, Ignore
    // other return-codes
    //
    lRetVal = sl_WlanDisconnect();
    if(0 == lRetVal)
    {
    // Wait
    while(IS_CONNECTED(g_ulStatus))
    {
    #ifndef SL_PLATFORM_MULTI_THREADED
    _SlNonOsMainLoopTask();
    #endif
    }
    }
    UART_PRINT("\n\rSet up static ip start\n");
    // Enable DHCP client
    lRetVal = sl_NetCfgSet(SL_IPV4_STA_P2P_CL_DHCP_ENABLE,1,1,&ucVal);
    ASSERT_ON_ERROR(lRetVal);
    /*SlNetCfgIpV4Args_t ipV4;
    ipV4.ipV4 = (_u32)SL_IPV4_VAL(10,1,1,201); // _u32 IP address
    ipV4.ipV4Mask = (_u32)SL_IPV4_VAL(255,255,255,0); // _u32 Subnet mask for this AP/P2P
    ipV4.ipV4Gateway = (_u32)SL_IPV4_VAL(10,1,1,1); // _u32 Default gateway address
    ipV4.ipV4DnsServer = (_u32)SL_IPV4_VAL(8,16,32,64); // _u32 DNS server address
    sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE,IPCONFIG_MODE_ENABLE_IPV4,sizeof(SlNetCfgIpV4Args_t),(_u8 *)&ipV4);
    sl_Stop(0);
    sl_Start(NULL,NULL,NULL);
    UART_PRINT("\n\rSet up static ip already\n");*/

    // Disable scan
    ucConfigOpt = SL_SCAN_POLICY(0);
    lRetVal = sl_WlanPolicySet(SL_POLICY_SCAN , ucConfigOpt, NULL, 0);
    ASSERT_ON_ERROR(lRetVal);

    // Set Tx power level for station mode
    // Number between 0-15, as dB offset from max power - 0 will set max power
    ucPower = 0;
    lRetVal = sl_WlanSet(SL_WLAN_CFG_GENERAL_PARAM_ID,
    WLAN_GENERAL_PARAM_OPT_STA_TX_POWER, 1, (unsigned char *)&ucPower);
    ASSERT_ON_ERROR(lRetVal);

    // Set PM policy to normal
    lRetVal = sl_WlanPolicySet(SL_POLICY_PM , SL_NORMAL_POLICY, NULL, 0);
    ASSERT_ON_ERROR(lRetVal);

    // Unregister mDNS services
    lRetVal = sl_NetAppMDNSUnRegisterService(0, 0);
    ASSERT_ON_ERROR(lRetVal);

    // Remove all 64 filters (8*8)
    memset(RxFilterIdMask.FilterIdMask, 0xFF, 8);
    lRetVal = sl_WlanRxFilterSet(SL_REMOVE_RX_FILTER, (_u8 *)&RxFilterIdMask,
    sizeof(_WlanRxFilterOperationCommandBuff_t));
    ASSERT_ON_ERROR(lRetVal);

    lRetVal = sl_Stop(SL_STOP_TIMEOUT);
    ASSERT_ON_ERROR(lRetVal);

    InitializeAppVariables();

    return lRetVal; // Success
    }



    //****************************************************************************
    //
    //! Confgiures the mode in which the device will work
    //!
    //! \param iMode is the current mode of the device
    //!
    //! This function
    //! 1. prompt user for desired configuration and accordingly configure the
    //! networking mode(STA or AP).
    //! 2. also give the user the option to configure the ssid name in case of
    //! AP mode.
    //!
    //! \return sl_start return value(int).
    //
    //****************************************************************************
    static int ConfigureMode(int iMode)
    {
    char pcSsidName[33];
    long lRetVal = -1;
    SlNetAppDhcpServerBasicOpt_t dhcpParams = {0};
    UART_PRINT("the AP SSID name\n\r");
    //GetSsidName(pcSsidName,33);
    strcpy(pcSsidName,"avnoic_ap");
    lRetVal = sl_WlanSetMode(ROLE_AP);
    ASSERT_ON_ERROR(lRetVal);

    lRetVal = sl_WlanSet(SL_WLAN_CFG_AP_ID, WLAN_AP_OPT_SSID, strlen(pcSsidName),
    (unsigned char*)pcSsidName);
    ASSERT_ON_ERROR(lRetVal);

    SlNetCfgIpV4Args_t net;
    net.ipV4 = SL_IPV4_VAL(192, 168, 0, 1);
    net.ipV4Mask = SL_IPV4_VAL(255, 255, 255, 0);
    net.ipV4Gateway = SL_IPV4_VAL(192, 168, 0, 1);
    net.ipV4DnsServer = SL_IPV4_VAL(192, 168, 0, 1);

    /* Configure the Static IP */
    lRetVal = sl_NetCfgSet(SL_IPV4_AP_P2P_GO_STATIC_ENABLE,1,sizeof(SlNetCfgIpV4Args_t),
    (unsigned char *)&net);
    if(lRetVal < 0)
    LOOP_FOREVER();

    dhcpParams.lease_time = IP_LEASE_TIME;
    dhcpParams.ipv4_addr_start = DHCP_START_IP;
    dhcpParams.ipv4_addr_last = DHCP_END_IP;

    lRetVal = sl_NetAppSet(SL_NET_APP_DHCP_SERVER_ID, NETAPP_SET_DHCP_SRV_BASIC_OPT,
    sizeof(SlNetAppDhcpServerBasicOpt_t), (unsigned char*)&dhcpParams);
    if(lRetVal < 0)
    LOOP_FOREVER();


    UART_PRINT("\nDevice is configured in AP mode\n\r");

    /* Restart Network processor */
    lRetVal = sl_Stop(SL_STOP_TIMEOUT);

    // reset status bits
    CLR_STATUS_BIT_ALL(g_ulStatus);

    return sl_Start(NULL,NULL,NULL);
    }

    //****************************************************************************
    //
    //! Get Ssid name form the user over UART
    //!
    //! \param pcSsidName is a pointer to the array which will contain the ssid name
    //!
    //! This function
    //! 1. gets the ssid name string over uart
    //!
    //! \return iRetVal is the length of the ssid(user input).
    //
    //****************************************************************************
    static int GetSsidName(char *pcSsidName, unsigned int uiMaxLen)
    {
    char ucRecvdAPDetails = 0;
    int iRetVal = 0;
    char acCmdStore[128];
    do
    {
    ucRecvdAPDetails = 0;

    //
    // Get the AP name to connect over the UART
    //
    iRetVal = GetCmd(acCmdStore, sizeof(acCmdStore));
    if(iRetVal > 0)
    {
    // remove start/end spaces if any
    iRetVal = TrimSpace(acCmdStore);

    //
    // Parse the AP name
    //
    strncpy(pcSsidName, acCmdStore, iRetVal);
    if(pcSsidName != NULL)
    {
    ucRecvdAPDetails = 1;
    pcSsidName[iRetVal] = '\0';
    }
    }
    }while(ucRecvdAPDetails == 0);

    return(iRetVal);
    }

    //****************************************************************************
    //
    //! \brief device will try to ping the machine that has just connected to the
    //! device.
    //!
    //! \param ulIpAddr is the ip address of the station which has connected to
    //! device
    //!
    //! \return 0 if ping is successful, -1 for error
    //
    //****************************************************************************
    static int PingTest(unsigned long ulIpAddr)
    {
    signed long lRetVal = -1;
    SlPingStartCommand_t PingParams;
    SlPingReport_t PingReport;
    PingParams.PingIntervalTime = PING_INTERVAL;
    PingParams.PingSize = PING_PKT_SIZE;
    PingParams.PingRequestTimeout = PING_TIMEOUT;
    PingParams.TotalNumberOfAttempts = NO_OF_ATTEMPTS;
    PingParams.Flags = PING_FLAG;
    PingParams.Ip = ulIpAddr; /* Cleint's ip address */

    UART_PRINT("Running Ping Test...\n\r");
    /* Check for LAN connection */
    lRetVal = sl_NetAppPingStart((SlPingStartCommand_t*)&PingParams, SL_AF_INET,
    (SlPingReport_t*)&PingReport, NULL);
    ASSERT_ON_ERROR(lRetVal);

    g_ulPingPacketsRecv = PingReport.PacketsReceived;

    if (g_ulPingPacketsRecv > 0 && g_ulPingPacketsRecv <= NO_OF_ATTEMPTS)
    {
    // LAN connection is successful
    UART_PRINT("Ping Test successful\n\r");
    }
    else
    {
    // Problem with LAN connection
    ASSERT_ON_ERROR(LAN_CONNECTION_FAILED);
    }

    return SUCCESS;
    }


    //****************************************************************************
    //
    //! \brief Opening a TCP server side socket and receiving data
    //!
    //! This function opens a TCP socket in Listen mode and waits for an incoming
    //! TCP connection.
    //! If a socket connection is established then the function will try to read
    //! 1000 TCP packets from the connected client.
    //!
    //! \param[in] port number on which the server will be listening on
    //!
    //! \return 0 on success, -1 on error.
    //!
    //! \note This function will wait for an incoming connection till
    //! one is established
    //
    //****************************************************************************
    int BsdTcpServer(unsigned short usPort)
    {
    SlSockAddrIn_t sAddr;
    SlSockAddrIn_t sLocalAddr;
    int iCounter;
    int iAddrSize;
    int iSockID;
    int iStatus;
    //int iNewSockID;
    long lLoopCount = 0;
    long lNonBlocking = 1;
    int iTestBufLen;
    int i=0;
    int len =0;

    // filling the buffer
    for (iCounter=0 ; iCounter<BUF_SIZE ; iCounter++)
    {
    g_cBsdBuf[iCounter] = (char)(iCounter % 10);
    }

    iTestBufLen = BUF_SIZE;

    //filling the TCP server socket address
    sLocalAddr.sin_family = SL_AF_INET;
    sLocalAddr.sin_port = sl_Htons((unsigned short)usPort);
    sLocalAddr.sin_addr.s_addr = 0;
    Report("sl_Socket\n\r");
    // creating a TCP socket
    iSockID = sl_Socket(SL_AF_INET,SL_SOCK_STREAM, 0);
    if( iSockID < 0 )
    {
    // error
    ASSERT_ON_ERROR(SOCKET_CREATE_ERROR);
    }

    iAddrSize = sizeof(SlSockAddrIn_t);
    Report("sl_Bind\n\r");
    // binding the TCP socket to the TCP server address
    iStatus = sl_Bind(iSockID, (SlSockAddr_t *)&sLocalAddr, iAddrSize);
    if( iStatus < 0 )
    {
    // error
    sl_Close(iSockID);
    ASSERT_ON_ERROR(BIND_ERROR);
    }
    Report("sl_Listen\n\r");
    // putting the socket for listening to the incoming TCP connection
    iStatus = sl_Listen(iSockID, 0);
    if( iStatus < 0 )
    {
    sl_Close(iSockID);
    ASSERT_ON_ERROR(LISTEN_ERROR);
    }
    Report("sl_SetSockOpt\n\r");
    // setting socket option to make the socket as non blocking
    iStatus = sl_SetSockOpt(iSockID, SL_SOL_SOCKET, SL_SO_NONBLOCKING,
    &lNonBlocking, sizeof(lNonBlocking));
    if( iStatus < 0 )
    {
    sl_Close(iSockID);
    ASSERT_ON_ERROR(SOCKET_OPT_ERROR);
    }
    iNewSockID = SL_EAGAIN;
    Report("start to while\n\r");
    // waiting for an incoming TCP connection
    while( iNewSockID < 0 )
    {

    // accepts a connection form a TCP client, if there is any
    // otherwise returns SL_EAGAIN
    iNewSockID = sl_Accept(iSockID, ( struct SlSockAddr_t *)&sAddr,
    (SlSocklen_t*)&iAddrSize);
    if( iNewSockID == SL_EAGAIN )
    {
    MAP_UtilsDelay(10000);
    }
    else if( iNewSockID < 0 )
    {
    // error
    sl_Close(iNewSockID);
    sl_Close(iSockID);
    ASSERT_ON_ERROR(ACCEPT_ERROR);
    }
    }
    Report("start to wait recving\n\r");
    // waits for 1000 packets from the connected TCP client
    while (1)
    {
    MAP_UtilsDelay(10000);
    sl_Send(iNewSockID,"1111111111111", 13, 0);
    /*iStatus = sl_Recv(iNewSockID, g_cBsdBuf, iTestBufLen, 0);
    if( iStatus <= 0 )
    {
    // error
    sl_Close(iNewSockID);
    sl_Close(iSockID);
    ASSERT_ON_ERROR(RECV_ERROR);
    }
    else*/
    {
    //Report("got;\n\r");
    //Report("start \n\r");
    // AP_circleBuff_ReadData();
    //Report("header %d\n\r",AP_circleBuff_ReadData());
    //while(1)
    { //len =AP_circleBuff_ReadPacketData();
    //if(len>0)

    if(issendA ==1)
    {
    //sl_Send(iNewSockID,g_ucRxBufA, DMA_SIZE, 0);
    //memset(g_ucRxBufA_tmp,0,DMA_SIZE);
    //Report("header %d %d %d %d\n ",rx_buffer[0],rx_buffer[1],rx_buffer[2],rx_buffer[3]);
    //Report("header %c %c %c %c\n ",rx_buffer[0],rx_buffer[1],rx_buffer[2],rx_buffer[3]);
    issendA =0;
    }
    else if(issendB ==1)
    {
    //sl_Send(iNewSockID,g_ucRxBufB, DMA_SIZE, 0);
    //memset(g_ucRxBufB_tmp,0,DMA_SIZE);
    //Report("header %d %d %d %d\n ",rx_buffer[0],rx_buffer[1],rx_buffer[2],rx_buffer[3]);
    //Report("header %c %c %c %c\n ",rx_buffer[0],rx_buffer[1],rx_buffer[2],rx_buffer[3]);
    issendB =0;
    }
    //UtilsDelay (8000);

    }
    //for(i=0;i<iTestBufLen;i++)
    {
    // Report("%s",g_cBsdBuf);

    }
    }

    lLoopCount++;
    }

    Report("Recieved %u packets successfully\n\r",g_ulPacketCount);

    // close the connected socket after receiving from connected TCP client
    iStatus = sl_Close(iNewSockID);
    ASSERT_ON_ERROR(iStatus);
    // close the listening socket
    iStatus = sl_Close(iSockID);
    ASSERT_ON_ERROR(iStatus);

    return SUCCESS;
    }

    //****************************************************************************
    //
    //! \brief start simplelink, wait for the sta to connect to the device and
    //! run the ping test for that sta
    //!
    //! \param pvparameters is the pointer to the list of parameters that can be
    //! passed to the task while creating it
    //!
    //! \return None
    //
    //****************************************************************************
    void WlanAPMode( void *pvParameters )
    {
    int iTestResult = 0;
    unsigned char ucDHCP;
    long lRetVal = -1;

    InitializeAppVariables();

    //
    // Following function configure the device to default state by cleaning
    // the persistent settings stored in NVMEM (viz. connection profiles &
    // policies, power policy etc)
    //
    // Applications may choose to skip this step if the developer is sure
    // that the device is in its default state at start of applicaton
    //
    // Note that all profiles and persistent settings that were done on the
    // device will be lost
    //
    lRetVal = ConfigureSimpleLinkToDefaultState();
    if(lRetVal < 0)
    {
    if (DEVICE_NOT_IN_STATION_MODE == lRetVal)
    UART_PRINT("Failed to configure the device in its default state \n\r");

    LOOP_FOREVER();
    }

    UART_PRINT("Device is configured in default state \n\r");
    //Report("Device is configured in default state \n\r");
    //
    // Asumption is that the device is configured in station mode already
    // and it is in its default state
    //
    lRetVal = sl_Start(NULL,NULL,NULL);

    if (lRetVal < 0)
    {
    UART_PRINT("Failed to start the device \n\r");
    LOOP_FOREVER();
    }

    UART_PRINT("Device started as STATION \n\r");
    //Report("Device started as STATION \n\r");
    //
    // Configure the networking mode and ssid name(for AP mode)
    //
    if(lRetVal != ROLE_AP)
    {
    if(ConfigureMode(lRetVal) != ROLE_AP)
    {
    UART_PRINT("Unable to set AP mode, exiting Application...\n\r");
    sl_Stop(SL_STOP_TIMEOUT);
    LOOP_FOREVER();
    }
    }

    while(!IS_IP_ACQUIRED(g_ulStatus))
    {
    //looping till ip is acquiredUART_PRINT("11111111111\n");
    Report("11111111111\n");
    }

    unsigned char len = sizeof(SlNetCfgIpV4Args_t);
    SlNetCfgIpV4Args_t ipV4 = {0};

    // get network configuration
    lRetVal = sl_NetCfgGet(SL_IPV4_AP_P2P_GO_GET_INFO,&ucDHCP,&len,
    (unsigned char *)&ipV4);

    if (lRetVal < 0)
    {
    UART_PRINT("Failed to get network configuration \n\r");
    LOOP_FOREVER();
    }

    UART_PRINT("Connect a client to Device\n\r");
    while(!IS_IP_LEASED(g_ulStatus))
    {
    //wating for the client to connect
    }
    UART_PRINT("Client is connected to Device\n\r");

    /*iTestResult = PingTest(g_ulStaIp);
    if(iTestResult < 0)
    {
    UART_PRINT("Ping to client failed \n\r");
    }

    UNUSED(ucDHCP);
    UNUSED(iTestResult);*/
    UART_PRINT("start tcp server\n\r");
    BsdTcpServer(6000);

    // revert to STA mode
    /*lRetVal = sl_WlanSetMode(ROLE_STA);
    if(lRetVal < 0)
    {
    ERR_PRINT(lRetVal);
    LOOP_FOREVER();
    }
    // Switch off Network processor
    lRetVal = sl_Stop(SL_STOP_TIMEOUT);*/
    UART_PRINT("WLAN AP example executed successfully");
    while(1);
    }

    //*****************************************************************************
    //
    //! Application startup display on UART
    //!
    //! \param none
    //!
    //! \return none
    //!
    //*****************************************************************************
    static void
    DisplayBanner(char * AppName)
    {
    Report("\n\n\n\r");
    Report("\t\t *************************************************\n\r");
    Report("\t\t CC3200 %s Application \n\r", AppName);
    Report("\t\t *************************************************\n\r");
    Report("\n\n\n\r");
    }

    //*****************************************************************************
    //
    //! Board Initialization & Configuration
    //!
    //! \param None
    //!
    //! \return None
    //
    //*****************************************************************************
    static void
    BoardInit(void)
    {
    /* In case of TI-RTOS vector table is initialize by OS itself */
    #ifndef USE_TIRTOS
    //
    // Set vector table base
    //
    #if defined(ccs) || defined(gcc)
    MAP_IntVTableBaseSet((unsigned long)&g_pfnVectors[0]);
    #endif
    #if defined(ewarm)
    MAP_IntVTableBaseSet((unsigned long)&__vector_table);
    #endif
    #endif
    //
    // Enable Processor
    //
    MAP_IntMasterEnable();
    MAP_IntEnable(FAULT_SYSTICK);

    PRCMCC3200MCUInit();
    }

    static void interrupt_handler()
    {
    unsigned long ulStatus;
    unsigned long ulMode;
    //
    // Read the interrupt status of the UART.
    //
    //ulStatus = MAP_SPIIntStatus(GSPI_BASE, 1);
    ulMode = MAP_uDMAChannelModeGet(UDMA_CH30_GSPI_RX | UDMA_PRI_SELECT);//获取DMA通道模式
    if(ulMode == UDMA_MODE_STOP)
    {
    UDMASetupTransfer(UDMA_CH30_GSPI_RX| UDMA_PRI_SELECT,UDMA_MODE_PINGPONG, DMA_SIZE,
    UDMA_SIZE_8,UDMA_ARB_1,
    (void *)(GSPI_BASE + MCSPI_O_RX0),UDMA_SRC_INC_NONE,
    g_ucRxBufA,UDMA_DST_INC_8);
    issendA=1;
    memcpy(g_ucRxBufA_tmp,g_ucRxBufA,DMA_SIZE);
    sl_Send(iNewSockID,"11111", 5, 0);
    Report("dma init %c %c %c %c %c\n ",g_ucRxBufA[0],g_ucRxBufA[1],g_ucRxBufA[2],g_ucRxBufA[3],g_ucRxBufA[4]);
    }
    //Report("dma init %c %c %c %c %c\n ",g_ucRxBufA[0],g_ucRxBufA[1],g_ucRxBufA[2],g_ucRxBufA[3],g_ucRxBufA[255]);

    ulMode = MAP_uDMAChannelModeGet(UDMA_CH30_GSPI_RX | UDMA_ALT_SELECT);
    if(ulMode == UDMA_MODE_STOP)
    {
    UDMASetupTransfer(UDMA_CH30_GSPI_RX| UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,DMA_SIZE,
    UDMA_SIZE_8,UDMA_ARB_1,
    (void *)(GSPI_BASE + MCSPI_O_RX0),UDMA_SRC_INC_NONE,
    g_ucRxBufB,UDMA_DST_INC_8);
    issendB=1;
    memcpy(g_ucRxBufB_tmp,g_ucRxBufB,DMA_SIZE);
    //sl_Send(iNewSockID,g_ucRxBufB_tmp, DMA_SIZE, 0);
    Report("dma init %c %c %c %c %c\n ",g_ucRxBufB[0],g_ucRxBufB[1],g_ucRxBufB[2],g_ucRxBufB[3],g_ucRxBufB[4]);
    }
    //Report("dma init %c %c %c %c %c\n ",g_ucRxBufB[0],g_ucRxBufB[1],g_ucRxBufB[2],g_ucRxBufB[3],g_ucRxBufB[255]);

    }



    void SlaveMain2()
    {
    //
    // Initialize the message
    //
    //memcpy(g_ucTxBuff,SLAVE_MSG,sizeof(SLAVE_MSG));

    //
    // Set Tx buffer index
    //
    ucTxBuffNdx = 0;
    ucRxBuffNdx = 0;

    //
    // Reset SPI
    //
    MAP_SPIReset(GSPI_BASE);
    UDMAInit();
    //
    // Configure SPI interface
    //
    MAP_SPIConfigSetExpClk(GSPI_BASE,MAP_PRCMPeripheralClockGet(PRCM_GSPI),
    SPI_IF_BIT_RATE,SPI_MODE_SLAVE,SPI_SUB_MODE_0,
    (SPI_HW_CTRL_CS |
    SPI_4PIN_MODE |
    SPI_TURBO_OFF |
    SPI_CS_ACTIVELOW |
    SPI_WL_8/*SPI_WL_32*/));
    //MAP_SPIIntRegister(GSPI_BASE,interrupt_handler);



    //
    // Register Interrupt Handler
    //
    MAP_SPIIntRegister(GSPI_BASE,interrupt_handler);
    MAP_SPIWordCountSet(GSPI_BASE, DMA_SIZE);
    MAP_SPIFIFOLevelSet(GSPI_BASE, 1, 1);
    MAP_SPIFIFOEnable(GSPI_BASE, SPI_RX_FIFO);
    MAP_SPIFIFOEnable(GSPI_BASE, SPI_TX_FIFO);
    MAP_SPIDmaEnable(GSPI_BASE,SPI_RX_DMA);
    MAP_SPIDmaEnable(GSPI_BASE,SPI_TX_DMA);
    MAP_SPIIntEnable(GSPI_BASE, SPI_INT_EOW);
    MAP_SPIEnable(GSPI_BASE);

    //
    // Enable Interrupts
    //
    //MAP_SPIIntEnable(GSPI_BASE,SPI_INT_RX_FULL|SPI_INT_TX_EMPTY);

    //
    // Enable SPI for communication
    //
    //MAP_SPIEnable(GSPI_BASE);
    MAP_SPIDisable(GSPI_BASE);
    UDMASetupTransfer(UDMA_CH30_GSPI_RX| UDMA_PRI_SELECT,UDMA_MODE_PINGPONG, DMA_SIZE,
    UDMA_SIZE_8,UDMA_ARB_1,
    (void *)(GSPI_BASE + MCSPI_O_RX0),UDMA_SRC_INC_NONE,
    g_ucRxBufA,UDMA_DST_INC_8);

    UDMASetupTransfer(UDMA_CH30_GSPI_RX| UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,DMA_SIZE,
    UDMA_SIZE_8,UDMA_ARB_1,
    (void *)(GSPI_BASE + MCSPI_O_RX0),UDMA_SRC_INC_NONE,
    g_ucRxBufB,UDMA_DST_INC_8);

    UDMASetupTransfer(UDMA_CH31_GSPI_TX| UDMA_PRI_SELECT,UDMA_MODE_BASIC,16,
    UDMA_SIZE_8,UDMA_ARB_1,
    (void *)g_ucTxBuff,UDMA_SRC_INC_8,(void *)(GSPI_BASE + MCSPI_O_TX0),
    UDMA_DST_INC_NONE);
    MAP_SPIEnable(GSPI_BASE);


    //
    // Print mode on uart
    //
    Message("Enabled SPI Interface in Slave Mode\n\rReceived : ");
    }

    //*****************************************************************************
    // MAIN FUNCTION
    //*****************************************************************************
    void main()
    {
    long lRetVal = -1;

    //
    // Board Initialization
    //
    BoardInit();

    //
    // Configure the pinmux settings for the peripherals exercised
    //
    PinMuxConfig();

    MAP_PRCMPeripheralClkEnable(PRCM_GSPI,PRCM_RUN_MODE_CLK);
    //MAP_PRCMPeripheralReset(PRCM_GSPI);

    #ifndef NOTERM
    //
    // Configuring UART
    //
    InitTerm();
    #endif

    //
    // Display banner
    //
    DisplayBanner(APP_NAME);

    //
    // Reset the peripheral
    //
    MAP_PRCMPeripheralReset(PRCM_GSPI);

    Report("SlaveMain ##########################\n");

    SlaveMain2();
    // while(1)
    {

    }
    //
    // Start the SimpleLink Host
    //
    lRetVal = VStartSimpleLinkSpawnTask(SPAWN_TASK_PRIORITY);
    if(lRetVal < 0)
    {
    ERR_PRINT(lRetVal);
    LOOP_FOREVER();
    }

    //
    // Start the WlanAPMode task
    //
    lRetVal = osi_TaskCreate( WlanAPMode, \
    (const signed char*)"wireless LAN in AP mode", \
    OSI_STACK_SIZE, NULL, 1, NULL );
    if(lRetVal < 0)
    {
    ERR_PRINT(lRetVal);
    LOOP_FOREVER();
    }

    //
    // Start the task scheduler
    //
    osi_start();
    }
    #endif

    这是我的代码,采用双dma收取spi数据,把数据发给client,数据发不出去,不知道为什么,感觉调用sl_send也发不出。
  • pingpang的双DMA和tcp的发送无法同时存在啊,有什么办法可以解决吗
  • SPI传输的数据通过sl_send发送需要一段时间,此时新的SPI数据完成的接收导致数据出错,在TCP的传输中可以使用阻塞模式,等待TCP的数据完全传输后再接收新的SPI数据,保证接收和发送的数据一致

    参考 e2echina.ti.com/.../130273
  • 你说的是单DMA,这个我做到了,可以调用sl_send,但是在双DMA的pingpang模式,一旦调用sl_send就卡死。