NRF51822 CAN MCP2515 MCP2562

#include "nrf_drv_spi.h"
#include "app_util_platform.h"
#include "nrf_drv_gpiote.h"
#include "nrf_delay.h"
#include "spi.h"
#include <stdint.h>
#include <string.h>


#define PIN_CS                21
#define PIN_MISO            24
#define PIN_MOSI            23
#define PIN_SCK                22


const nrf_drv_spi_t m_spi_master_0 = NRF_DRV_SPI_INSTANCE(0); 


void spi_master_init(nrf_drv_spi_t const * p_instance)  
{  
    uint32_t err_code = NRF_SUCCESS;  
  
    nrf_drv_spi_config_t config =  
    {  
        .ss_pin       = NRF_DRV_SPI_PIN_NOT_USED,  
        .irq_priority = APP_IRQ_PRIORITY_LOW,  
        .orc          = 0xFF,  
        .frequency    = SPI_FREQUENCY_FREQUENCY_M4,  
        .mode         = NRF_DRV_SPI_MODE_0,  
        .bit_order    = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST
             
    };  
  
    #if (SPI0_ENABLED == 1)  
//    if (p_instance == &m_spi_master_0)  
    {  
        config.sck_pin  = PIN_SCK;  
        config.mosi_pin = PIN_MOSI;  
        config.miso_pin = PIN_MISO;  
        err_code = nrf_drv_spi_init(p_instance, &config,  
        NULL);  
    }  
    #endif // (SPI0_ENABLED == 1)  
  
    APP_ERROR_CHECK(err_code);  
}  




uint8_t spi_transfer(uint8_t data){



unsigned char tx_data = data;


nrf_drv_spi_transfer(&m_spi_master_0,(uint8_t const *)&tx_data,1,NULL,0);
tx_data = 0;

return 0;
}


uint8_t spi_transfer1(){


unsigned char rx_data;
nrf_drv_spi_transfer(&m_spi_master_0,NULL,0,&rx_data,1);

return rx_data;
}




#define SPI_MCP2515_CS_H()    nrf_gpio_pin_set(21);
#define SPI_MCP2515_CS_L()    nrf_gpio_pin_clear(21);




void mcp2515_write_register(uint8_t adress, uint8_t data)
{
  SPI_MCP2515_CS_L();
  spi_transfer(SPI_WRITE); // ??SPI???????
  spi_transfer(adress);  //???????
  spi_transfer(data);   //???????
  //CS high ,MCP2515 disable
  SPI_MCP2515_CS_H();
}


uint8_t mcp2515_read_register(uint8_t adress)
{
  uint8_t data;
  // CS low ,MCP2515 enable
  SPI_MCP2515_CS_L();
  spi_transfer(SPI_READ); // ??SPI???????
  spi_transfer(adress); //???????
  data = spi_transfer1(); //???????
  //CS high ,MCP2515 disable
  SPI_MCP2515_CS_H();
  return (data);
}
void mcp2515_bit_modify(uint8_t adress, uint8_t mask, uint8_t data)
{
  // CS low ,MCP2515 enable
  SPI_MCP2515_CS_L();
  spi_transfer(SPI_BIT_MODIFY); //SPI?????
  spi_transfer(adress);    //???????
  spi_transfer(mask);     //??????,
  spi_transfer(data);     //??????
  //CS high ,MCP2515 disable
  SPI_MCP2515_CS_H();
}
// 00 00 07 df


void Can_send(unsigned char ID[],unsigned char tx_buff[],unsigned char Fream)
{
unsigned char i,ret;
    do 
    {
        ret = mcp2515_read_register(0x30);
    } while (ret&0x10);
    if (Fream==1) //±ê×¼Êý¾ÝÖ¡
    {
mcp2515_write_register(0x31, (ID[0]<<5) | (ID[1] >> 3));
mcp2515_write_register(0x32, (ID[1]<<5));
//        mcp2515_write_register(0x31, 0xfb); //·¢ËÍ»º³åÆ÷0±ê×¼±êʶ·û¸ßλ
   ID[1]=ID[1]&0xe0;
//        mcp2515_write_register(0x32, 0xe0); //·¢ËÍ»º³åÆ÷0±ê×¼±êʶ·ûµÍλ
        mcp2515_write_register(0x35, 0x8); //·¢ËÍ»º³åÆ÷0Êý¾Ý³¤¶ÈÂë
    }
else if (Fream==2) //À©Õ¹Êý¾ÝÖ¡
{        
//        ID[1]=(ID[1]&0xe3)|0x08;
        mcp2515_write_register(0x31, (ID[0]<<3) | (ID[1] >> 5)); //·¢ËÍ»º³åÆ÷0±ê×¼±êʶ·û¸ßλ
        mcp2515_write_register(0x32, ((ID[1]<<3) &0xE0) | 0x1C | (ID[1] & 0x03)); //·¢ËÍ»º³åÆ÷0±ê×¼±êʶ·ûµÍλ
        mcp2515_write_register(0x33, ID[2]); //·¢ËÍ»º³åÆ÷0À©Õ¹±êʶ·û¸ßλ
        mcp2515_write_register(0x34, ID[3]); //·¢ËÍ»º³åÆ÷0À©Õ¹±êʶ·ûµÍλ
        mcp2515_write_register(0x35, 0x08); //·¢ËÍ»º³åÆ÷0Êý¾Ý³¤¶ÈÂë
}



    SPI_MCP2515_CS_L();
    spi_transfer(0x02);
    spi_transfer(0x36);
    for(i = 0; i < 8; i++) spi_transfer(tx_buff[i]);
    SPI_MCP2515_CS_H();
    //Write_BYTE_2515(0x35,0x08);
    //t_cmd();
    SPI_MCP2515_CS_L();
 spi_transfer(0x81);
 SPI_MCP2515_CS_H();//·¢ËÍÇëÇó
}


unsigned char CAN_Receive_Buffer(unsigned char *CAN_RX_Buf)
{
unsigned char i=0,len=0,temp=0,id_len = 0;
unsigned char ID[4] = {0};
temp = mcp2515_read_register(CANINTF);

if(!(mcp2515_read_register(RXB0SIDL) & 0x08)){
ID[0] = mcp2515_read_register(RXB0SIDH) >>5;
ID[1] = mcp2515_read_register(RXB0SIDH) << 3;
memcpy(CAN_RX_Buf,"\x08",1);
memcpy(CAN_RX_Buf+1,ID,2);
id_len = 3;
}else{

ID[0] = mcp2515_read_register(RXB0SIDH) >>3;
ID[1] = (mcp2515_read_register(RXB0SIDL) & 0x03)| ((mcp2515_read_register(RXB0SIDL) & 0xE0) >> 3) | (mcp2515_read_register(RXB0SIDH) << 5);
ID[2] = mcp2515_read_register(RXB0EID8);
ID[3] = mcp2515_read_register(RXB0EID0);

memcpy(CAN_RX_Buf,"\x88",1);
memcpy(CAN_RX_Buf+1,ID,4);
id_len = 5;
}
if(temp & 0x01)
{
len=mcp2515_read_register(RXB0DLC);//¶ÁÈ¡½ÓÊÕ»º³åÆ÷0½ÓÊÕµ½µÄÊý¾Ý³¤¶È(0~8¸ö×Ö½Ú)
while(i<len)
{
CAN_RX_Buf[i+id_len]=mcp2515_read_register(RXB0D0+i);//°ÑCAN½ÓÊÕµ½µÄÊý¾Ý·ÅÈëÖ¸¶¨»º³åÇø
i++;
}
}
mcp2515_bit_modify(CANINTF,0xe3,0);//Çå³ýÖжϱê־λ(ÖжϱêÖ¾¼Ä´æÆ÷±ØÐëÓÉMCUÇåÁã)
return len + id_len;
}


uint32_t mcp2515_init()     //?8M?????,??????1.8MS     SPI = 687.5K
{
  SPI_MCP2515_CS_L();     //MCP2515?CS??
  spi_transfer(SPI_RESET); //??????
nrf_delay_ms(1);
SPI_MCP2515_CS_H();

mcp2515_bit_modify(0x0f,0xe0,0x80);
//lv bo
mcp2515_write_register(0x00,0);
mcp2515_write_register(0x01,0xeb);
mcp2515_write_register(0x02,0);
mcp2515_write_register(0x03,0);

//pi bi
mcp2515_write_register(0x20,0);//ff
mcp2515_write_register(0x21,0);//e0
mcp2515_write_register(0x22,0);

//zhongduan
mcp2515_write_register(0x2b,0x01);
//huanhui
mcp2515_bit_modify(0x0f,0xe0,0x40);
mcp2515_bit_modify(0x0f,0xe0,0);
if(0 != ((mcp2515_read_register(CANSTAT))&0xE0))//ÅжÏMCP2515ÊÇ·ñÒѾ­½øÈëÕý³£Ä£Ê½
{
// LED();
mcp2515_bit_modify(0x0f,0xe0,0);
}


}


uint8_t SetBaudrate(uint32_t bps)
{
box.baudrate=bps;


mcp2515_bit_modify(0x0f,0xe0,0x80);
switch(bps){

// case 0x01040309:
// mcp2515_write_register(0x2a,0x0);//1000
//    mcp2515_write_register(0x29,0xb5);
//    mcp2515_write_register(0x28,0x01);
// break;
case 0x01040312:
mcp2515_write_register(0x2a,0x00);//500
   mcp2515_write_register(0x29,0x91);
   mcp2515_write_register(0x28,0x01);
break;
case 0x01080712:
mcp2515_write_register(0x2a,0x00);//250
   mcp2515_write_register(0x29,0xb5);
   mcp2515_write_register(0x28,0x01);
break;
case 0x01080724:
mcp2515_write_register(0x2a,0x01);//125
   mcp2515_write_register(0x29,0xb5);
   mcp2515_write_register(0x28,0x01);
break;
case 0x0108072d:
mcp2515_write_register(0x2a,0x01);//100
   mcp2515_write_register(0x29,0xbf);
   mcp2515_write_register(0x28,0x02);
break;
// case 0x01080787:
// mcp2515_write_register(0x2a,0x01);//33.3
//    mcp2515_write_register(0x29,0xb5);
//    mcp2515_write_register(0x28,0x01);
// break;
case 0x010d025a:
mcp2515_write_register(0x2a,0x04);//50
   mcp2515_write_register(0x29,0xb5);
   mcp2515_write_register(0x28,0x01);
break;

}

mcp2515_bit_modify(0x0f,0xe0,0);
if(0 != ((mcp2515_read_register(CANSTAT))&0xE0))//ÅжÏMCP2515ÊÇ·ñÒѾ­½øÈëÕý³£Ä£Ê½
{
mcp2515_bit_modify(0x0f,0xe0,0);
}

return 1;
}




unsigned char buff1[15] = {0},buff[8];


void GPIOTE_IRQHandler(){


    if ((NRF_GPIOTE->EVENTS_IN[0] == 1) && 
        (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[0] = 0;
    }
nrf_delay_ms(5);
int len = CAN_Receive_Buffer(buff1);
LED();
AddDataToBuffer(buff1,len);
}


void MCP2515_IRQ_Init(void) //?????
{
  
    nrf_gpio_cfg_input(26,NRF_GPIO_PIN_NOPULL);
    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo << 16) 
                           | (26<< 8UL)  
                           | (0x01);
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;


    NVIC_EnableIRQ(GPIOTE_IRQn);
//    NVIC_SetPriority(GPIOTE_IRQn,3);//???????

}

main函数

/**
 * Copyright (c) 2014 - 2017, Nordic Semiconductor ASA
 * 
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 * 
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, 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.
 * 
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 * 
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 * 
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 * 
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
 * 
 */


/** @file
 *
 * @defgroup ble_sdk_uart_over_ble_main main.c
 * @{
 * @ingroup  ble_sdk_app_nus_eval
 * @brief    UART over BLE application main file.
 *
 * This file contains the source code for a sample application that uses the Nordic UART service.
 * This application uses the @ref srvlib_conn_params module.
 */


#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "ble_hci.h"
#include "ble_advdata.h"
#include "ble_advertising.h"
#include "ble_conn_params.h"
#include "softdevice_handler.h"
#include "app_timer.h"
#include "app_button.h"
#include "ble_nus.h"
#include "app_uart.h"
#include "app_util_platform.h"
#include "bsp.h"
#include "bsp_btn_ble.h"
#include "spi.h"
#include "nrf_delay.h"
#include "nrf_drv_common.h"
#include "nrf_drv_gpiote.h"
#include "box.h"
#include "nrf_drv_adc.h"
#include "nrf_drv_uart.h"
#include "nrf_drv_rtc.h"


#include "app_scheduler.h"
#include "app_fifo.h"
static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE);
#define UART_BAUDRATE_BAUDRATE_Baud10400 0x002AA000UL


//RTT
#define NRF_LOG_MODULE_NAME "APP"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
static void log_init(){


ret_code_t ret = NRF_LOG_INIT(NULL);
APP_ERROR_CHECK(ret);


}




APP_TIMER_DEF(m_wdt_timer_id);
#define WDT_LEVEL_MEAS_INTERVAL APP_TIMER_TICKS(200,APP_TIMER_PRESCALER)




#define IS_SRVC_CHANGED_CHARACT_PRESENT 0                                           /**< Include the service_changed characteristic. If not enabled, the server's database cannot be changed for the lifetime of the device. */


#if (NRF_SD_BLE_API_VERSION == 3)
#define NRF_BLE_MAX_MTU_SIZE            GATT_MTU_SIZE_DEFAULT                       /**< MTU size used in the softdevice enabling and to reply to a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. */
#endif


#define APP_FEATURE_NOT_SUPPORTED       BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2        /**< Reply when unsupported features are requested. */


#define CENTRAL_LINK_COUNT              0                                           /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/
#define PERIPHERAL_LINK_COUNT           1                                           /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/


#define DEVICE_NAME                     "XU_UART"                               /**< Name of device. Will be included in the advertising data. */
#define NUS_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN                  /**< UUID type for the Nordic UART Service (vendor specific). */


#define APP_ADV_INTERVAL                64                                          /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */
#define APP_ADV_TIMEOUT_IN_SECONDS      0                                        /**< The advertising timeout (in units of seconds). */


#define APP_TIMER_PRESCALER             0                                           /**< Value of the RTC1 PRESCALER register. */
#define APP_TIMER_OP_QUEUE_SIZE         4                                           /**< Size of timer operation queues. */


#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)             /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)             /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
#define SLAVE_LATENCY                   0                                           /**< Slave latency. */
#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)             /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */
#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000, APP_TIMER_PRESCALER)  /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT    3                                           /**< Number of attempts before giving up the connection parameter negotiation. */


#define DEAD_BEEF                       0xDEADBEEF                                  /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */


#define UART_TX_BUF_SIZE                256                                         /**< UART TX buffer size. */
#define UART_RX_BUF_SIZE                256                                         /**< UART RX buffer size. */


static ble_nus_t                        m_nus;                                      /**< Structure to identify the Nordic UART Service. */
static uint16_t                         m_conn_handle = BLE_CONN_HANDLE_INVALID;    /**< Handle of the current connection. */


static ble_uuid_t                       m_adv_uuids[] = {{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}};  /**< Universally unique service identifier. */




static ble_opt_t m_static_pin_option;


#define IO_CAPS      BLE_GAP_IO_CAPS_DISPLAY_ONLY  //??????
#define BOND         0                               //???
#define OOB          0                          
#define MITM         1


#define MAX_DMA_RECV_SIZE 60 
#define MAX_REQ_DATA_SIZE (MAX_DMA_RECV_SIZE-10)


uint8_t ExecuteMcu(uint16_t cmd,uint8_t *param,uint16_t len);
 struct tagResData resData = {0};
 uint8_t receive_uart[20] = {0};


void LED(){


nrf_gpio_cfg_output(5);
nrf_gpio_pin_clear(5);
nrf_delay_ms(10);
nrf_gpio_pin_set(5);


}


//0x55,0xAA,0x00,0x00,0x00,0x05,0xFF,0xFA,0x01,0x00,0x02,0x60,0xC1,0x5D
// SetProtocol 0x55,0xAA,0x00,0x00,0x00,0x06,0xFF,0xF9,0x01,0x00,0x03,0x60,0x05,0x01,0x5D
//0x55,0xAA,0x00,0x00,0x00,0x05,0xFF,0xFA,0x01,0x00,0x07,0x61,0x04,0xc1,0x33,0xf1,0x82,0x67,0x5D
// kwp-fast12  0x55,0xAA,0x00,0x00,0x00,0x0A,0xFF,0xF5,0x01,0x00,0x07,0x61,0x04,0xc1,0x33,0xf1,0x04,0xE9,0x5D
//can 0x55,0xAA,0x00,0x08,0x00,0x13,0xFF,0xEc,0x01,0x00,0x10,0x61,0x04,0x00,0x0B,0x08,0x07,0xdf,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x4F
// can kuo zhan 0x55,0xAA,0x00,0x0E,0x00,0x15,0xFF,0xEA,0x01,0x00,0x12,0x61,0x04,0x00,0x0D,0x88,0x18,0xDB,0x33,0xF1,0x02,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x14
// 0x55,0xAA,0x00,0x0A,0x00,0x23,0xFF,0xDC,0x05,0x00,0x03,0x60,0x07,0x00,0x00,0x04,0x61,0x03,0x00,0x19,0x00,0x03,0x60,0x07,0xFF,0x00,0x04,0x61,0x03,0x00,0x19,0x00,0x0A,0x61,0x04,0x00,0x05,0xC1,0x33,0xF1,0x81,0x66,0xFF,0x7E
// 0x55,0xAA,0x00,0x0C,0x00,0x0F,0xFF,0xF0,0x01,0x00,0x0C,0x61,0x05,0x19,0x33,0x02,0x02,0x01,0x60,0x00,0x00,0x00,0x05,0xD4
// 0x55,0xAA,0x00,0x0D,0x00,0x0E,0xFF,0xF1,0x01,0x00,0x0B,0x61,0x04,0x00,0x06,0xC2,0x33,0xF1,0x01,0x00,0xE7,0xFF,0x82
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FuncState;
static  FuncState BlueState = ENABLE;
static uint32_t lenBlue = 0;
static uint8_t RecvBuffBlue[MAX_DMA_RECV_SIZE] = {0};
uint8_t buffer[MAX_REQ_DATA_SIZE] = {0};
static  uint16_t packet_id = 0;
#define TYPE_AUTO_UPLOAD  (1)
#define TYPE_REQUEST      (2)
static  uint8_t SendBuffBlue[MAX_DMA_SEND_SIZE] = {0};
static  uint16_t AutoUploadPacketID = 0;
static  uint8_t excursion = 0;




FuncState Get_BlueState(void){
  return BlueState;
}


void Set_BlueState(FuncState NewStatus){
BlueState = NewStatus;
}


//void Blue_Send(uint8_t * p_string, uint16_t length){
//
// ble_nus_string_send(&m_nus, p_string, length);
//}




static void SendPacketByType(uint8_t Type, uint8_t num,uint8_t* buff,uint16_t lenBlue)
{
uint8_t   cs = 0;
uint16_t  i, index = 0;


if(Type == TYPE_AUTO_UPLOAD)
{
SendBuffBlue[index++] = 0x55;
SendBuffBlue[index++] = 0xAA;
SendBuffBlue[index++] = (uint8_t)(AutoUploadPacketID >> 8);
SendBuffBlue[index++] = (uint8_t)(AutoUploadPacketID >> 0);
}
else
{
SendBuffBlue[index++] = 0xAA;
SendBuffBlue[index++] = 0x55;
SendBuffBlue[index++] = (uint8_t)(packet_id>>8);
SendBuffBlue[index++] = (uint8_t)(packet_id>>0);
}

i = lenBlue + 1;
SendBuffBlue[index++] = (uint8_t)(i >> 8);
SendBuffBlue[index++] = (uint8_t)(i >> 0);
i = ~i;
SendBuffBlue[index++] = (uint8_t)(i >> 8);
SendBuffBlue[index++] = (uint8_t)(i >> 0);
SendBuffBlue[index++] = num;
memcpy(SendBuffBlue + index, buff, lenBlue);


cs = SendBuffBlue[0];
for(i = 1; i < index + lenBlue; i++)
{
cs ^= SendBuffBlue[i];
}

SendBuffBlue[i++] = cs;


if(i < 20){


ble_nus_string_send(&m_nus, SendBuffBlue, i);


}else{


uint8_t j = 0;
while(1)
{
ble_nus_string_send(&m_nus, SendBuffBlue + (20 * j), 20);
i = i - 20;
j++;
if(i < 20){
if(i == 0){
break;
}
ble_nus_string_send(&m_nus, SendBuffBlue + (20 * j), i);
break;
}
}


}

}


void SendPacket(uint8_t num,uint8_t* buff,uint16_t lenBlue)
{

SendPacketByType(TYPE_REQUEST, num, buff, lenBlue);
}


//55 AA 00 00 00 05 FF FA 01 00 02 60 C1 5D
uint16_t RecvPacket(uint8_t* buff, uint16_t maxlenBlue)
{


uint16_t i = 0, j = 0, len = 0, tmp = 0, cs = 0, ret = 0;
if(lenBlue < 9)
{
return 0;
}
for(i = 0; i < sizeof(RecvBuffBlue); i++)
{

if(RecvBuffBlue[i + 0] != 0x55)
{

continue;
}

if(RecvBuffBlue[i + 1] != 0xAA)
{

continue;
}


if(lenBlue < i + 8 + 0 + 1)
{

break;
}

len = (RecvBuffBlue[i + 4] << 8) | RecvBuffBlue[i + 5];
tmp = (RecvBuffBlue[i + 6] << 8) | RecvBuffBlue[i + 7];
if(len != (uint16_t)~tmp)
{
continue;
}

if(lenBlue < i + 8 + len + 1)
{
break;
}

if(len > maxlenBlue)
{
i = lenBlue;
break;
}

cs = 0xff ^ RecvBuffBlue[i + 2] ^ RecvBuffBlue[i + 3];
packet_id = (RecvBuffBlue[i + 2] << 8) | RecvBuffBlue[i + 3];
for(j = 0; j < len; j++)
{
buff[j] = RecvBuffBlue[i + 8 + j];
cs ^= buff[j];
}

if(cs == RecvBuffBlue[i + 8 + len])
{
SendPacket(0x00, (uint8_t*)"\x00\x02\x00\x00",4);
i += (8 + len + 1);
ret = len;
break;
}
}

// memcpy(RecvBuffBlue, RecvBuffBlue + i, lenBlue - i);
excursion = i;
lenBlue = lenBlue - i;
return ret;
}


 
void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
{
    app_error_handler(DEAD_BEEF, line_num, p_file_name);
}




/**@brief Function for the GAP initialization.
 *
 * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of
 *          the device. It also sets the permissions and appearance.
 */
static void gap_params_init(void)
{
    uint32_t                err_code;
    ble_gap_conn_params_t   gap_conn_params;
    ble_gap_conn_sec_mode_t sec_mode;


    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);


    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                          (const uint8_t *) DEVICE_NAME,
                                          strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);


    memset(&gap_conn_params, 0, sizeof(gap_conn_params));


    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
    gap_conn_params.slave_latency     = SLAVE_LATENCY;
    gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;


    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
    APP_ERROR_CHECK(err_code);

// uint8_t *passcode="123456";  
//    ble_opt_t     static_option;  
//    static_option.gap_opt.passkey.p_passkey = passcode;  
//    err_code =  sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &static_option);  
//    APP_ERROR_CHECK(err_code);

}


·µ»Ø¸øÉ豸µÄ
//void resp_pair_request(){
//    ble_gap_sec_params_t sec_params;
//    uint32_t                    err_code;


//    memset(&sec_params,0,sizeof(ble_gap_sec_params_t));


//    sec_params.bond = BOND;
//    sec_params.io_caps = IO_CAPS;
//    sec_params.max_key_size = 16;
//    sec_params.min_key_size = 7;
//    sec_params.oob = BOND;
//    sec_params.mitm = MITM;
//err_code=sd_ble_gap_sec_params_reply(m_conn_handle,BLE_GAP_SEC_STATUS_SUCCESS,&sec_params,NULL);
//    APP_ERROR_CHECK(err_code);
//}




void InitDataBuffer(void)
{
resData.count = 0;
resData.size = 0;
memset(resData.buff,0,sizeof(resData.buff));
}


uint8_t ExecuteCmd(uint8_t *buffer)
{
uint8_t tmp, ret = 3;
uint8_t index = 0;
uint8_t *pbData = buffer + 1;

InitDataBuffer();
while(index < buffer[0])
{
switch(pbData[2])
{
// case 0x60:  //55 AA 00 00 00 05 FF FA 01 00 02 60 C1 5D
default:
tmp = ExecuteMcu((pbData[2] << 8) | pbData[3], pbData + 4, ((pbData[0] << 8) | pbData[1]) - 2);
break;
}
if(ret != 2)
{
ret = tmp;//????????,????2
}

pbData += 2 + ((pbData[0] << 8) | pbData[1]);
index++;
}
// memset(receive_uart,0,20);
return ret;
}


void SendAutoUploadDataBuffer(void)
{
// if(0 == autoUploadData.count)
// {
// }
// else
// {
// SendAutoUploadPacket(autoUploadData.count, autoUploadData.buff, autoUploadData.size);
// }
}


void SendDataBuffer(void)
{
if(0 == resData.count)
{
SendPacket(1, (uint8_t*)"\xff\xff", 2);
}
else
{
SendPacket(resData.count, resData.buff, resData.size);
}
}




void SendDataToHost(uint8_t type)
{
uint8_t buff[4] = {0x00, 0x02, 0x00, 0x00};

switch(type)
{
case 0:
buff[3] = 0x01;
SendPacket(0, buff, 4);
break;

case 1:
SendPacket(0, buff, 4);
break;

case 2:
SendDataBuffer();
break;

case 3:
break;

case 4:
//SendAutoUploadDataBuffer();
break;

default://´íÎó´úÂë
buff[3] = type;
SendPacket(0, buff, 4);
break;
}
}






uint8_t flge = 0,flge_cs = 0;
app_fifo_t m_test_fifo;
uint8_t test_fifo[512];


static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length)
{
LED();
 NRF_LOG_INFO("111111\r\n");
// app_fifo_write(&m_test_fifo,p_data,(uint32_t *)&length);

//½ÓÊÕµ½ÊÖ»úµÄÊý¾Ý
//  uint8_t buffer[MAX_REQ_DATA_SIZE] = {0};
if(!flge){

flge_cs = 8 + *(p_data +5) + 1;
NRF_LOG_INFO("flge_cs:%d.\r\n", flge_cs);

}

if((flge_cs < 20)  || (flge_cs ==  length))
{
NRF_LOG_INFO("111111\r\n");
flge = 0;
flge_cs = 0;
lenBlue += length;
memcpy(RecvBuffBlue+(20 * flge), p_data, length);
NRF_LOG_INFO("lenBlue:%d.\r\n", lenBlue);
app_fifo_write(&m_test_fifo,RecvBuffBlue,&lenBlue);
lenBlue = 0;

}else{


memcpy(RecvBuffBlue+(20 * flge), p_data, length);
flge++;
lenBlue += length;
flge_cs = flge_cs - length;
NRF_LOG_INFO("flge_cs:%d.\r\n", flge_cs);
}
}
/**@snippet [Handling the data received over BLE] */




/**@brief Function for initializing services that will be used by the application.
 */
static void services_init(void)
{
    uint32_t       err_code;
    ble_nus_init_t nus_init;


    memset(&nus_init, 0, sizeof(nus_init));


    nus_init.data_handler = nus_data_handler;


    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling an event from the Connection Parameters Module.
 *
 * @details This function will be called for all events in the Connection Parameters Module
 *          which are passed to the application.
 *
 * @note All this function does is to disconnect. This could have been done by simply setting
 *       the disconnect_on_fail config parameter, but instead we use the event handler
 *       mechanism to demonstrate its use.
 *
 * @param[in] p_evt  Event received from the Connection Parameters Module.
 */
static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
{
    uint32_t err_code;


    if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED)
    {
        err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
        APP_ERROR_CHECK(err_code);
    }
}




/**@brief Function for handling errors from the Connection Parameters module.
 *
 * @param[in] nrf_error  Error code containing information about what went wrong.
 */
static void conn_params_error_handler(uint32_t nrf_error)
{
    APP_ERROR_HANDLER(nrf_error);
}




/**@brief Function for initializing the Connection Parameters module.
 */
static void conn_params_init(void)
{
    uint32_t               err_code;
    ble_conn_params_init_t cp_init;


    memset(&cp_init, 0, sizeof(cp_init));


    cp_init.p_conn_params                  = NULL;
    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
    cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
    cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
    cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
    cp_init.disconnect_on_fail             = false;
    cp_init.evt_handler                    = on_conn_params_evt;
    cp_init.error_handler                  = conn_params_error_handler;


    err_code = ble_conn_params_init(&cp_init);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for putting the chip into sleep mode.
 *
 * @note This function will not return.
 */
static void sleep_mode_enter(void)
{
    uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
    APP_ERROR_CHECK(err_code);


    // Prepare wakeup buttons.
    err_code = bsp_btn_ble_sleep_mode_prepare();
    APP_ERROR_CHECK(err_code);


    // Go to system-off mode (this function will not return; wakeup will cause a reset).
    err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling advertising events.
 *
 * @details This function will be called for advertising events which are passed to the application.
 *
 * @param[in] ble_adv_evt  Advertising event.
 */
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    uint32_t err_code;


    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
            APP_ERROR_CHECK(err_code);
            break;
        case BLE_ADV_EVT_IDLE:
            sleep_mode_enter();
            break;
        default:
            break;
    }
}




/**@brief Function for the application's SoftDevice event handler.
 *
 * @param[in] p_ble_evt SoftDevice event.
 */
static void on_ble_evt(ble_evt_t * p_ble_evt)
{
    uint32_t err_code;


    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
//°²È«ÇëÇó
// ble_gap_sec_params_t params;
//         params.bond = 0;
//         params.mitm = 1;
//        
//         sd_ble_gap_authenticate(m_conn_handle,&params);


            break; // BLE_GAP_EVT_CONNECTED


        case BLE_GAP_EVT_DISCONNECTED:
            err_code = bsp_indication_set(BSP_INDICATE_IDLE);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break; // BLE_GAP_EVT_DISCONNECTED



//         case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
//            printf("receive pair request\n");
//           resp_pair_request();
//            break;
//  
 
//        case BLE_GAP_EVT_AUTH_STATUS:
//          if(p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS){
//            printf("pair success\r\n");
//          }else{
//            sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
//          }


        case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
            // Pairing not supported
            err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
            APP_ERROR_CHECK(err_code);
            break; // BLE_GAP_EVT_SEC_PARAMS_REQUEST


        case BLE_GATTS_EVT_SYS_ATTR_MISSING:
            // No system attributes have been stored.
            err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0);
            APP_ERROR_CHECK(err_code);
            break; // BLE_GATTS_EVT_SYS_ATTR_MISSING


        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break; // BLE_GATTC_EVT_TIMEOUT


        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break; // BLE_GATTS_EVT_TIMEOUT


        case BLE_EVT_USER_MEM_REQUEST:
            err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL);
            APP_ERROR_CHECK(err_code);
            break; // BLE_EVT_USER_MEM_REQUEST


        case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
        {
            ble_gatts_evt_rw_authorize_request_t  req;
            ble_gatts_rw_authorize_reply_params_t auth_reply;


            req = p_ble_evt->evt.gatts_evt.params.authorize_request;


            if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
            {
                if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)     ||
                    (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
                    (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
                {
                    if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
                    {
                        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
                    }
                    else
                    {
                        auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
                    }
                    auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED;
                    err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                               &auth_reply);
                    APP_ERROR_CHECK(err_code);
                }
            }
        } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST


#if (NRF_SD_BLE_API_VERSION == 3)
        case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
            err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle,
                                                       NRF_BLE_MAX_MTU_SIZE);
            APP_ERROR_CHECK(err_code);
            break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST
#endif


        default:
            // No implementation needed.
            break;
    }
}




/**@brief Function for dispatching a SoftDevice event to all modules with a SoftDevice
 *        event handler.
 *
 * @details This function is called from the SoftDevice event interrupt handler after a
 *          SoftDevice event has been received.
 *
 * @param[in] p_ble_evt  SoftDevice event.
 */
static void ble_evt_dispatch(ble_evt_t * p_ble_evt)
{
    ble_conn_params_on_ble_evt(p_ble_evt);
    ble_nus_on_ble_evt(&m_nus, p_ble_evt);
    on_ble_evt(p_ble_evt);
    ble_advertising_on_ble_evt(p_ble_evt);
    bsp_btn_ble_on_ble_evt(p_ble_evt);


}




/**@brief Function for the SoftDevice initialization.
 *
 * @details This function initializes the SoftDevice and the BLE event interrupt.
 */
static void ble_stack_init(void)
{
    uint32_t err_code;


    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;


    // Initialize SoftDevice.
    SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL);


    ble_enable_params_t ble_enable_params;
    err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT,
                                                    PERIPHERAL_LINK_COUNT,
                                                    &ble_enable_params);
    APP_ERROR_CHECK(err_code);


    //Check the ram settings against the used number of links
    CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT);


    // Enable BLE stack.
#if (NRF_SD_BLE_API_VERSION == 3)
    ble_enable_params.gatt_enable_params.att_mtu = NRF_BLE_MAX_MTU_SIZE;
#endif
    err_code = softdevice_enable(&ble_enable_params);
    APP_ERROR_CHECK(err_code);


    // Subscribe for BLE events.
    err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
    APP_ERROR_CHECK(err_code);
}




/**@brief Function for handling events from the BSP module.
 *
 * @param[in]   event   Event generated by button press.
 */
void bsp_event_handler(bsp_event_t event)
{
    uint32_t err_code;
    switch (event)
    {
        case BSP_EVENT_SLEEP:
            sleep_mode_enter();
            break;


        case BSP_EVENT_DISCONNECT:
            err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            if (err_code != NRF_ERROR_INVALID_STATE)
            {
                APP_ERROR_CHECK(err_code);
            }
            break;


        case BSP_EVENT_WHITELIST_OFF:
            if (m_conn_handle == BLE_CONN_HANDLE_INVALID)
            {
                err_code = ble_advertising_restart_without_whitelist();
                if (err_code != NRF_ERROR_INVALID_STATE)
                {
                    APP_ERROR_CHECK(err_code);
                }
            }
            break;


        default:
            break;
    }
}


// static uint8_t data_array[BLE_NUS_MAX_DATA_LEN];


void uart_event_handle(app_uart_evt_t * p_event)
{
   
    static uint8_t index = 0;
    uint32_t       err_code;


    switch (p_event->evt_type)
    {
        case APP_UART_DATA_READY:
            UNUSED_VARIABLE(app_uart_get(&receive_uart[index]));
NRF_LOG_INFO("%x\r\n",receive_uart[index]);
   index++;
            break;


        case APP_UART_COMMUNICATION_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_communication);
            break;


        case APP_UART_FIFO_ERROR:
            APP_ERROR_HANDLER(p_event->data.error_code);
            break;


        default:
            break;
    }
}


 void uart_init(void)
{
    uint32_t                     err_code;
    const app_uart_comm_params_t comm_params =
    {
        RX_PIN_NUMBER,
        TX_PIN_NUMBER,
        RTS_PIN_NUMBER,
        CTS_PIN_NUMBER,
        APP_UART_FLOW_CONTROL_DISABLED,
        false,
        UART_BAUDRATE_BAUDRATE_Baud10400
    };


    APP_UART_FIFO_INIT( &comm_params,
                       UART_RX_BUF_SIZE,
                       UART_TX_BUF_SIZE,
                       uart_event_handle,
                       APP_IRQ_PRIORITY_LOWEST,
                       err_code);
    APP_ERROR_CHECK(err_code);
}
/**@snippet [UART Initialization] */




/**@brief Function for initializing the Advertising functionality.
 */
static void advertising_init(void)
{
    uint32_t               err_code;
    ble_advdata_t          advdata;
    ble_advdata_t          scanrsp;
    ble_adv_modes_config_t options;


    // Build advertising data struct to pass into @ref ble_advertising_init.
    memset(&advdata, 0, sizeof(advdata));
    advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = false;
    advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    memset(&scanrsp, 0, sizeof(scanrsp));
    scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    scanrsp.uuids_complete.p_uuids  = m_adv_uuids;


    memset(&options, 0, sizeof(options));
    options.ble_adv_fast_enabled  = true;
    options.ble_adv_fast_interval = APP_ADV_INTERVAL;
    options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;


    err_code = ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL);
    APP_ERROR_CHECK(err_code);
}


///**@brief Function for placing the application in low power state while waiting for events.
// */
static void power_manage(void)
{
    uint32_t err_code = sd_app_evt_wait();
    APP_ERROR_CHECK(err_code);
}








//static void adc_config(void)
//{
//    ret_code_t ret_code;
//    nrf_drv_adc_config_t config = NRF_DRV_ADC_DEFAULT_CONFIG;


//    ret_code = nrf_drv_adc_init(&config, adc_event_handler);
//    APP_ERROR_CHECK(ret_code);


//    nrf_drv_adc_channel_enable(&m_channel_config);
//}




uint8_t SetBaudrate(uint32_t bps)
{
box.baudrate=bps;


mcp2515_bit_modify(0x0f,0xe0,0x80);
switch(bps){

// case 0x01040309:
// mcp2515_write_register(0x2a,0x0);//1000
//    mcp2515_write_register(0x29,0xb5);
//    mcp2515_write_register(0x28,0x01);
// break;
case 0x01040312:
mcp2515_write_register(0x2a,0x00);//500
   mcp2515_write_register(0x29,0x91);
   mcp2515_write_register(0x28,0x01);
break;
case 0x01080712:
mcp2515_write_register(0x2a,0x00);//250
   mcp2515_write_register(0x29,0xb5);
   mcp2515_write_register(0x28,0x01);
break;
case 0x01080724:
mcp2515_write_register(0x2a,0x01);//125
   mcp2515_write_register(0x29,0xb5);
   mcp2515_write_register(0x28,0x01);
break;
case 0x0108072d:
mcp2515_write_register(0x2a,0x01);//100
   mcp2515_write_register(0x29,0xbf);
   mcp2515_write_register(0x28,0x02);
break;
// case 0x01080787:
// mcp2515_write_register(0x2a,0x01);//33.3
//    mcp2515_write_register(0x29,0xb5);
//    mcp2515_write_register(0x28,0x01);
// break;
case 0x010d025a:
mcp2515_write_register(0x2a,0x04);//50
   mcp2515_write_register(0x29,0xb5);
   mcp2515_write_register(0x28,0x01);
break;

}

mcp2515_bit_modify(0x0f,0xe0,0);
if(0 != ((mcp2515_read_register(CANSTAT))&0xE0))//ÅжÏMCP2515ÊÇ·ñÒѾ­½øÈëÕý³£Ä£Ê½
{
mcp2515_bit_modify(0x0f,0xe0,0);
}

return 1;
}




unsigned char buff1[15] = {0},buff[8];


void GPIOTE_IRQHandler(){


    if ((NRF_GPIOTE->EVENTS_IN[0] == 1) && 
        (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_IN0_Msk))
    {
        NRF_GPIOTE->EVENTS_IN[0] = 0;
    }
nrf_delay_ms(5);
int len = CAN_Receive_Buffer(buff1);
LED();
AddDataToBuffer(buff1,len);
}


void MCP2515_IRQ_Init(void) //?????
{
  
    nrf_gpio_cfg_input(26,NRF_GPIO_PIN_NOPULL);
    NRF_GPIOTE->CONFIG[0] =  (GPIOTE_CONFIG_POLARITY_HiToLo << 16) 
                           | (26<< 8UL)  
                           | (0x01);
    NRF_GPIOTE->INTENSET  = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;


    NVIC_EnableIRQ(GPIOTE_IRQn);
//    NVIC_SetPriority(GPIOTE_IRQn,3);//???????
}






uint8_t ExecuteMcu(uint16_t cmd,uint8_t *param,uint16_t len)
{
uint8_t ret=0;//0:¸ºÏìÓ¦Êý¾Ý 1£ºÕýÏìÓ¦Êý¾Ý  2:·µ»ØÊý¾Ý  3:²»·µ»ØÊý¾Ý
switch(cmd){
case CA_RESET_COMMBOX:
ret=ResetCommbox();
break;
case CA_ECU_commnication_model:
ret=SetProtocol(param[0]);
break;                                  //55 AA 00 00 00 05 FF FA 01 00 02 60 C1 5D
case CA_IO_Parameter:
// ret=SetCommPort((param[2]>>4)&0x0f,param[2]&0x0f,param[0]|(param[1]<<8));
 ret =1;
break;
case CA_ECU_COMMUNICATION_BAUD_RATE:
ret=SetBaudrate((param[0]<<24)|(param[1]<<16)|(param[2]<<8)|param[3]);
break;   
case CA_ECU_COMM_TIME_INTERVAL:
// ret=SetCommTime(
// (param[6]<<8)|param[7],
// (param[4]<<8)|param[5],
// (param[2]<<8)|param[3],
// (param[0]<<8)|param[1]
// );
 ret =1;
break;
case CA_IO_HI_LOW_Voltage:
ret=SetCommLevel(param[0]);
break;
case CA_SEND_M_FRAME_DATA:
ret=SendReceive(0,param,len);
break;
case CA_SEND_5BPS_DATA: //+
ret=AddrCodeEnter(0,param,len);
break;
case CA_SET_COMM_FILTER:
ret=SetCommFilter(param,len);
break;
case CA_SET_CAN_Filter:  // +
ret=SetCanFilter(param,len);
break;
case CA_SET_CAN_FLOW_CTRL:
ret=SetFlowControl(param,len);
break;
case CA_DELAY_TIM_MS:
ret=SetCommDelay((param[0]<<8)|param[1]);
break;
case CA_AFC_ENABLE_AND_DISABLE:
box.afc_flag=param[0];
ret=1;
break;
case CA_SET_BUSY_MODE:
ret=SetBusyCount(
(param[0]<<8)|param[1],
(param[2]<<8)|param[3],
(param[4]<<8)|param[5]
);
break;
case CA_ECU_LINK_KEEP:
ret=SetKeepLink(param,len); 
break;
case CA_LINK_KEEP_ENABLE_AND_DISABLE: 
box.link_flag=param[0];
// box.idle_tick=Clock();
ret=1; 
break;
case CA_JMP_BOOT:
RCC_ClearFlag();
EXTI_DeInit();
DMA_TX_WaitForLastTask();
DMA_RX_WaitForLastTask();
DelayMs(10);
DMA_Cmd(DMA1_Channel4,DISABLE);
ExecuteApplication(0x08000000);
ret=1;
break;
case CA_JMP_MCU:
ret=1;
break;
case CA_GET_STATE:
AddDataToBuffer("\x01",1);
ret=2;
break;
case CA_RESPOSE_SN:
ret = GetSerialNo();
break;

case CA_RESPOSE_VERSION:
AddDataToBuffer((uint8_t*)MyVer, 4);
ret = 2;
break;

case CA_RESPOSE_TIME_DATA: 
AddDataToBuffer((uint8_t*)MyDate,11);
ret=2;
break;

case CA_RESPOSE_CPU_ID: 
// ret = GetCpuId();
break;

case CA_RESPOSE_IO_ADC: 
// ret=GetIoAdc();
 ret = 1;
break;
case CA_AUTO_LOGGING:
box.log_flag=param[0];
ret=1;
break;
}
return ret;
}


static nrf_drv_adc_channel_t m_channel_config = NRF_DRV_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_6);


static void adc_event_handler(nrf_drv_adc_evt_t const * p_event)
{
    if (p_event->type == NRF_DRV_ADC_EVT_DONE)
    {
//        uint32_t i;
//        for (i = 0; i < p_event->data.done.size; i++)
//        {
           NRF_LOG_INFO("Current sample value: %d\r\n", p_event->data.done.p_buffer[i]);
//        }
    }
}


static void adc_config(void)
{
    ret_code_t ret_code;
    nrf_drv_adc_config_t config = NRF_DRV_ADC_DEFAULT_CONFIG;


    ret_code = nrf_drv_adc_init(&config, adc_event_handler);
    APP_ERROR_CHECK(ret_code);


    nrf_drv_adc_channel_enable(&m_channel_config);
}


static void wdt_level_meas_timeout_handle(void *p_context){


UNUSED_PARAMETER(p_context);
if(receive_uart[2] == 0x8A){
AddDataToBuffer(receive_uart,3);
memset(receive_uart,0,20);
}

}


uint32_t length = 0;
uint32_t rev_length = 0;




int main(void)
{
nrf_gpio_cfg_output(21);//can CS

nrf_gpio_cfg_output(30);
nrf_gpio_pin_set(30);

nrf_gpio_cfg_output(25);//can mode
nrf_gpio_pin_clear(25);

nrf_gpio_cfg_output(2);
nrf_gpio_cfg_output(3);
nrf_gpio_pin_set(2);
nrf_gpio_pin_set(3);

uint8_t ret = 0;
  uint16_t rev_length_temp= 0;


  uint32_t err_code;
  bool erase_bonds;
NRF_CLOCK->XTALFREQ=0x00;


    // Initialize.
    APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false);
app_timer_create(&m_wdt_timer_id,APP_TIMER_MODE_REPEATED,wdt_level_meas_timeout_handle);
app_timer_start(m_wdt_timer_id,WDT_LEVEL_MEAS_INTERVAL,NULL);

    uart_init();
spi_master_init(&m_spi_master_0);
log_init();
mcp2515_init();
adc_config();


    ble_stack_init();
    gap_params_init();
    services_init();
    advertising_init();
    conn_params_init();


    err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
    APP_ERROR_CHECK(err_code);

MCP2515_IRQ_Init();

err_code = app_fifo_init(&m_test_fifo,test_fifo,512);
APP_ERROR_CHECK(err_code);


// app_fifo_read(&m_test_fifo,data_test1,&length);
// NRF_LOG_INFO(":%d.\r\n", data_test1[0]);


while(1){

app_fifo_read(&m_test_fifo,NULL,&length);

if(length){
NRF_LOG_INFO("length:%d.\r\n",length);
app_fifo_read(&m_test_fifo,buffer,(uint32_t *)8);

rev_length = buffer[4] + buffer [5] + 1;
rev_length_temp = rev_length + 8;


app_fifo_read(&m_test_fifo,buffer + 8,&rev_length);
   if(RecvPacket(buffer, rev_length_temp))
    {
    ret = ExecuteCmd(buffer);
    SendDataToHost(ret);
memset(buffer,0,sizeof(buffer)/sizeof(buffer[0]));
  }
}

if(NRF_LOG_PROCESS() == false){

}


}
}
/**
 * @}

 */

box.函数

#include <stdint.h>
#include <string.h>
#include "box.h"
#include "nrf_delay.h"
#include "nrf_drv_adc.h"
#include "app_error.h"
#include "app_uart.h"
#include "spi.h"
#include "nrf_drv_uart.h"
#include "nrf_gpio.h"
#include "nrf_drv_rtc.h"
#include "nrf_drv_gpiote.h"


#include "nrf_log.h"
#include "nrf_log_ctrl.h"




extern uint8_t receive_uart[20];


static void LED(){


nrf_gpio_cfg_output(5);
nrf_gpio_pin_clear(5);
nrf_delay_ms(10);
nrf_gpio_pin_set(5);


}


uint8_t ResetCommbox(void)
{
box.protocol=PT_INVALID;
box.baudrate=10400;
box.io_param[0]=0;
box.io_param[1]=0;
box.io_param[2]=0;
box.b2b_time=5;
box.f2f_time=55;
box.out_time=800;
box.out_b2b=50;
box.filter_mode=FILTER_TIMEOUT;
box.afc_flag=0;
box.afc_time=0;
box.link_time=500;
box.link_flag=0;
box.IsWaitBeforeSendFrame=1;
box.max_7f78=65535;
box.max_7f21=65535;
box.max_7f23=65535;
box.flag_7fxx=0;
// box.TIM_VPWM=TIM2;
box.bosch_count=0;
box.log_flag=1;
return 1;
}




uint8_t SetCommTime(uint16_t b2b_time,uint16_t f2f_time,uint16_t out_time,uint16_t out_b2b)
{
box.b2b_time=b2b_time;
box.f2f_time=f2f_time;
box.out_time=out_time;
box.out_b2b=out_b2b;
return 1;
}


uint8_t SetProtocol(uint16_t nProtocol)
{
box.protocol=nProtocol&0x0F;
box.prot_type=(nProtocol>>8)&0x0F;
switch(box.protocol){
case PT_KWP:
box.protocol = 0x01;
     break;
case PT_CAN:
case PT_SINGEL_CAN:
box.protocol = 0x07;
break;
default:
break;
}
return 1;
}


uint8_t SetCommLevel(uint8_t nLevel)
{
// if(box.usart == NULL)return 1;
if(nLevel){
nrf_gpio_cfg_output(PIN_CPU_TXD);
nrf_gpio_cfg_input(PIN_CPU_RXD,NRF_GPIO_PIN_NOPULL);
nrf_gpio_pin_set(PIN_CPU_TXD);
nrf_gpio_pin_set(PIN_CPU_RXD);
}
else{
nrf_gpio_cfg_output(PIN_CPU_TXD);
nrf_gpio_cfg_input(PIN_CPU_RXD,NRF_GPIO_PIN_NOPULL);
nrf_gpio_pin_clear(PIN_CPU_TXD);
nrf_gpio_pin_clear(PIN_CPU_RXD);
}
box.IsWaitBeforeSendFrame=0;
return 1;
}


uint8_t SetCommFilter(uint8_t *param,uint16_t len)
{
box.filter_mode=param[0];
memcpy(box.filter_buff,param+1,len-1);
return 1;
}


uint8_t SetFlowControl(uint8_t *param,uint16_t len)
{
uint8_t length=2+param[1];
memcpy(box.afc_buff,param,length);
box.afc_buff[length]=0x00;
memcpy(box.afc_buff+length+1,param+length,len-length);
if(len>2+param[1]+1+param[2+param[1]]+1)box.afc_time=(param[len-2]<<8)|param[len-1];
if(param[length]==0)box.afc_flag=0;
else box.afc_flag=1;
return 1;
}


uint8_t SetCommDelay(uint16_t nDelay)
{
nrf_delay_ms(nDelay);
return 1;
}


uint8_t SetBusyCount(uint16_t max_7f78,uint16_t max_7f21,uint16_t max_7f23)
{
box.max_7f78=max_7f78;
box.max_7f21=max_7f21;
box.max_7f23=max_7f23;
return 1;
}


uint8_t SetKeepLink(uint8_t *param,uint16_t len)
{
uint16_t length=(param[0]<<8)|param[1];
box.link_time=(param[2+length+0]<<8)|param[2+length+1];
if(box.link_time<50)box.link_time=400;
memcpy(box.link_buff,param,length+2);
box.link_buff[length+2]=0x01;//????
box.link_num=1;
return 1;
}


extern struct tagResData resData;


uint8_t AddDataToBuffer(void *buff, uint16_t len)
{
if(resData.size + 2 + len > MAX_RES_DATA_SIZE)
{
return 0;
}
resData.buff[resData.size++] = (uint8_t)(len >> 8);
resData.buff[resData.size++] = (uint8_t)(len >> 0);

memcpy(resData.buff + resData.size , buff, len);

resData.size += len;
resData.count++;
return 1;
}


uint8_t MySn[] = "12";
uint8_t GetSerialNo(void)
{
char DataBuf[SN_LEN]= {0};

memcpy(DataBuf, MySn, 2);
//SeqEncrypt(0xD6AAB5C0,DataBuf,SN_LEN);
AddDataToBuffer(DataBuf,2);
return 2;
}


uint8_t GetCpuId(void)
{
uint8_t i = 0, DataBuf[12];

while(i < 12)
{
DataBuf[i] = *(volatile unsigned char*)(0x1FFFF7E8 + i);
i++;
}
AddDataToBuffer(DataBuf, 12);

return 2;
}


nrf_adc_value_t adc_buffer[10] = {0};
#define ADC_BUFFER_SIZE (sizeof(adc_buffer) / sizeof(adc_buffer[0]))


uint16_t GetAveValue(void)
{
 uint16_t adc;
APP_ERROR_CHECK(nrf_drv_adc_buffer_convert(adc_buffer,ADC_BUFFER_SIZE));
uint32_t i;
for (i = 0; i < ADC_BUFFER_SIZE; i++)
{
// manually trigger ADC conversion
nrf_drv_adc_sample();
// enter into sleep mode
__SEV();
__WFE();
__WFE();
adc += adc_buffer[i];
nrf_delay_ms(100);
}
return adc/ADC_BUFFER_SIZE;
}




uint8_t GetIoAdc(void)
{
uint8_t DataBuf[2];
uint16_t adc=GetAveValue();
DataBuf[0]= (uint8_t)(adc>>8);
DataBuf[1]= (uint8_t)(adc>>0);
AddDataToBuffer(DataBuf,2);
return 2;
}


void SendDataWaitIdle(void)
{
uint32_t iTimeout=0;
if(box.IsWaitBeforeSendFrame==0)return;

}


uint8_t *g_pSendReceive = NULL;
uint8_t *Plen = NULL;
static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE);


int SendFrame(uint8_t *pSendFrame)
{
int iLength = 0,i = 0;
uint8_t flage = 0;
box.protocol =0x01;

g_pSendReceive = pSendFrame;
switch(box.protocol)
{
case PT_NORMAL:
case PT_ISO:
break;


case PT_KWP:
g_pSendReceive = g_pSendReceive + 1;
   for (uint32_t i = 1; i < *g_pSendReceive + 1; i++)
    {
        while(app_uart_put(g_pSendReceive[i]) != NRF_SUCCESS);
        nrf_delay_ms(1);
    }
nrf_delay_ms(10);

     while(1){
if((receive_uart[6] != 0) && (receive_uart[13] != 0)){
 Plen = receive_uart + 6;
 AddDataToBuffer(Plen,8);
 break;
     }
 nrf_delay_us(1);
  }
break;


case PT_CAN:
case PT_SINGEL_CAN:

if(pSendFrame[2]&0x80)
{
Can_send(pSendFrame + 3,pSendFrame+7,2);
nrf_delay_ms(60);

}
else
{
Can_send(pSendFrame + 3,pSendFrame+5,1);
nrf_delay_ms(60);
}
break;
}
return iLength;
}




#define RFN_AUTO 0xFF
#define RFN_LOOP 0xFE
#define RFN_MULT 0xFC


CReceiveFrame rf;
struct tagEcuData ecuData;
uint8_t AddDataToFrame(void *buff,uint16_t len)
{
if(ecuData.size+2+len>MAX_ECU_DATA_SIZE)return 0;
ecuData.buff[ecuData.size++]=(uint8_t)(len>>8);
ecuData.buff[ecuData.size++]=(uint8_t)(len>>0);
memcpy(ecuData.buff+ecuData.size,buff,len);


rf.frame[rf.count].size=len;
rf.frame[rf.count].buff=ecuData.buff+ecuData.size;
rf.count++;


ecuData.size+=len;
ecuData.count++;
return 1;
}


void AddDataToHello(uint8_t flag,void *buff,uint16_t len)
{
if(flag==0)AddDataToBuffer(buff,len);
else AddDataToFrame(buff,len);
}




uint8_t SendReceive(uint8_t flag, uint8_t *param, uint16_t length)
{


uint8_t *pFrm = param;
uint16_t len = (pFrm[0] << 8) + pFrm[1];


if(len > 0)
{
SendFrame(param);
}
return 2;
}


void panduan_up_low(uint8_t i)
{
if(i)
{
   nrf_gpio_pin_set(PIN_CPU_TXD);
 nrf_delay_ms(200);
 }
else
{
 
nrf_gpio_pin_clear(PIN_CPU_TXD);
   nrf_delay_ms(200);
}
}



void Send5BpsToEcu(uint8_t ucAddrCode)
{
panduan_up_low(ucAddrCode & 0x00);
panduan_up_low(ucAddrCode & 0x01);
panduan_up_low(ucAddrCode & 0x02);
panduan_up_low(ucAddrCode & 0x04);
panduan_up_low(ucAddrCode & 0x08);
panduan_up_low(ucAddrCode & 0x10);
panduan_up_low(ucAddrCode & 0x20);
panduan_up_low(ucAddrCode & 0x40);
panduan_up_low(ucAddrCode & 0x80);
nrf_gpio_pin_set(PIN_CPU_TXD);
nrf_delay_ms(10);
}




 extern void uart_init(void);


uint8_t AddrCodeEnter(uint8_t flag,uint8_t *param,uint16_t len)
{
// uint8_t ucReverseWaitTime=param[0];
uint8_t ucAddress=param[1];
uint32_t uBps = (param[6]<<24)|(param[7]<<16)|(param[8]<<8)|param[9];
uint8_t length,i = 0;
// memset(receive_uart,0,20);


if(uBps==5){

nrf_drv_uart_uninit(&app_uart_inst);
nrf_gpio_cfg_output(PIN_CPU_TXD);
nrf_delay_ms(1);
Send5BpsToEcu(ucAddress);
uart_init();
nrf_delay_ms(10);
}
while(1){
if(receive_uart[2] != 0){

   AddDataToBuffer(receive_uart,3);
break;
}
nrf_delay_us(1);
}
    return 2;
}


uint8_t SetCanFilter(uint8_t *param,uint16_t len)
{
box.canid_len=len;
memcpy(box.canid_buff,param,len);

// mcp2515_bit_modify(0x0f,0xe0,0x80);
//
// if(len > 5){
//
mcp2515_write_register(0x00,(box.canid_buff[1]<<3) | (box.canid_buff[2] >> 5));
mcp2515_write_register(0x03,((box.canid_buff[2]<<3) &0xE0) | 0x1C | (box.canid_buff[2] & 0x03));
mcp2515_write_register(0x06,box.canid_buff[3]);
mcp2515_write_register(0x07,box.canid_buff[4]);
//
mcp2515_write_register(0x22,box.canid_buff[5]);
mcp2515_write_register(0x23,box.canid_buff[6]);
mcp2515_write_register(0x26,box.canid_buff[7]);
mcp2515_write_register(0x27,box.canid_buff[8]);
//
// }else{
//
// mcp2515_write_register(0x00,(box.canid_buff[1]<<5) | (box.canid_buff[2] >> 3));
// mcp2515_write_register(0x01,(box.canid_buff[2]<<5));
//
mcp2515_write_register(0x20,(box.canid_buff[3]<<5) | (box.canid_buff[4] >> 3));
mcp2515_write_register(0x21,(box.canid_buff[4]<<5));
//
// }
// mcp2515_bit_modify(0x0f,0xe0,0);
// if(0 != ((mcp2515_read_register(CANSTAT))&0xE0))//ÅжÏMCP2515ÊÇ·ñÒѾ­½øÈëÕý³£Ä£Ê½
// {
// mcp2515_bit_modify(0x0f,0xe0,0);
// }
return 1;
}


uint8_t SetIoPort(uint8_t Prot, uint8_t *Param, uint16_t Len)
{
uint8_t IoTx = (Param[2] >> 4) & 0x0F;
uint8_t IoRx = Param[2] & 0x0F;


if((OBDII_P14 == IoTx) && (OBDII_P6 == IoRx))
{
// HW_LLineCmd(DISABLE);
// HW_CANCmd(ENABLE);
nrf_gpio_cfg_output(25);//can mode
nrf_gpio_pin_clear(25);
}
else
{
if(OBDII_P7 == IoRx)
{
nrf_gpio_cfg_output(2);
nrf_gpio_cfg_output(3);
nrf_gpio_pin_set(2);
nrf_gpio_pin_set(3);
}
}

return 1;
}


void EnableLLine(void)
{
nrf_gpio_pin_set(PIN_L_LINE_CTRL);
}


uint8_t SetCommPort(uint8_t nSendLine,uint8_t nRecvLine,uint16_t nLinkCtrl)
{
uint8_t param[3];

param[0]=nLinkCtrl>>0;
param[1]=nLinkCtrl>>8;
param[2]=((nSendLine<<4)&0xF0)|(nRecvLine&0x0F);

if(memcmp(box.io_param, param, 3))
{
memcpy(box.io_param, param, 3);
SetIoPort(box.protocol, param, 3);
}
else
{
if(((param[2]>>4)&0xf)==OBDII_P15)
EnableLLine();
}

return 1;
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值