#include //#include //#include //#include //#include //#include //#include #include #include //#include #define GPIO3 0x04 #define GPIO2 0x08 /*********************************************************************************/ /****************************************************************************** * CONSTANTS */ /* configuration registers */ #define CC112X_IOCFG3 0x0000 #define CC112X_IOCFG2 0x0001 #define CC112X_IOCFG1 0x0002 #define CC112X_IOCFG0 0x0003 #define CC112X_SYNC3 0x0004 #define CC112X_SYNC2 0x0005 #define CC112X_SYNC1 0x0006 #define CC112X_SYNC0 0x0007 #define CC112X_SYNC_CFG1 0x0008 #define CC112X_SYNC_CFG0 0x0009 #define CC112X_DEVIATION_M 0x000A #define CC112X_MODCFG_DEV_E 0x000B #define CC112X_DCFILT_CFG 0x000C #define CC112X_PREAMBLE_CFG1 0x000D #define CC112X_PREAMBLE_CFG0 0x000E #define CC112X_FREQ_IF_CFG 0x000F #define CC112X_IQIC 0x0010 #define CC112X_CHAN_BW 0x0011 #define CC112X_MDMCFG1 0x0012 #define CC112X_MDMCFG0 0x0013 #define CC112X_SYMBOL_RATE2 0x0014 #define CC112X_SYMBOL_RATE1 0x0015 #define CC112X_SYMBOL_RATE0 0x0016 #define CC112X_AGC_REF 0x0017 #define CC112X_AGC_CS_THR 0x0018 #define CC112X_AGC_GAIN_ADJUST 0x0019 #define CC112X_AGC_CFG3 0x001A #define CC112X_AGC_CFG2 0x001B #define CC112X_AGC_CFG1 0x001C #define CC112X_AGC_CFG0 0x001D #define CC112X_FIFO_CFG 0x001E #define CC112X_DEV_ADDR 0x001F #define CC112X_SETTLING_CFG 0x0020 #define CC112X_FS_CFG 0x0021 #define CC112X_WOR_CFG1 0x0022 #define CC112X_WOR_CFG0 0x0023 #define CC112X_WOR_EVENT0_MSB 0x0024 #define CC112X_WOR_EVENT0_LSB 0x0025 #define CC112X_PKT_CFG2 0x0026 #define CC112X_PKT_CFG1 0x0027 #define CC112X_PKT_CFG0 0x0028 #define CC112X_RFEND_CFG1 0x2F//0x2F29//0x0029-- will go to Tx mode after Rx #define CC112X_RFEND_CFG0 0x30//0x302A//0x002A-- will go to Rx mode after Tx #define CC112X_PA_CFG2 0x002B #define CC112X_PA_CFG1 0x002C #define CC112X_PA_CFG0 0x002D #define CC112X_PKT_LEN 0x002E /* Extended Configuration Registers */ #define CC112X_IF_MIX_CFG 0x2F00 #define CC112X_FREQOFF_CFG 0x2F01 #define CC112X_TOC_CFG 0x2F02 #define CC112X_MARC_SPARE 0x2F03 #define CC112X_ECG_CFG 0x2F04 #define CC112X_CFM_DATA_CFG 0x2F05 #define CC112X_EXT_CTRL 0x2F06 #define CC112X_RCCAL_FINE 0x2F07 #define CC112X_RCCAL_COARSE 0x2F08 #define CC112X_RCCAL_OFFSET 0x2F09 #define CC112X_FREQOFF1 0x2F0A #define CC112X_FREQOFF0 0x2F0B #define CC112X_FREQ2 0x2F0C #define CC112X_FREQ1 0x2F0D #define CC112X_FREQ0 0x2F0E #define CC112X_IF_ADC2 0x2F0F #define CC112X_IF_ADC1 0x2F10 #define CC112X_IF_ADC0 0x2F11 #define CC112X_FS_DIG1 0x2F12 #define CC112X_FS_DIG0 0x2F13 #define CC112X_FS_CAL3 0x2F14 #define CC112X_FS_CAL2 0x2F15 #define CC112X_FS_CAL1 0x2F16 #define CC112X_FS_CAL0 0x2F17 #define CC112X_FS_CHP 0x2F18 #define CC112X_FS_DIVTWO 0x2F19 #define CC112X_FS_DSM1 0x2F1A #define CC112X_FS_DSM0 0x2F1B #define CC112X_FS_DVC1 0x2F1C #define CC112X_FS_DVC0 0x2F1D #define CC112X_FS_LBI 0x2F1E #define CC112X_FS_PFD 0x2F1F #define CC112X_FS_PRE 0x2F20 #define CC112X_FS_REG_DIV_CML 0x2F21 #define CC112X_FS_SPARE 0x2F22 #define CC112X_FS_VCO4 0x2F23 #define CC112X_FS_VCO3 0x2F24 #define CC112X_FS_VCO2 0x2F25 #define CC112X_FS_VCO1 0x2F26 #define CC112X_FS_VCO0 0x2F27 #define CC112X_GBIAS6 0x2F28 #define CC112X_GBIAS5 0x2F29 #define CC112X_GBIAS4 0x2F2A #define CC112X_GBIAS3 0x2F2B #define CC112X_GBIAS2 0x2F2C #define CC112X_GBIAS1 0x2F2D #define CC112X_GBIAS0 0x2F2E #define CC112X_IFAMP 0x2F2F #define CC112X_LNA 0x2F30 #define CC112X_RXMIX 0x2F31 #define CC112X_XOSC5 0x2F32 #define CC112X_XOSC4 0x2F33 #define CC112X_XOSC3 0x2F34 #define CC112X_XOSC2 0x2F35 #define CC112X_XOSC1 0x2F36 #define CC112X_XOSC0 0x2F37 #define CC112X_ANALOG_SPARE 0x2F38 #define CC112X_PA_CFG3 0x2F39 #define CC112X_IRQ0M 0x2F3F #define CC112X_IRQ0F 0x2F40 /* Status Registers */ #define CC112X_WOR_TIME1 0x2F64 #define CC112X_WOR_TIME0 0x2F65 #define CC112X_WOR_CAPTURE1 0x2F66 #define CC112X_WOR_CAPTURE0 0x2F67 #define CC112X_BIST 0x2F68 #define CC112X_DCFILTOFFSET_I1 0x2F69 #define CC112X_DCFILTOFFSET_I0 0x2F6A #define CC112X_DCFILTOFFSET_Q1 0x2F6B #define CC112X_DCFILTOFFSET_Q0 0x2F6C #define CC112X_IQIE_I1 0x2F6D #define CC112X_IQIE_I0 0x2F6E #define CC112X_IQIE_Q1 0x2F6F #define CC112X_IQIE_Q0 0x2F70 #define CC112X_RSSI1 0x2F71 #define CC112X_RSSI0 0x2F72 #define CC112X_MARCSTATE 0x2F73 #define CC112X_LQI_VAL 0x2F74 #define CC112X_PQT_SYNC_ERR 0x2F75 #define CC112X_DEM_STATUS 0x2F76 #define CC112X_FREQOFF_EST1 0x2F77 #define CC112X_FREQOFF_EST0 0x2F78 #define CC112X_AGC_GAIN3 0x2F79 #define CC112X_AGC_GAIN2 0x2F7A #define CC112X_AGC_GAIN1 0x2F7B #define CC112X_AGC_GAIN0 0x2F7C #define CC112X_CFM_RX_DATA_OUT 0x2F7D #define CC112X_CFM_TX_DATA_IN 0x2F7E #define CC112X_ASK_SOFT_RX_DATA 0x2F7F #define CC112X_RNDGEN 0x2F80 #define CC112X_MAGN2 0x2F81 #define CC112X_MAGN1 0x2F82 #define CC112X_MAGN0 0x2F83 #define CC112X_ANG1 0x2F84 #define CC112X_ANG0 0x2F85 #define CC112X_CHFILT_I2 0x2F86 #define CC112X_CHFILT_I1 0x2F87 #define CC112X_CHFILT_I0 0x2F88 #define CC112X_CHFILT_Q2 0x2F89 #define CC112X_CHFILT_Q1 0x2F8A #define CC112X_CHFILT_Q0 0x2F8B #define CC112X_GPIO_STATUS 0x2F8C #define CC112X_FSCAL_CTRL 0x2F8D #define CC112X_PHASE_ADJUST 0x2F8E #define CC112X_PARTNUMBER 0x2F8F #define CC112X_PARTVERSION 0x2F90 #define CC112X_SERIAL_STATUS 0x2F91 #define CC112X_MODEM_STATUS1 0x2F92 #define CC112X_MODEM_STATUS0 0x2F93 #define CC112X_MARC_STATUS1 0x2F94 #define CC112X_MARC_STATUS0 0x2F95 #define CC112X_PA_IFAMP_TEST 0x2F96 #define CC112X_FSRF_TEST 0x2F97 #define CC112X_PRE_TEST 0x2F98 #define CC112X_PRE_OVR 0x2F99 #define CC112X_ADC_TEST 0x2F9A #define CC112X_DVC_TEST 0x2F9B #define CC112X_ATEST 0x2F9C #define CC112X_ATEST_LVDS 0x2F9D #define CC112X_ATEST_MODE 0x2F9E #define CC112X_XOSC_TEST1 0x2F9F #define CC112X_XOSC_TEST0 0x2FA0 #define CC112X_RXFIRST 0x2FD2 #define CC112X_TXFIRST 0x2FD3 #define CC112X_RXLAST 0x2FD4 #define CC112X_TXLAST 0x2FD5 #define CC112X_NUM_TXBYTES 0x2FD6 /* Number of bytes in TXFIFO */ #define CC112X_NUM_RXBYTES 0x2FD7 /* Number of bytes in RXFIFO */ #define CC112X_FIFO_NUM_TXBYTES 0x2FD8 #define CC112X_FIFO_NUM_RXBYTES 0x2FD9 /* DATA FIFO Access */ #define CC112X_SINGLE_TXFIFO 0x003F /* TXFIFO - Single accecss to Transmit FIFO */ #define CC112X_BURST_TXFIFO 0x007F /* TXFIFO - Burst accecss to Transmit FIFO */ #define CC112X_SINGLE_RXFIFO 0x00BF /* RXFIFO - Single accecss to Receive FIFO */ #define CC112X_BURST_RXFIFO 0x00FF /* RXFIFO - Busrrst ccecss to Receive FIFO */ #define CC112X_LQI_CRC_OK_BM 0x80 #define CC112X_LQI_EST_BM 0x7F /* Command strobe registers */ #define CC112X_SRES 0x30 /* SRES - Reset chip. */ #define CC112X_SFSTXON 0x31 /* SFSTXON - Enable and calibrate frequency synthesizer. */ #define CC112X_SXOFF 0x32 /* SXOFF - Turn off crystal oscillator. */ #define CC112X_SCAL 0x33 /* SCAL - Calibrate frequency synthesizer and turn it off. */ #define CC112X_SRX 0x34 /* SRX - Enable RX. Perform calibration if enabled. */ #define CC112X_STX 0x35 /* STX - Enable TX. If in RX state, only enable TX if CCA passes. */ #define CC112X_SIDLE 0x36 /* SIDLE - Exit RX / TX, turn off frequency synthesizer. */ #define CC112X_SWOR 0x38 /* SWOR - Start automatic RX polling sequence (Wake-on-Radio) */ #define CC112X_SPWD 0x39 /* SPWD - Enter power down mode when CSn goes high. */ #define CC112X_SFRX 0x3A /* SFRX - Flush the RX FIFO buffer. */ #define CC112X_SFTX 0x3B /* SFTX - Flush the TX FIFO buffer. */ #define CC112X_SWORRST 0x3C /* SWORRST - Reset real time clock. */ #define CC112X_SNOP 0x3D /* SNOP - No operation. Returns status byte. */ #define CC112X_AFC 0x37 /* AFC - Automatic Frequency Correction */ /* Chip states returned in status byte */ #define CC112X_STATE_IDLE 0x00 #define CC112X_STATE_RX 0x10 #define CC112X_STATE_TX 0x20 #define CC112X_STATE_FSTXON 0x30 #define CC112X_STATE_CALIBRATE 0x40 #define CC112X_STATE_SETTLING 0x50 #define CC112X_STATE_RXFIFO_ERROR 0x60 #define CC112X_STATE_TXFIFO_ERROR 0x70 /*********************************************************************************************/ /****************FROM hal_spi_rf_trxeb.c*******************************************/ /****************************************************************************** * CONSTANTS */ #define TRXEM_PORT_SEL P3SEL #define TRXEM_PORT_OUT P3OUT #define TRXEM_PORT_DIR P3DIR #define TRXEM_PORT_IN P3IN #define TRXEM_SPI_MOSI_PIN BIT1// BIT4 #define TRXEM_SPI_MISO_PIN BIT2// BIT5 #define TRXEM_SPI_SCLK_PIN BIT3 //BIT3 #define TRXEM_SPI_SC_N_PIN BIT0 //BIT0 #define RF_RESET_N_PORT_OUT P8OUT #define RF_RESET_N_PORT_SEL P8SEL #define RF_RESET_N_PORT_DIR P8DIR #define RF_RESET_N_PIN BIT0 #define RADIO_BURST_ACCESS 0x40 #define RADIO_SINGLE_ACCESS 0x00 #define RADIO_READ_ACCESS 0x80 #define RADIO_WRITE_ACCESS 0x00 /* Bit fields in the chip status byte */ #define STATUS_CHIP_RDYn_BM 0x80 #define STATUS_STATE_BM 0x70 #define STATUS_FIFO_BYTES_AVAILABLE_BM 0x0F /******************************************************************************/ /******** * FROM bsp.c */ #define BSP_FLASH_CS_N BIT6 #define BSP_IO_SPI0_BUS_BASE __MSP430_BASEADDRESS_PORT9_R__ #define BSP_IO_SPI0_PORT 9 #define BSP_IO_SPI0_MOSI BIT1 //! P9.1 #define BSP_IO_SPI0_MISO BIT2 //! P9.2 #define BSP_IO_SPI0_SCLK BIT3 //! P9.3 #define BSP_IO_SPI0 1 #define BSP_IO_SPI1 2 #define BSP_IO_SPI1_BUS_BASE __MSP430_BASEADDRESS_PORT9_R__ #define BSP_IO_SPI1_PORT 9 #define BSP_IO_SPI1_MOSI BIT4 //! P9.4 #define BSP_IO_SPI1_MISO BIT5 //! P9.5 #define BSP_IO_SPI1_SCLK BIT0 //! P9.0 #define BSP_LED_1 BIT0 //!< P4.0 #define BSP_LED_2 BIT1 //!< P4.1 #define BSP_LED_3 BIT2 //!< P4.2 #define BSP_LED_4 BIT3 //!< P4.3 #define BSP_LED_ALL (BSP_LED_1 | \ BSP_LED_2 | \ BSP_LED_3 | \ BSP_LED_4) #define DCO_MULT_1MHZ 30 #define DCO_MULT_4MHZ 122 #define DCO_MULT_8MHZ 244 #define DCO_MULT_12MHZ 366 #define DCO_MULT_16MHZ 488 #define DCO_MULT_20MHZ 610 #define DCO_MULT_25MHZ 763 #define DCORSEL_1MHZ DCORSEL_2 #define DCORSEL_4MHZ DCORSEL_4 #define DCORSEL_8MHZ DCORSEL_4 #define DCORSEL_12MHZ DCORSEL_5 #define DCORSEL_16MHZ DCORSEL_5 #define DCORSEL_20MHZ DCORSEL_6 #define DCORSEL_25MHZ DCORSEL_7 #define VCORE_1MHZ PMMCOREV_0 #define VCORE_4MHZ PMMCOREV_0 #define VCORE_8MHZ PMMCOREV_0 #define VCORE_12MHZ PMMCOREV_1 #define VCORE_16MHZ PMMCOREV_1 #define VCORE_20MHZ PMMCOREV_2 #define VCORE_25MHZ PMMCOREV_3 #define VCORE_1_35V PMMCOREV_0 #define VCORE_1_55V PMMCOREV_1 #define VCORE_1_75V PMMCOREV_2 #define VCORE_1_85V PMMCOREV_3 #define BSP_SYS_CLK_1MHZ 1000000ul #define BSP_SYS_CLK_4MHZ 4000000ul #define BSP_SYS_CLK_8MHZ 8000000ul #define BSP_SYS_CLK_12MHZ 12000000ul #define BSP_SYS_CLK_16MHZ 16000000ul #define BSP_SYS_CLK_20MHZ 20000000ul #define BSP_SYS_CLK_25MHZ 25000000ul // //! Default system clock speed // #define BSP_SYS_CLK_SPD BSP_SYS_CLK_8MHZ // //! Default IO SPI0 clock speed // #define BSP_FLASH_LCD_SPI_SPD BSP_SYS_CLK_SPD #define BSP_FLASH_LCD_SPI BSP_IO_SPI0 // LCD defines // #define BSP_LCD_SPI BSP_IO_SPI0 #define BSP_LCD_SPI_PORT BSP_IO_SPI0_PORT #define BSP_LCD_SPI_BUS_BASE BSP_IO_SPI0_BUS_BASE #define BSP_LCD_MOSI BSP_IO_SPI0_MOSI #define BSP_LCD_MISO BSP_IO_SPI1_MISO #define BSP_LCD_SCLK BSP_IO_SPI1_SCLK #define BSP_LCD_CS_N_BASE __MSP430_BASEADDRESS_PORT9_R__ #define BSP_LCD_CS_N_PORT 9 #define BSP_LCD_CS_N BIT6 //! P9.6 #define BSP_LCD_PWR_BASE __MSP430_BASEADDRESS_PORT7_R__ #define BSP_LCD_PWR_PORT 7 #define BSP_LCD_PWR BIT7 //! P7.7 #define BSP_LCD_RST_BASE __MSP430_BASEADDRESS_PORT7_R__ #define BSP_LCD_RST_PORT 7 #define BSP_LCD_RST BIT3 //! P7.3 #define BSP_LCD_MODE_BASE __MSP430_BASEADDRESS_PORT9_R__ #define BSP_LCD_MODE_PORT 9 #define BSP_LCD_MODE BIT7 //! P9.7 (aka. LCD A0) #define BSP_KEY_1 BIT1 //!< P2.1 #define BSP_KEY_2 BIT2 //!< P2.2 #define BSP_KEY_3 BIT4 //!< P2.4 #define BSP_KEY_4 BIT5 //!< P2.5 #define BSP_KEY_5 BIT3 //!< P2.3 #define BSP_KEY_ALL (BSP_KEY_1| \ BSP_KEY_2| \ BSP_KEY_3| \ BSP_KEY_4| \ BSP_KEY_5) //!< Bitmask of all keys /**************************************************************/ #define BSP_KEY_DEBOUNCE(expr) { uint16_t i; for (i=0; i<500; i++) { \ if (!(expr)) i = 0; } } /*********************************************************************/ typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef uint8_t uint_fast8_t; /**********************************************************************/ /**********from lcd_trxeb.c*************************/ /* Port to use for display */ #define LCD_CS_A0_OUT P9OUT #define LCD_CS_A0_DIR P9DIR #define LCD_CS_A0_SEL P9SEL #define LCD_RST_OUT P7OUT #define LCD_RST_DIR P7DIR #define LCD_RST_SEL P7SEL #define LCD_SPI_BUS_SEL P9SEL #define LCD_PWR_OUT P7OUT #define LCD_PWR_DIR P7DIR #define LCD_PWR_SEL P7SEL #define LCD_PWR_DS P7DS //! Condition for SPI TX-buffer to be ready for new data #define LCD_TX_BUF_READY() (UCB2IFG & UCTXIFG) //! Condition for SPI transmission to be completed. #define LCD_TX_BUSY() (UCB2STAT & UCBUSY) //! Macro for asserting LCD CSn (set low) #define LCD_SPI_BEGIN() (LCD_CS_A0_OUT &= ~(BSP_LCD_CS_N)) //! Macro for deasserting LCD CSn (set high) #define LCD_SPI_END() (LCD_CS_A0_OUT |= BSP_LCD_CS_N) //! Macro for setting LCD mode signal low (command) #define LCD_MODE_SET_CMD() (LCD_CS_A0_OUT &= ~BSP_LCD_MODE) //! Macro for setting LCD mode signal (data) #define LCD_MODE_SET_DATA() (LCD_CS_A0_OUT |= BSP_LCD_MODE) /*******************************************************/ // Ambient light sensor defines // #define BSP_ALS_BASE __MSP430_BASEADDRESS_PORT6_R__ #define BSP_ALS_PORT 6 #define BSP_ALS_PWR BIT1 //!< P6.1 #define BSP_ALS_OUT BIT2 //!< P6.2 #define BSP_KEY_LEFT BSP_KEY_1 #define BSP_KEY_RIGHT BSP_KEY_2 #define BSP_KEY_UP BSP_KEY_3 #define BSP_KEY_DOWN BSP_KEY_4 #define BSP_KEY_SELECT BSP_KEY_5 #define BSP_KEY_DIR_ALL (BSP_KEY_LEFT | \ BSP_KEY_RIGHT| \ BSP_KEY_UP | \ BSP_KEY_DOWN) //!< Bitmask of all dir. keys #define BSP_KEY_DIR P2DIR #define BSP_KEY_SEL P2SEL #define BSP_KEY_OUT P2OUT #define BSP_KEY_IN P2IN #define BSP_KEY_REN P2REN //!< Resistor enable register #define BSP_KEY_IE P2IE //!< Interrupt enable register #define BSP_KEY_IFG P2IFG //!< Interrupt flag register #define BSP_KEY_MODE_POLL 0 #define BSP_KEY_MODE_ISR 1 #define BSP_KEY_DEBOUNCE(expr) { uint16_t i; for (i=0; i<500; i++) { \ if (!(expr)) i = 0; } } /****************************************************************************** * TYPEDEFS */ typedef struct { uint16 addr; uint8 data; }registerSetting_t; typedef uint8 rfStatus_t; /**************************************************************************/ /****************************************************************************** * MACROS */ /* Macros for Tranceivers(TRX) */ #define TRXEM_SPI_BEGIN() st( TRXEM_PORT_OUT &= ~TRXEM_SPI_SC_N_PIN; /*NOP();*/ ) #define TRXEM_SPI_TX(x) st( UCB0IFG &= ~UCRXIFG; UCB0TXBUF= (x); ) #define TRXEM_SPI_WAIT_DONE() st( while(!(UCB0IFG & UCRXIFG)); ) #define TRXEM_SPI_RX() UCB0RXBUF #define TRXEM_SPI_WAIT_MISO_LOW(x) st( uint8 count = 200; \ while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN) \ { \ __delay_cycles(5000); \ count--; \ if (count == 0) break; \ } \ if(count>0) (x) = 1; \ else (x) = 0; ) #define TRXEM_SPI_END() st( /*NOP();*/ TRXEM_PORT_OUT |= TRXEM_SPI_SC_N_PIN; ) /**************************************************************************************/ /****************************************************************************** * VARIABLES */ // Carrier frequency = 169.000000 // Symbol rate = 1.2 // Bit rate = 1.2 // Deviation = 3.997803 // Manchester enable = false // Bit rate = 1.2 // Modulation format = 2-FSK // Bit rate = 1.2 // RX filter BW = 25.000000 // TX power = -6 // PA ramping = true // Packet length mode = Variable // Whitening = false // Address config = No address check. // Packet length = 255 // Device address = 0 static const registerSetting_t preferredSettings[] = { {CC112X_IOCFG3, 0xB0},//0xB0, 0x0f to read the CCA {CC112X_IOCFG2, 0x0F},//0x06, 0x0f to use TXCCA_DONE {CC112X_IOCFG1, 0xB0}, {CC112X_IOCFG0, 0x4F},//0x40, 0x4f to use txcca_failed {CC112X_SYNC_CFG1, 0x02},//0x0B, 0x02 to use fixed threshold {CC112X_DCFILT_CFG, 0x1C}, {CC112X_IQIC, 0xC6}, {CC112X_CHAN_BW, 0x08}, {CC112X_MDMCFG0, 0x05}, {CC112X_AGC_REF, 0x20}, {CC112X_AGC_CS_THR, 0x22},//RSSI threshold {CC112X_AGC_CFG1, 0xA9}, {CC112X_AGC_CFG0, 0xCF}, {CC112X_FIFO_CFG, 0x00}, {CC112X_SETTLING_CFG, 0x03}, {CC112X_FS_CFG, 0x1A}, {CC112X_PKT_CFG2, 0x0C},//CCA mode 3: 000 011 00 {CC112X_PKT_CFG1, 0x05}, {CC112X_PKT_CFG0, 0x20}, {CC112X_PA_CFG2, 0x7F}, {CC112X_PA_CFG1, 0x56}, {CC112X_PA_CFG0, 0x7C}, {CC112X_PKT_LEN, 0xFF}, {CC112X_IF_MIX_CFG, 0x00}, {CC112X_FREQOFF_CFG, 0x22}, {CC112X_FREQ2, 0x69}, {CC112X_FREQ1, 0xA0}, {CC112X_FREQ0, 0x00}, {CC112X_RFEND_CFG0, 0x30},//will go to Rx mode after Tx {CC112X_RFEND_CFG1, 0x2F},//will go to Tx mode after Rx {CC112X_FS_DIG1, 0x00}, {CC112X_FS_DIG0, 0x5F}, {CC112X_FS_CAL0, 0x0E}, {CC112X_FS_DIVTWO, 0x03}, {CC112X_FS_DSM0, 0x33}, {CC112X_FS_DVC0, 0x17}, {CC112X_FS_PFD, 0x50}, {CC112X_FS_PRE, 0x6E}, {CC112X_FS_REG_DIV_CML, 0x14}, {CC112X_FS_SPARE, 0xAC}, {CC112X_XOSC5, 0x0E}, {CC112X_XOSC3, 0x03}, {CC112X_XOSC1, 0x03}, }; #define BSP_KEY_COUNT 5 #define RX_FIFO_ERROR 0x11 #define IO_PIN_PORT_1 1 #define IO_PIN_PORT_2 2 #define IO_PIN_FALLING_EDGE 0 #define IO_PIN_RISING_EDGE 1 #define PKT_LEN 1 #define NUM_PKTS 10 /****************************************************************************** * PROTOTYPES */ rfStatus_t cc112xSpiWriteReg(uint16 addr, uint8 *data, uint8 len); void trxRfSpiInterfaceInit(uint8 clockDivider); rfStatus_t trx8BitRegAccess(uint8 accessType, uint8 addrByte, uint8 *pData, uint16 len); rfStatus_t trxSpiCmdStrobe(uint8 cmd); /* CC112X specific prototype function */ rfStatus_t trx16BitRegAccess(uint8 accessType, uint8 extAddr, uint8 regAddr, uint8 *pData, uint8 len); static void trxReadWriteBurstSingle(uint8 addr,uint8 *pData,uint16 len); void bspInit(uint32 ui32SysClockSpeed); uint32_t bspIoSpiInit(uint8_t ui8Spi, uint32 ui32ClockSpeed); static void bspMcuStartXT1(void); void bspSysClockSpeedSet(uint32 ui32SystemClockSpeed); uint32_t bspSysClockSpeedGet(void); static void bspMcuSetVCore(uint8_t ui8Level); static void bspMcuGetSystemClockSettings(uint32 ui32SystemClockSpeed, uint8_t *pui8SetDcoRange, uint8_t *pui8SetVCore, uint32_t *pui32SetMultiplier); static void bspMcuSetVCoreDown(uint8_t ui8Level); void lcdInit(void); //void ioPinIntRegister(uint32_t ui32Base, uint8_t ui8Pins,void (*pfnIntHandler)(void)); static void txintISR(void); static void txintISR1(void); void bspAssert(void); static void manualCalibration(void); rfStatus_t cc112xSpiReadReg(uint16 addr, uint8 *pData, uint8 len); rfStatus_t cc112xSpiWriteTxFifo(uint8 *pData, uint8 len); rfStatus_t cc112xSpiReadRxFifo(uint8 * pData, uint8 len); uint8_t bspKeyPushed(uint8_t ui8ReadMask); void bspLedInit(void); void bspKeyInit(uint8_t ui8Mode); void ioPinIntRegister(uint32_t ui32Base, uint8_t ui8Pins, void (*pfnIntHandler)(void)); void ioPinIntTypeSet(uint32_t ui32Base, uint8_t ui8Pins, uint8_t ui8IntType); static void bspKeyPushedISR(void); void ioPinIntDisable(uint32_t ui32Base, uint8_t ui8Pins); int Read8BitRssi(void); volatile static uint8 sent; static uint32_t ui32BspMclkSpeed; static uint8_t ui8BspKeyMode; static volatile uint8_t bspKeysPressed; volatile static uint8 send=0; volatile static uint8 received; volatile static uint8 timeout; volatile static uint8 out; volatile static uint8 counter=0; //static uint32_t ui32IoSpiClkSpeed[2]; uint8 buffer[PKT_LEN+1] = {0}; /****************************************************************/ static volatile uint8_t bspKeyIntDisabledMask; static uint_fast8_t ioPort1PinHasIsr; static uint_fast8_t ioPort2PinHasIsr; static uint32 packetCounter = 0; static uint32 packetCounter1 = 0; static uint32 nottimeout=0; uint8 rc,busy; uint8 rsiConverted,rssiValid,txonccafailed; // Function pointer arrays static void (*ioPort1IsrTable[8])(void); static void (*ioPort2IsrTable[8])(void); static void (*bspKeysIsrTable[BSP_KEY_COUNT])(void); // Function prototypes __interrupt void ioPort1Isr(void); /* * main.c */ /****************************************************************/ /* * creates the packet: * PKT_LEN||numtx||2||3||...||PKT_LEN * ****************************************************************/ static void createPacket(uint8 txBuffer[],uint8 numtx) { uint8 i; txBuffer[0] = PKT_LEN; // Length byte txBuffer[1] = (uint8) (numtx); // number of transaction //txBuffer[2] = (uint8) packetCounter; // LSB of packetCounter // Fill rest of buffer with random bytes for(i = 2; i < (PKT_LEN + 1); i++) { txBuffer[i] = (uint8)i; } } int main(void) { uint8 writeByte,i,j; uint8 marcState; uint8 rxBuffer[128] = {0}; uint8 rxBytes; // WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer /************************************INIT LCD*************************************************************/ //bspinit() for SPI clock basically bspInit(BSP_SYS_CLK_8MHZ); bspLedInit(); bspKeyInit(BSP_KEY_MODE_POLL); // Initialize SPI interface to LCD (shared with SPI flash) //bspIoSpiInit(BSP_FLASH_LCD_SPI, BSP_FLASH_LCD_SPI_SPD); // Instantiate transceiver RF SPI interface to SCLK ~ 4 MHz // Input parameter is clockDivider // SCLK frequency = SMCLK/clockDivider trxRfSpiInterfaceInit(2); /**********************timerB0 configuration***********************************************************/ TBCCR0 = 16384-1; //1s TBCTL = TBSSEL_1 + MC_1 + TBCLR; // ACLK, upmode, clear TBR /*****************************************************************************************************************/ _BIS_SR(GIE); //ConfigureSettings // Reset radio trxSpiCmdStrobe(CC112X_SRES); // Write registers to radio for(i = 0; i < (sizeof(preferredSettings)/sizeof(registerSetting_t)); i++) { writeByte = preferredSettings[i].data; cc112xSpiWriteReg(preferredSettings[i].addr, &writeByte, 1); } /**********Configuration of the Tx Interrupt*****************************/ ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &txintISR); //ioPinIntRegister(IO_PIN_PORT_1, 0x02, &txintISR1); // Interrupt on falling edge P1IES|=GPIO2; // P1IES|=0x02; // Clear ISR flag P1IFG &= ~GPIO2; // P1IFG &= ~0x02; // Enable interrupt P1IE |= GPIO2; // P1IE |= 0x02; /***********************************************************************///end of Configuration of the Tx Interrupt manualCalibration(); /****************send packet*******************************************/ while(1){//after finish come back and wait for the next button pushed. while(!(bspKeyPushed(BSP_KEY_ALL)));// wait for the button for (j=0;j140)P4OUT^=3; }while(rsiConverted>140); //trxSpiCmdStrobe(CC112X_SRES); trxSpiCmdStrobe(CC112X_SRX); rc=cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1); //wait 5 ms // __delay_cycles(5000); do{ cc112xSpiReadReg(CC112X_RSSI0, &rssiValid, 1);//rssi value valid? }while((rssiValid & 0x01)==0); //if(rssiValid&0x01){ do{ cc112xSpiReadReg(CC112X_MARC_STATUS0, &txonccafailed, 1);//channel busy? busy=txonccafailed&0x02; }while(busy==1);//wait until channel free*/ //} send=1; rc=cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1); // Strobe TX to send packet trxSpiCmdStrobe(CC112X_STX); rc=cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1); /***************************************************///end of send packet while(sent != 1);//waiting for confirmation of Transmission sent=0;//reset flag /********CHECK LED********/ P4DIR^=BIT2; // LED to check if it is there /**************************///end of check led rc=cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1); __delay_cycles(1); /*****************************Wait for the ACK from the receiver(if not timeout and send it again)****************************************************************/ //trxSpiCmdStrobe(CC112X_SRES); //send=0; // Set radio in RX trxSpiCmdStrobe(CC112X_SRX); rc=cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1); //while(timeout!=1); //while(!((received)|(timeout)));//wait for the ACKNOWLEDGE/timeout while(!((received)|(timeout))); //while((received!=1)); if((timeout==1)&&(received==0)){ if(j>0)j--;//for sending the same packet and not the next one TBCCTL0 &= ~CCIE; timeout=0; counter++; nottimeout++; if(counter>9){counter=0;break;}//sends 10 times the same packet before finish } if(received==1){ counter=0; TBCCTL0 &= ~CCIE; timeout=0; // Read number of bytes in RX FIFO cc112xSpiReadReg(CC112X_NUM_RXBYTES, &rxBytes, 1); rc=cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1); // Check that we have bytes in FIFO if(rxBytes != 0) { // Read MARCSTATE to check for RX FIFO error cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1); // Mask out MARCSTATE bits and check if we have a RX FIFO error if((marcState & 0x1F) == RX_FIFO_ERROR) { //trxSpiCmdStrobe(CC112X_SFTX);//Flush TX FIFO trxSpiCmdStrobe(CC112X_SFRX);//Flush RX FIFO } else { // Read n bytes from RX FIFO cc112xSpiReadRxFifo(rxBuffer, rxBytes); // Check CRC ok (CRC_OK: bit7 in second status byte) // This assumes status bytes are appended in RX_FIFO // (PKT_CFG1.APPEND_STATUS = 1) // If CRC is disabled the CRC_OK field will read 1 if(rxBuffer[rxBytes - 1] & 0x80) { // Update packet counter packetCounter++; } } } } received = 0; // Reset packet semaphore //trxSpiCmdStrobe(CC112X_SRX); P4DIR^=BIT3; // LED to check if it is in the interrupt //trxSpiCmdStrobe(CC112X_SRES); //sleep(500); //trxSpiCmdStrobe(CC112X_STX); rc=cc112xSpiReadReg(CC112X_MARCSTATE, &marcState, 1); /*****************************************************************************************************************************************************************/ } } } /*************************************************************************************************************************/ // Timer B0 interrupt service routine #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__) #pragma vector=TIMERB0_VECTOR __interrupt void TIMERB1_ISR(void) #elif defined(__GNUC__) void __attribute__ ((interrupt(TIMERB0_VECTOR))) TIMERB1_ISR (void) #else #error Compiler not supported! #endif { timeout= 1; } /**************************************************************************************/ /*************************************************************************************/ int Read8BitRssi(void){ uint8 rssi2compl,rssiValid; uint8 rssiOffset = 102; int8 rssiConverted; // Read RSSI_VALID from RSSI0 cc112xSpiReadReg(CC112X_RSSI0, &rssiValid, 1); // Check if the RSSI_VALID flag is set if(rssiValid & 0x01){ // Read RSSI from MSB register cc112xSpiReadReg(CC112X_RSSI1, &rssi2compl, 1); rssiConverted = (int8)rssi2compl - rssiOffset; return rssiConverted; } // return 0 since new value is not valid return 0; } /*****************************************************************************/ /**************************************************************************//** * @brief Function returns the system clock speed (in MHz) set by bspInit(). * * @return Returns the system clock speed (in MHz) set by bspInit(). ******************************************************************************/ uint32_t bspSysClockSpeedGet(void) { return (ui32BspMclkSpeed); } /**************************************************************/ /**************************************************************/ static void txintISR(void) { // Set packet semaphore if(send==1){ // Set packet semaphore sent = 1;//packet sent P4OUT^=1; // Clear ISR flag P1IFG &= ~(GPIO2); send=0; //start timeout TBCCTL0 = CCIE; // TRCCR0 interrupt enabled } else{ received = 1;//ACK received P4OUT^=1; // Clear ISR flag P1IFG &= ~(GPIO2); } } /***********************************************************/ /******************************************************************************* cc112xSpiReadRxFifo */ rfStatus_t cc112xSpiReadRxFifo(uint8 * pData, uint8 len) { uint8 rc; rc = trx8BitRegAccess(0x00,CC112X_BURST_RXFIFO, pData, len); return (rc); } /************************************************************************/ /******************************************************************************/ void bspKeyInit(uint8_t ui8Mode) { // // Store mode // #ifndef BSP_KEY_NO_ISR ui8BspKeyMode = ui8Mode; #else ui8BspKeyMode = BSP_KEY_MODE_POLL; #endif // // Initialize keys as GPIO input pullup: // BSP_KEY_SEL &= ~(BSP_KEY_ALL); BSP_KEY_DIR &= ~(BSP_KEY_ALL); BSP_KEY_OUT |= BSP_KEY_ALL; BSP_KEY_REN |= BSP_KEY_ALL; #ifndef BSP_KEY_NO_ISR if(ui8BspKeyMode == BSP_KEY_MODE_ISR) { // // Disable interrupts on key pins and clear interrupt flags // BSP_KEY_IE &= ~(BSP_KEY_ALL); BSP_KEY_IFG &= ~(BSP_KEY_ALL); // // Connect bspKeyPushedISR() to key pins // ioPinIntRegister(IO_PIN_PORT_2, BSP_KEY_ALL, &bspKeyPushedISR); // // Set trigger type // ioPinIntTypeSet(IO_PIN_PORT_2, BSP_KEY_ALL, IO_PIN_RISING_EDGE); } #endif // BSP_KEY_NO_ISR } /******************************************************************************/ #ifndef BSP_KEY_NO_ISR static void bspKeyPushedISR(void) { uint8_t ui8IrqBm; uint16_t ui16IntState; // // Disable WDT interrupt and stop WDT SFRIE1 &= ~WDTIE; WDTCTL = WDTPW + WDTHOLD; // // Critical section // ui16IntState = __get_interrupt_state(); __disable_interrupt(); // // Get interrupt flags for keys with interrupt enabled, and store info // ui8IrqBm = (BSP_KEY_IFG & BSP_KEY_ALL); ui8IrqBm &= BSP_KEY_IE; bspKeysPressed |= ui8IrqBm; bspKeyIntDisabledMask |= ui8IrqBm; // // End critical section, set interrupt state back to previous // __set_interrupt_state(ui16IntState); // // Disable interrupts on keys where interrupt flag was set // ioPinIntDisable(IO_PIN_PORT_2, bspKeyIntDisabledMask); // // Run custom ISR if any (unrolled for speed) // if((ui8IrqBm & BSP_KEY_SELECT) && (bspKeysIsrTable[0] != 0)) { (*bspKeysIsrTable[0])(); } if((ui8IrqBm & BSP_KEY_LEFT) && (bspKeysIsrTable[1] != 0)) { (*bspKeysIsrTable[1])(); } if((ui8IrqBm & BSP_KEY_RIGHT) && (bspKeysIsrTable[2] != 0)) { (*bspKeysIsrTable[2])(); } if((ui8IrqBm & BSP_KEY_UP) && (bspKeysIsrTable[3] != 0)) { (*bspKeysIsrTable[3])(); } if((ui8IrqBm & BSP_KEY_DOWN) && (bspKeysIsrTable[4] != 0)) { (*bspKeysIsrTable[4])(); } // // Clear pending WDT interrupt flag, start WDT in timer mode (250 ms // interval counter when ACLK is 32768 Hz), and enable WDT interrupts. // SFRIFG1 &= ~WDTIFG; WDTCTL = WDTPW + WDTSSEL_1 + WDTTMSEL + WDTCNTCL + WDTIS_5; SFRIE1 |= WDTIE; } #endif /*****************************************************************************/ /******************************************************************************/ void ioPinIntTypeSet(uint32_t ui32Base, uint8_t ui8Pins, uint8_t ui8IntType) { switch(ui8IntType) { case IO_PIN_FALLING_EDGE: switch(ui32Base) { case IO_PIN_PORT_1: P1IES |= ui8Pins; return; case IO_PIN_PORT_2: P2IES |= ui8Pins; return; default: return; } case IO_PIN_RISING_EDGE: switch(ui32Base) { case IO_PIN_PORT_1: P1IES &= ~ui8Pins; return; case IO_PIN_PORT_2: P2IES &= ~ui8Pins; return; default: return; } default: return; } } /********************************************************************************/ /******************************************************************************/ void ioPinIntDisable(uint32_t ui32Base, uint8_t ui8Pins) { switch(ui32Base) { case IO_PIN_PORT_1: P1IE &= (~ui8Pins); return; case IO_PIN_PORT_2: P2IE &= (~ui8Pins); return; default: return; } } /******************************************************************************/ void ioPinIntRegister(uint32_t ui32Base, uint8_t ui8Pins, void (*pfnIntHandler)(void)) { uint_fast8_t ui8Cnt; uint16_t ui16IntState; // // Critical section // ui16IntState = __get_interrupt_state(); __disable_interrupt(); if(pfnIntHandler) { // // Update HasIsr variables and clear interrupt flags // switch(ui32Base) { case IO_PIN_PORT_1: ioPort1PinHasIsr |= ui8Pins; P1IFG &= (~ui8Pins); break; case IO_PIN_PORT_2: ioPort2PinHasIsr |= ui8Pins; P2IFG &= (~ui8Pins); break; } } // // Go through pins // for(ui8Cnt = 0; ui8Cnt < 8; ui8Cnt++) { if(ui8Pins & (1 << ui8Cnt)) { // // Place function to offset in the correct lookup table // switch(ui32Base) { case IO_PIN_PORT_1: ioPort1IsrTable[ui8Cnt] = pfnIntHandler; break; case IO_PIN_PORT_2: ioPort2IsrTable[ui8Cnt] = pfnIntHandler; break; default: break; } } } // // End critical section // __set_interrupt_state(ui16IntState); } /**************************************************************************/ /**************************************************************************/ void bspLedInit(void) { // // Set as GPIO output high // P4OUT |= 0x0F; P4SEL &= ~0x0F; P4DIR |= 0x0F; } /******************************************************************************* * @fn manualCalibration * * @brief Calibrates radio according to CC112x errata * * @param none * * @return none */ #define VCDAC_START_OFFSET 2 #define FS_VCO2_INDEX 0 #define FS_VCO4_INDEX 1 #define FS_CHP_INDEX 2 static void manualCalibration(void) { uint8 original_fs_cal2; uint8 calResults_for_vcdac_start_high[3]; uint8 calResults_for_vcdac_start_mid[3]; uint8 marcstate; uint8 writeByte; // 1) Set VCO cap-array to 0 (FS_VCO2 = 0x00) writeByte = 0x00; cc112xSpiWriteReg(CC112X_FS_VCO2, &writeByte, 1); // 2) Start with high VCDAC (original VCDAC_START + 2): cc112xSpiReadReg(CC112X_FS_CAL2, &original_fs_cal2, 1); writeByte = original_fs_cal2 + VCDAC_START_OFFSET; cc112xSpiWriteReg(CC112X_FS_CAL2, &writeByte, 1); // 3) Calibrate and wait for calibration to be done // (radio back in IDLE state) trxSpiCmdStrobe(CC112X_SCAL); do { cc112xSpiReadReg(CC112X_MARCSTATE, &marcstate, 1); } while (marcstate != 0x41); // 4) Read FS_VCO2, FS_VCO4 and FS_CHP register obtained with // high VCDAC_START value cc112xSpiReadReg(CC112X_FS_VCO2, &calResults_for_vcdac_start_high[FS_VCO2_INDEX], 1); cc112xSpiReadReg(CC112X_FS_VCO4, &calResults_for_vcdac_start_high[FS_VCO4_INDEX], 1); cc112xSpiReadReg(CC112X_FS_CHP, &calResults_for_vcdac_start_high[FS_CHP_INDEX], 1); // 5) Set VCO cap-array to 0 (FS_VCO2 = 0x00) writeByte = 0x00; cc112xSpiWriteReg(CC112X_FS_VCO2, &writeByte, 1); // 6) Continue with mid VCDAC (original VCDAC_START): writeByte = original_fs_cal2; cc112xSpiWriteReg(CC112X_FS_CAL2, &writeByte, 1); // 7) Calibrate and wait for calibration to be done // (radio back in IDLE state) trxSpiCmdStrobe(CC112X_SCAL); do { cc112xSpiReadReg(CC112X_MARCSTATE, &marcstate, 1); } while (marcstate != 0x41); // 8) Read FS_VCO2, FS_VCO4 and FS_CHP register obtained // with mid VCDAC_START value cc112xSpiReadReg(CC112X_FS_VCO2, &calResults_for_vcdac_start_mid[FS_VCO2_INDEX], 1); cc112xSpiReadReg(CC112X_FS_VCO4, &calResults_for_vcdac_start_mid[FS_VCO4_INDEX], 1); cc112xSpiReadReg(CC112X_FS_CHP, &calResults_for_vcdac_start_mid[FS_CHP_INDEX], 1); // 9) Write back highest FS_VCO2 and corresponding FS_VCO // and FS_CHP result if (calResults_for_vcdac_start_high[FS_VCO2_INDEX] > calResults_for_vcdac_start_mid[FS_VCO2_INDEX]) { writeByte = calResults_for_vcdac_start_high[FS_VCO2_INDEX]; cc112xSpiWriteReg(CC112X_FS_VCO2, &writeByte, 1); writeByte = calResults_for_vcdac_start_high[FS_VCO4_INDEX]; cc112xSpiWriteReg(CC112X_FS_VCO4, &writeByte, 1); writeByte = calResults_for_vcdac_start_high[FS_CHP_INDEX]; cc112xSpiWriteReg(CC112X_FS_CHP, &writeByte, 1); } else { writeByte = calResults_for_vcdac_start_mid[FS_VCO2_INDEX]; cc112xSpiWriteReg(CC112X_FS_VCO2, &writeByte, 1); writeByte = calResults_for_vcdac_start_mid[FS_VCO4_INDEX]; cc112xSpiWriteReg(CC112X_FS_VCO4, &writeByte, 1); writeByte = calResults_for_vcdac_start_mid[FS_CHP_INDEX]; cc112xSpiWriteReg(CC112X_FS_CHP, &writeByte, 1); } } /************************************************************************/ uint8_t bspKeyPushed(uint8_t ui8ReadMask) { if(ui8BspKeyMode == BSP_KEY_MODE_POLL) { // // Polling mode. // // // Get key state bitmask // uint_fast8_t ui8Pins = ((~BSP_KEY_IN) & BSP_KEY_ALL); // // Return the first key pressed // if(ui8Pins & BSP_KEY_LEFT) { BSP_KEY_DEBOUNCE(BSP_KEY_IN & BSP_KEY_LEFT); return (BSP_KEY_LEFT); } else if(ui8Pins & BSP_KEY_RIGHT) { BSP_KEY_DEBOUNCE(BSP_KEY_IN & BSP_KEY_RIGHT); return (BSP_KEY_RIGHT); } else if(ui8Pins & BSP_KEY_UP) { BSP_KEY_DEBOUNCE(BSP_KEY_IN & BSP_KEY_UP); return (BSP_KEY_UP); } else if(ui8Pins & BSP_KEY_DOWN) { BSP_KEY_DEBOUNCE(BSP_KEY_IN & BSP_KEY_DOWN); return (BSP_KEY_DOWN); } else if(ui8Pins & BSP_KEY_SELECT) { BSP_KEY_DEBOUNCE(BSP_KEY_IN & BSP_KEY_SELECT); return (BSP_KEY_SELECT); } // // No keys pressed // return (0); } #ifndef BSP_KEY_NO_ISR else { uint_fast8_t ui8Bm = 0; // // Disable global interrupts // uint16_t ui16IntState = __get_interrupt_state(); __disable_interrupt(); // // Critical section // ui8Bm = bspKeysPressed; bspKeysPressed &= ~ui8ReadMask; // // Re-enable interrupt if initially enabled, and return key bitmask // __set_interrupt_state(ui16IntState); return (ui8Bm); } #else else { // // If we get here, something is configured wrong (ISR mode chosen _and_ // BSP_KEY_NO_ISR defined) // return (0); } #endif // BSP_KEY_NO_ISR } /**********************************************************/ //interrupt Tx #pragma vector=PORT1_VECTOR __interrupt void ioPort1Isr(void) { register uint_fast8_t ui8IntBm, ui8IsrBm; // // Get bitmask of pins with interrupt triggered (and interrupt enabled) // ui8IntBm = P1IFG; ui8IntBm &= P1IE; // // Create bitmask of pins with interrupt _and_ custom isr // ui8IsrBm = (ui8IntBm & ioPort1PinHasIsr); if((ui8IsrBm & BIT0)) { (*ioPort1IsrTable[0])(); } if((ui8IsrBm & BIT1)) { (*ioPort1IsrTable[1])(); } if((ui8IsrBm & BIT2)) { (*ioPort1IsrTable[2])(); } if((ui8IsrBm & BIT3)) { (*ioPort1IsrTable[3])(); } if((ui8IsrBm & BIT4)) { (*ioPort1IsrTable[4])(); } if((ui8IsrBm & BIT5)) { (*ioPort1IsrTable[5])(); } if((ui8IsrBm & BIT6)) { (*ioPort1IsrTable[6])(); } if((ui8IsrBm & BIT7)) { (*ioPort1IsrTable[7])(); } // // Clear pin interrupt flags (custom isr or not) // P1IFG &= (~ui8IntBm); #ifndef IO_PIN_KEEP_POWER_MODE_ON_EXIT // // Turn off low power mode // __low_power_mode_off_on_exit(); #endif } /*********************************************************/ /**************************************************************************//** *bpsInit ******************************************************************************/ void bspInit(uint32 ui32SysClockSpeed) { uint16_t ui16IntState; // // Stop watchdog timer (prevent timeout reset) // WDTCTL = WDTPW + WDTHOLD; // // Disable global interrupts // ui16IntState = __get_interrupt_state(); __disable_interrupt(); // // Set capacitor values for XT1, 32768 Hz */ // bspMcuStartXT1(); bspSysClockSpeedSet(ui32SysClockSpeed); // // Initialize LEDs as off (pins as GPIO output high) // P4SEL &= ~BSP_LED_ALL; P4OUT |= BSP_LED_ALL; P4DIR |= BSP_LED_ALL; // // LCD CS as GPIO output high // P9SEL &= ~BIT6; P9OUT |= BIT6; P9DIR |= BIT6; // // Accelerometer + SPI flash CS as GPIO output high // P8SEL &= ~(BSP_FLASH_CS_N | BIT7); P8OUT |= (BSP_FLASH_CS_N | BIT7); P8DIR |= (BSP_FLASH_CS_N | BIT7); // // RF SPI0 CS as GPIO output high // P3SEL &= ~BIT0; P3OUT |= BIT0; P3DIR |= BIT0; // // RF SPI1 CS as GPIO output high // P4SEL &= ~BIT1; P4OUT |= BIT1; P4DIR |= BIT1; // // Hold SPI flash powered up, but in reset (GPIO output high, full drive // strength). // P7SEL &= ~(BIT2 | BIT6); P7DS |= BIT6; P7OUT |= BIT6; P7OUT &= ~BIT2; P7DIR |= (BIT2 | BIT6); // // Accelerometer + Light sensor PWR as GPIO input pulldown // P6SEL &= ~(BIT0 | BSP_ALS_PWR); P6OUT &= ~(BIT0 | BSP_ALS_PWR); P6REN |= (BIT0 | BSP_ALS_PWR); P6DIR &= ~(BIT0 | BSP_ALS_PWR); // // USB UART as GPIO input pullup // P5SEL &= ~(BIT6 | BIT7); P5OUT |= (BIT6 | BIT7); P5REN |= (BIT6 | BIT7); P5DIR &= ~(BIT6 | BIT7); // // Return to previous interrupt state // __set_interrupt_state(ui16IntState); } /***************************************************************************************/ /******************************************************************************* trxReadWriteBurstSingle */ static void trxReadWriteBurstSingle(uint8 addr,uint8 *pData,uint16 len) { uint16 i; /* Communicate len number of bytes: if RX - the procedure sends 0x00 to push bytes from slave*/ if(addr&RADIO_READ_ACCESS) { if(addr&RADIO_BURST_ACCESS) { for (i = 0; i < len; i++) { TRXEM_SPI_TX(0); /* Possible to combining read and write as one access type */ TRXEM_SPI_WAIT_DONE(); *pData = TRXEM_SPI_RX(); /* Store pData from last pData RX */ pData++; } } else { TRXEM_SPI_TX(0); TRXEM_SPI_WAIT_DONE(); *pData = TRXEM_SPI_RX(); } } else { if(addr&RADIO_BURST_ACCESS) { /* Communicate len number of bytes: if TX - the procedure doesn't overwrite pData */ for (i = 0; i < len; i++) { TRXEM_SPI_TX(*pData); TRXEM_SPI_WAIT_DONE(); pData++; } } else { TRXEM_SPI_TX(*pData); TRXEM_SPI_WAIT_DONE(); } } return; } /********************************************************************************/ /****************************************************************************** cc112xSpiWriteReg */ rfStatus_t cc112xSpiWriteReg(uint16 addr, uint8 *pData, uint8 len) { uint8 tempExt = (uint8)(addr>>8); uint8 tempAddr = (uint8)(addr & 0x00FF); uint8 rc; /* Checking if this is a FIFO access - returns chip not ready */ if((CC112X_SINGLE_TXFIFO<=tempAddr)&&(tempExt==0)) return STATUS_CHIP_RDYn_BM; /* Decide what register space is accessed */ if(!tempExt) { rc = trx8BitRegAccess((RADIO_BURST_ACCESS|RADIO_WRITE_ACCESS),tempAddr,pData,len); } else if (tempExt == 0x2F) { rc = trx16BitRegAccess((RADIO_BURST_ACCESS|RADIO_WRITE_ACCESS),tempExt,tempAddr,pData,len); } return (rc); } /********************************************************************************/ /****************************************************************************** trxRfSpiInterfaceInit */ void trxRfSpiInterfaceInit(uint8 prescalerValue) { /* Keep peripheral in reset state*/ UCB0CTL1 |= UCSWRST; /* Configuration * - 8-bit * - Master Mode * - 3-pin * - synchronous mode * - MSB first * - Clock phase select = captured on first edge * - Inactive state is low * - SMCLK as clock source * - Spi clk is adjusted corresponding to systemClock as the highest rate * supported by the supported radios: this could be optimized and done * after chip detect. */ UCB0CTL0 = 0x00+UCMST + UCSYNC + UCMODE_0 + UCMSB + UCCKPH; UCB0CTL1 |= UCSSEL_2; UCB0BR1 = 0x00; UCB0BR0 = prescalerValue; //UCRXIE=1; /* Configure port and pins * - MISO/MOSI/SCLK GPIO controlled by peripheral * - CS_n GPIO controlled manually, set to 1 */ TRXEM_PORT_SEL |= TRXEM_SPI_MOSI_PIN + TRXEM_SPI_MISO_PIN + TRXEM_SPI_SCLK_PIN; TRXEM_PORT_SEL &= ~TRXEM_SPI_SC_N_PIN; TRXEM_PORT_OUT |= TRXEM_SPI_SC_N_PIN + TRXEM_SPI_MISO_PIN;/* Pullup on MISO */ TRXEM_PORT_DIR |= TRXEM_SPI_SC_N_PIN; /* In case not automatically set */ TRXEM_PORT_DIR |= TRXEM_SPI_MOSI_PIN + TRXEM_SPI_SCLK_PIN; TRXEM_PORT_DIR &= ~TRXEM_SPI_MISO_PIN; /* Release for operation */ UCB0CTL1 &= ~UCSWRST; return; } /********************************************************************************/ /******************************************************************************* trx8BitRegAccess */ rfStatus_t trx8BitRegAccess(uint8 accessType, uint8 addrByte, uint8 *pData, uint16 len) { uint8 readValue; /* Pull CS_N low and wait for SO to go low before communication starts */ TRXEM_SPI_BEGIN(); while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN); /* send register address byte */ TRXEM_SPI_TX(accessType|addrByte); TRXEM_SPI_WAIT_DONE(); /* Storing chip status */ readValue = TRXEM_SPI_RX(); trxReadWriteBurstSingle(accessType|addrByte,pData,len); TRXEM_SPI_END(); /* return the status byte value */ return(readValue); } /********************************************************************************/ /******************************************************************************* trxSpiCmdStrobe */ rfStatus_t trxSpiCmdStrobe(uint8 cmd) { uint8 rc; TRXEM_SPI_BEGIN(); while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN); TRXEM_SPI_TX(cmd); TRXEM_SPI_WAIT_DONE(); rc = TRXEM_SPI_RX(); TRXEM_SPI_END(); return(rc); } /********************************************************************************/ /****************************************************************************** trx16BitRegAccess */ rfStatus_t trx16BitRegAccess(uint8 accessType, uint8 extAddr, uint8 regAddr, uint8 *pData, uint8 len) { uint8 readValue; TRXEM_SPI_BEGIN(); while(TRXEM_PORT_IN & TRXEM_SPI_MISO_PIN); /* send extended address byte with access type bits set */ TRXEM_SPI_TX(accessType|extAddr); TRXEM_SPI_WAIT_DONE(); /* Storing chip status */ readValue = TRXEM_SPI_RX(); TRXEM_SPI_TX(regAddr); TRXEM_SPI_WAIT_DONE(); /* Communicate len number of bytes */ trxReadWriteBurstSingle(accessType|extAddr,pData,len); TRXEM_SPI_END(); /* return the status byte value */ return(readValue); } /********************************************************************************/ /**************************************************************************//** bspIoSpiInit ******************************************************************************/ uint32_t bspIoSpiInit(uint8_t ui8Spi, uint32 ui32ClockSpeed) { uint16_t ui16Div; uint32_t ui32SysClk = bspSysClockSpeedGet(); //uint32_t ui32BspMclkSpeed; int ui32IoSpiClkSpeed[2]; // // Check arguments // if(ui32ClockSpeed > ui32SysClk) { ui32ClockSpeed = ui32SysClk; } if((ui8Spi == BSP_IO_SPI0) && (ui32ClockSpeed > 20000000)) { // // Clock speed too high. Max 20 MHz for signal integrity. // ui32ClockSpeed = 20000000; } else if((ui8Spi == BSP_IO_SPI1) && (ui32ClockSpeed > 400000)) { // // Clock speed too high. Accelerometer supports max 400 kHz. // ui32ClockSpeed = 400000; } else if((ui8Spi != BSP_IO_SPI0) && (ui8Spi != BSP_IO_SPI1)) { // // Invalid input argument. No clock set. // return (0); } // // Calculate divider and store actual clock speed // ui16Div = ui32SysClk / ui32ClockSpeed; if(ui32SysClk % ui32ClockSpeed) { // // Choose the closest, low-side rate // ui16Div++; } ui32IoSpiClkSpeed[(ui8Spi >> 1)] = ui32SysClk / (uint16_t)ui16Div; if(ui8Spi == BSP_IO_SPI0) { // // Configure USCI B2 for SPI master. Disabling SPI module. // Configuration: Synchronous mode, 3-pin PSI, master, 8-bit, MSB // first, clock pol=1 (inactive high), clock pha=0 (sampling on second // edge), clock source = SMCLK. // UCB2CTL1 |= UCSWRST; UCB2CTL0 = UCSYNC | UCMST | UCCKPL | UCMSB; UCB2CTL1 |= UCSSEL1 | UCSSEL0; // // Apply divider (low nibble, high nibble) // UCB2BR0 = (ui16Div & 0xFF); UCB2BR1 = ((ui16Div >> 8) & 0xFF); // // Configure ports and pins // P9SEL |= (BSP_IO_SPI0_MOSI | BSP_IO_SPI0_MISO | BSP_IO_SPI0_SCLK); // // Enable SPI interface // UCB2CTL1 &= ~UCSWRST; } if(ui8Spi == BSP_IO_SPI1) { // // Configure USCI A2 for SPI master. Disabling SPI module. // Configuration: Synchronous mode, 3-pin PSI, master, 8-bit, MSB // first, clock pol=1 (inactive high), clock pha=0 (sampling on second // edge), clock source = SMCLK. // UCA2CTL1 |= UCSWRST; UCA2CTL0 = UCSYNC | UCMST | UCCKPL | UCMSB; UCA2CTL1 |= UCSSEL1 | UCSSEL0; // // Apply divider (low nibble, high nibble) // UCA2BR0 = (ui16Div & 0xFF); UCA2BR1 = (ui16Div >> 8) & 0xFF; // // Configure ports and pins // P9SEL |= (BSP_IO_SPI1_MOSI | BSP_IO_SPI1_MISO | BSP_IO_SPI1_SCLK); // // Enable SPI interface // UCA2CTL1 &= ~UCSWRST; } // // Return actual SPI clock speed // return (ui32IoSpiClkSpeed[(ui8Spi >> 1)]); } /********************************************************************************************/ /** bspSysClockSpeedSet ******************************************************************************/ void bspSysClockSpeedSet(uint32 ui32SystemClockSpeed) { uint8_t ui8SetDcoRange, ui8SetVCore; uint32_t ui32SetMultiplier; //uint32_t ui32BspMclkSpeed; // // Set clocks (doing sanity check) // MCLK = ui32SysClockSpeed; // SMCLK = ui32SysClockSpeed; // ACLK = 32 768 Hz // if((ui32SystemClockSpeed > 25000000UL) || (ui32SystemClockSpeed < 1000000UL)) { bspAssert(); } ui32BspMclkSpeed = ui32SystemClockSpeed; // // Get DCO, VCore and multiplier settings for the given clock speed // bspMcuGetSystemClockSettings(ui32SystemClockSpeed, &ui8SetDcoRange, &ui8SetVCore, &ui32SetMultiplier); // // Set VCore setting // bspMcuSetVCore(ui8SetVCore); // // Disable FLL control loop, set lowest possible DCOx, MODx and select // a suitable range // __bis_SR_register(SCG0); UCSCTL0 = 0x00; UCSCTL1 = ui8SetDcoRange; // // Set DCO multiplier and reenable the FLL control loop // UCSCTL2 = ui32SetMultiplier + FLLD_1; UCSCTL4 = SELA__XT1CLK | SELS__DCOCLKDIV | SELM__DCOCLKDIV ; __bic_SR_register(SCG0); // // Loop until osciallator fault falgs (XT1, XT2 & DCO fault flags) // are cleared // do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); // // Clear XT2, XT1, DCO fault flags // SFRIFG1 &= ~OFIFG; } while(SFRIFG1 & OFIFG); // // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_FLL_reference. See UCS chapter in 5xx UG // for optimization. // 32 x 32 x / f_FLL_reference (32,768 Hz) = .03125 = t_DCO_settle // t_DCO_settle / (1 / 25 MHz) = 781250 = counts_DCO_settle // __delay_cycles(781250); } /**************************************************************************/ /************************************************/ /***************************************************************************** * @brief This function runs the initialization routine for XT1. It sets the * necessary internal capacitor values, and loops until all ocillator * fault flags remain cleared. XT1 is in Low Power Mode. * * @return none ******************************************************************************/ static void bspMcuStartXT1(void) { // // Set up XT1 Pins to analog function, and to lowest drive // P7SEL |= 0x03; // // Set internal cap values // UCSCTL6 |= XCAP_3 ; // // Check OFIFG fault flag // while(SFRIFG1 & OFIFG) { // // Check OFIFG fault flag // while(SFRIFG1 & OFIFG) { // // Clear OSC fault flags and OFIFG fault flag // UCSCTL7 &= ~(DCOFFG + XT1LFOFFG + XT1HFOFFG + XT2OFFG); SFRIFG1 &= ~OFIFG; } // // Reduce the drive strength // UCSCTL6 &= ~(XT1DRIVE1_L + XT1DRIVE0); } } /*************************************************************************/ /**************************************************************************//** * @brief This function decrements the VCore setting. * * @param ui8Level is the target VCore setting. * * @return None ******************************************************************************/ static void bspMcuSetVCoreDown(uint8_t ui8Level) { // // Open PMM module registers for write access // PMMCTL0_H = 0xA5; // // Set SVS/M low side to new level // SVSMLCTL = (SVSMLCTL & ~(SVSLRVL0 * 3 + SVSMLRRL_3)) | \ (SVSLRVL0 * ui8Level + SVMLE + SVSMLRRL0 * ui8Level); // // Wait until SVM is settled // while((PMMIFG & SVSMLDLYIFG) == 0) { } // // Set VCore to new level // PMMCTL0_L = (ui8Level * PMMCOREV0); // // Lock PMM module registers for write access // PMMCTL0_H = 0x00; } /************************************************************************/ /**************************************************************************//** * @brief Increments the VCore setting. * * @param ui8Level is the target VCore setting. * * @return None ******************************************************************************/ static void bspMcuSetVCoreUp(uint8_t ui8Level) { // // Open PMM module registers for write access // PMMCTL0_H = 0xA5; // // Set SVS/M high side to new ui8Level // SVSMHCTL = (SVSMHCTL & ~(SVSHRVL0 * 3 + SVSMHRRL0)) | (SVSHE + SVSHRVL0 * ui8Level + SVMHE + SVSMHRRL0 * ui8Level); // // Set SVM new Level // SVSMLCTL = SVSLE + SVMLE + SVSMLRRL0 * ui8Level; // // Set SVS/M low side to new level // SVSMLCTL = (SVSMLCTL & ~(SVSMLRRL_3)) | (SVMLE + SVSMLRRL0 * ui8Level); // // Wait until SVM is settled // while((PMMIFG & SVSMLDLYIFG) == 0) { } // // Set VCore to 'level' and clear flags // PMMCTL0_L = PMMCOREV0 * ui8Level; PMMIFG &= ~(SVMLVLRIFG + SVMLIFG); if((PMMIFG & SVMLIFG)) { // // Wait until level is reached // while((PMMIFG & SVMLVLRIFG) == 0); } // // Set SVS/M Low side to new level // SVSMLCTL = (SVSMLCTL & ~(SVSLRVL0 * 3 + SVSMLRRL_3)) | \ (SVSLE + SVSLRVL0 * ui8Level + SVMLE + SVSMLRRL0 * ui8Level); // // Lock PMM module registers from write access // PMMCTL0_H = 0x00; } /******************************************************************************/ /***************************************************************************** * @brief Get function for the DCORSEL, VCORE, and DCO multiplier * settings that map to a given clock speed. * * @param ui32SystemClockSpeed is the target DCO frequency; can be one of * the following values: * \li \b BSP_SYS_CLK_1MHZ * \li \b BSP_SYS_CLK_4MHZ * \li \b BSP_SYS_CLK_8MHZ * \li \b BSP_SYS_CLK_12MHZ * \li \b BSP_SYS_CLK_16MHZ * \li \b BSP_SYS_CLK_20MHZ * \li \b BSP_SYS_CLK_25MHZ * @param pui8SetDcoRange is a pointer to the DCO range select bits. * @param pui8SetVCore is a pointer to the VCore level bits. * @param pui32SetMultiplier is a pointer to the DCO multiplier bits. * * @return None ******************************************************************************/ static void bspMcuGetSystemClockSettings(uint32 ui32SystemClockSpeed, uint8_t *pui8SetDcoRange, uint8_t *pui8SetVCore, uint32_t *pui32SetMultiplier) { switch(ui32SystemClockSpeed) { case BSP_SYS_CLK_1MHZ: *pui8SetDcoRange = DCORSEL_1MHZ; *pui8SetVCore = VCORE_1MHZ; *pui32SetMultiplier = DCO_MULT_1MHZ; break; case BSP_SYS_CLK_4MHZ: *pui8SetDcoRange = DCORSEL_4MHZ; *pui8SetVCore = VCORE_4MHZ; *pui32SetMultiplier = DCO_MULT_4MHZ; break; case BSP_SYS_CLK_8MHZ: *pui8SetDcoRange = DCORSEL_8MHZ; *pui8SetVCore = VCORE_8MHZ; *pui32SetMultiplier = DCO_MULT_8MHZ; break; case BSP_SYS_CLK_12MHZ: *pui8SetDcoRange = DCORSEL_12MHZ; *pui8SetVCore = VCORE_12MHZ; *pui32SetMultiplier = DCO_MULT_12MHZ; break; case BSP_SYS_CLK_16MHZ: *pui8SetDcoRange = DCORSEL_16MHZ; *pui8SetVCore = VCORE_16MHZ; *pui32SetMultiplier = DCO_MULT_16MHZ; break; case BSP_SYS_CLK_20MHZ: *pui8SetDcoRange = DCORSEL_20MHZ; *pui8SetVCore = VCORE_20MHZ; *pui32SetMultiplier = DCO_MULT_20MHZ; break; case BSP_SYS_CLK_25MHZ: *pui8SetDcoRange = DCORSEL_25MHZ; *pui8SetVCore = VCORE_25MHZ; *pui32SetMultiplier = DCO_MULT_25MHZ; break; } } /***************************************************************************** * @brief This function sets the PMM core voltage (PMMCOREV) setting. * * @param ui8Level is the target VCore setting. * * @return None ******************************************************************************/ static void bspMcuSetVCore(uint8_t ui8Level) { int ui8ActLevel; do { ui8ActLevel = PMMCTL0_L & PMMCOREV_3; if(ui8ActLevel < ui8Level) { // // Set Vcore (step by step) // bspMcuSetVCoreUp(++ui8ActLevel); } if(ui8ActLevel > ui8Level) { // // Set VCore step by step // bspMcuSetVCoreDown(--ui8ActLevel); } } while(ui8ActLevel != ui8Level); } /**************************************************************************//** Register an interrupt handler to the specified GPIO pin(s). This function will register a general ISR to the GPIO port and then assign the ISR specified by \e pfnIntHandler to the given pins. ******************************************************************************/ /****************************************************************************** cc112xSpiReadReg */ rfStatus_t cc112xSpiReadReg(uint16 addr, uint8 *pData, uint8 len) { uint8 tempExt = (uint8)(addr>>8); uint8 tempAddr = (uint8)(addr & 0x00FF); uint8 rc; /* Checking if this is a FIFO access -> returns chip not ready */ if((CC112X_SINGLE_TXFIFO<=tempAddr)&&(tempExt==0)) return STATUS_CHIP_RDYn_BM; /* Decide what register space is accessed */ if(!tempExt) { rc = trx8BitRegAccess((RADIO_BURST_ACCESS|RADIO_READ_ACCESS),tempAddr,pData,len); } else if (tempExt == 0x2F) { rc = trx16BitRegAccess((RADIO_BURST_ACCESS|RADIO_READ_ACCESS),tempExt,tempAddr,pData,len); } return (rc); } /*************************************************************************************/ /******************************************************************************/ void bspAssert(void) { // // Set all LEDs to the same state before the infinite loop // P4OUT |= BSP_LED_ALL; while(1) { // // Toggle LEDs // P4OUT ^= BSP_LED_ALL; // // Simple wait // __delay_cycles(900000); } } /*********************************************************************************************/ rfStatus_t cc112xSpiWriteTxFifo(uint8 *pData, uint8 len) { uint8 rc; rc = trx8BitRegAccess(0x00,CC112X_BURST_TXFIFO, pData, len); return (rc); } /************************************************************************************************/