#ifndef Basic_h
#define Basic_h
#include "MicroBit.h"
#include "delay.h"

// Pin ID
const uint32_t g_PinID[] = {
    MICROBIT_ID_IO_P0,
    MICROBIT_ID_IO_P1,
    MICROBIT_ID_IO_P2,
    MICROBIT_ID_IO_P3,
    MICROBIT_ID_IO_P4,
    MICROBIT_ID_IO_P5,
    MICROBIT_ID_IO_P6,
    MICROBIT_ID_IO_P7,
    MICROBIT_ID_IO_P8,
    MICROBIT_ID_IO_P9,
    MICROBIT_ID_IO_P10,
    MICROBIT_ID_IO_P11,
    MICROBIT_ID_IO_P12,
    MICROBIT_ID_IO_P13,
    MICROBIT_ID_IO_P14,
    MICROBIT_ID_IO_P15,
    MICROBIT_ID_IO_P16,
    MICROBIT_ID_IO_P19,
    MICROBIT_ID_IO_P20
};

const uint32_t g_ADigitalPinMap[] = {
  MICROBIT_PIN_P0,  // io3 is the left most pad (ANALOG/DIGITAL) used to be P0_3 on green board
  MICROBIT_PIN_P1,  // io2 is the middle pad (ANALOG/DIGITAL)
  MICROBIT_PIN_P2,  // io1 is the right most pad (ANALOG/DIGITAL) used to be P0_1 on green board
  MICROBIT_PIN_P3,  // io4 COL1 (ANALOG/DIGITAL)
  MICROBIT_PIN_P4,  // io5 COL2 (ANALOG/DIGITAL)
  MICROBIT_PIN_P5,  // io17 BTN_A
  MICROBIT_PIN_P6,  // io12 COL9
  MICROBIT_PIN_P7,  // io17 COL8
  MICROBIT_PIN_P8,  // io18 PIN 18
  MICROBIT_PIN_P9,  // io10 COL7
  MICROBIT_PIN_P10, // io6 COL3 (ANALOG/DIGITAL)
  MICROBIT_PIN_P11, // io26 BTN_B
  MICROBIT_PIN_P12, // io20 PIN 20
  MICROBIT_PIN_P13, // io23 SCK
  MICROBIT_PIN_P14, // io22 MISO
  MICROBIT_PIN_P15, // io21 MOSI
  MICROBIT_PIN_P16, // io16 PIN 16
  (uint32_t)-1,     // 3.3V
  (uint32_t)-1,     // 3.3V
  MICROBIT_PIN_P19,  // io0 SCL
  MICROBIT_PIN_P20,  // io30 SDA
};

extern MicroBit uBit;
void yield(void);
void init(void);
MicroBitPin *getMicroBitPin(int id);

// 无线烧录相关
#if CONFIG_ENABLED(MICROBIT_RADIO_BRUN)
// Status Flags
#define MICROBIT_RADIO_STATUS_INITIALISED       0x0001
// Default configuration values
#define MICROBIT_RADIO_BASE_ADDRESS             0x87654321
#define MICROBIT_RADIO_DEFAULT_GROUP            0x123456FF
#define MICROBIT_RADIO_DEFAULT_TX_POWER         7
#define MICROBIT_RADIO_DEFAULT_FREQUENCY        0
#define MICROBIT_RADIO_MAX_PACKET_SIZE          64
#define MICROBIT_RADIO_BURN_MAX_PACKET_SIZE     240
#define MICROBIT_RADIO_HEADER_SIZE              4
#define MICROBIT_RADIO_MAXIMUM_RX_BUFFERS       4
//PCNF0
#define PACKET_S1_FIELD_SIZE                    (0UL)
#define PACKET_S0_FIELD_SIZE                    (0UL)
#define PACKET_LENGTH_FIELD_SIZE                (8UL)
//PCNF1
#define RADIO_PCNF1_WHITEEN_DISABLE             (0UL)
#define RADIO_PCNF1_ENDIAN_BIG                  (1UL)
#define PACKET_BASE_ADDRESS_LENGTH              (4UL)
#define PACKET_STATIC_LENGTH                    (0UL)
// Known Protocol Numbers
#define MICROBIT_RADIO_PROTOCOL_DATAGRAM        1
#define MICROBIT_RADIO_PROTOCOL_EVENTBUS        2
// Events
#define MICROBIT_RADIO_EVT_DATAGRAM             1

#define ApplicationAddressBase    (0x00008000UL)
#define VectorTableBase           (0x00007800UL)
#define ApplicationCheckAddress   (VectorTableBase + 0x00000400UL) //0x00007c04UL

typedef struct radioFrameBuffer
{
    uint8_t     length;                             // 数据包中剩余字节的长度。包括协议/版本/组字段，不包括长度字段本身。
    uint8_t     version;                            // 协议版本号。
    uint8_t     group;                              // 此包所属组的ID。
    uint8_t     protocol;                           // 内部协议编号c.f. 由IANA为IP协议而发布的。

    uint8_t     payload[MICROBIT_RADIO_MAX_PACKET_SIZE]; // 用户/上层协议数据。
    int         rssi;                               // 接收到此包的信号强度。
}RadioFrameBuffer;

typedef struct radioConfig
{
    uint32_t    baseAddress;                        //无线通讯地址
    uint8_t     channel;                            //通道
    int         power;                              //发射功率
    int         frequencyBand;                      //频带
    int         speed;                              //数据发送速度
    int         maxSize;                            //用户上层协议字段长度
}RadioConfig;

typedef int (*radio_callback_t)(uint8_t *p_data);


void radioBrunHandle(void);
void radioBrunInit();
int  radioEnable(RadioConfig *config);
int  radioDisable(void);
int  radioSetGroup(uint8_t _group);
int  radioSend(uint8_t *buffer, uint8_t len);
void radioRegisterCallback(radio_callback_t callback_handler);
int  radioSendConfig(RadioFrameBuffer *buffer);
int  radioSetTransmitPower(int power);
int  radioSetFrequencyBand(int band);
int  radioTransmissionHandle(uint8_t *p_data);
int  radioDisconnect(char *cmd, uint8_t *p_data);
void radioBroadcast(void);
bool isConnection(void);
void getBoardName(char *name);
uint32_t getAddress(void);
uint8_t getChannel(void);
void saveConnectFlag(bool flag);
void setBoardName(char *name);
void nvmcPageErase(uint32_t address);
void nvmcWriteBytes(uint32_t address, const uint8_t * src, uint32_t num_bytes);
#endif

#endif // Basic_h