/*Operation: ***********************************************************************************/ /*********************************************************************************** * INCLUDES */ #include "ioCCxx10_bitdef.h" #include #include #include #include #include "bsp.h" #include "mrfi.h" #include "nwk_types.h" #include "nwk_api.h" #include "bsp_leds.h" #include "bsp_buttons.h" #include "bsp_extended.h" // Define size of allocated UART RX/TX buffer (just an example) #define SIZE_OF_UART_RX_BUFFER 50 #define SIZE_OF_UART_TX_BUFFER SIZE_OF_UART_RX_BUFFER #define UART_TST_CHAR_1 0xA5 #define UART_TST_CHAR_2 0xB5 // Test definitions #define UART_TST_MODE_RX #define UART_TST_MODE_TX // Baudrate = 57.6 kbps (U0BAUD.BAUD_M = 34, U0GCR.BAUD_E = 11) #define UART_BAUD_M 34 #define UART_BAUD_E 11 /*********************************************************************************** * LOCAL VARIABLES */ // Buffer for UART RX/TX static uint16 __xdata uartRxBuffer[SIZE_OF_UART_RX_BUFFER]; static uint16 __xdata uartTxBuffer[SIZE_OF_UART_TX_BUFFER]; // Variable for buffer indexing static uint16 __xdata i; // Prototype for local functions void uart0Send(uint16* uartTxBuf, uint16 uartTxBufLength); void uart0Receive(uint16* uartRxBuf, uint16 uartRxBufLength); /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////// #define SPIN_ABOUT_QUARTER_A_SECOND NWK_DELAY(250) #define SPIN_ABOUT_100_MS NWK_DELAY(100) #define NUM_TX_RETRIES 3 #define NO_ACK_THRESHOLD 50 #define RSSI_UPPER_THRESHOLD -40 #define RSSI_LOWER_THRESHOLD -70 #define MINIMUM_OUTPUT_POWER 0 #define MEDIUM_OUTPUT_POWER 1 #define MAXIMUM_OUTPUT_POWER 2 #define SLEEP_31_25_US_RESOLUTION 0 #define SLEEP_1_MS_RESOLUTION 1 #define SLEEP_32_MS_RESOLUTION 2 #define SLEEP_1_S_RESOLUTION 3 #define MASTER_BUTTON 1 #define SLAVE_BUTTON 2 #define BOTH_BUTTONS 3 /*********************************************************************************** * LOCAL VARIABLES */ static linkID_t sLinkID; static volatile uint8_t sSemaphore; static uint8_t sCurrentPwrLevel; static uint8_t sRequestPwrLevel; static uint8_t sNoAckCount = 0; /*********************************************************************************** * LOCAL FUNCTIONS */ static uint8_t sRxCallback(linkID_t); static void sMaster(void); static void sSlave(void); /*********************************************************************************** * @fn main * * @brief This is the main entry of the SMPL link application. It sets * random addresses for the nodes, initalises and runs * MASTER and SLAVE tasks sequentially in an endless loop. * * @return none */ void main (void) { uint8_t buttonPushed; BSP_Init(); /* Create and set random address for this device. */ addr_t lAddr; BSP_createRandomAddress(&lAddr); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr); /* Initialize SimpliciTI and provide Callback function */ SMPL_Init(sRxCallback); /* Turn on LEDs indicating power on */ BSP_TURN_ON_LED1(); BSP_TURN_ON_LED2(); BSP_SleepFor( POWER_MODE_2, SLEEP_1_MS_RESOLUTION, 1000); BSP_TURN_OFF_LED1(); BSP_TURN_OFF_LED2(); /* Enter PM3 until a button is pushed */ buttonPushed = BSP_SleepUntilButton( POWER_MODE_3, BOTH_BUTTONS); if(buttonPushed==1) sMaster(); if(buttonPushed==2) sSlave(); while (1); } /*********************************************************************************** * LOCAL FUNCTIONS */ /*********************************************************************************** * @fn sMaster * * @brief Sends a packet and waits for ACK from slave. * Blinking green led indicates packet acknowledged * Blinking red led indicates packet not acknowledged * Adjust output power dynamically * * @param none * * @return none */ static void sMaster(void) { uint8_t radioMsg[2], len,msg; ioctlRadioSiginfo_t info; sCurrentPwrLevel = MAXIMUM_OUTPUT_POWER; SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &sCurrentPwrLevel); /* Continue to try to link until success */ while (SMPL_SUCCESS != SMPL_Link(&sLinkID)) { BSP_TOGGLE_LED1(); BSP_TOGGLE_LED2(); } BSP_TURN_OFF_LED1(); BSP_TURN_OFF_LED2(); while (1) { /* If SLAVE button pushed, lit both LEDs for 1 second */ if( BSP_BUTTON2() ) { BSP_TURN_ON_LED2(); BSP_SleepFor( POWER_MODE_2, SLEEP_1_MS_RESOLUTION, 5000); BSP_TURN_OFF_LED1(); BSP_TURN_OFF_LED2() ; BSP_TURN_ON_LED1(); } // Configure USART0 for Alternative 1 => Port P0 (PERCFG.U0CFG = 0) // To avoid potential I/O conflict with USART1: // configure USART1 for Alternative 2 => Port P1 (PERCFG.U1CFG = 1) PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U1CFG; // Configure relevant Port P0 pins for peripheral function: // P0SEL.SELP0_2/3/4/5 = 1 => RX = P0_2, TX = P0_3, CT = P0_4, RT = P0_5 P0SEL |= BIT5 | BIT4 | BIT3 | BIT2; /*************************************************************************** * Configure UART * * The system clock source used is the HS XOSC at 26 MHz speed. */ // Set system clock source to 26 Mhz XSOSC to support maximum transfer speed, // ref. [clk]=>[clk_xosc.c] SLEEP &= ~SLEEP_OSC_PD; while( !(SLEEP & SLEEP_XOSC_S) ); CLKCON = (CLKCON & ~(CLKCON_CLKSPD | CLKCON_OSC)) | CLKSPD_DIV_1; while (CLKCON & CLKCON_OSC); SLEEP |= SLEEP_OSC_PD; // Initialise bitrate = 57.6 kbps (U0BAUD.BAUD_M = 34, U0GCR.BAUD_E = 11) U0BAUD = UART_BAUD_M; U0GCR = (U0GCR&~U0GCR_BAUD_E) | UART_BAUD_E; // Initialise UART protocol (start/stop bit, data bits, parity, etc.): // USART mode = UART (U0CSR.MODE = 1) U0CSR |= U0CSR_MODE; // Start bit level = low => Idle level = high (U0UCR.START = 0) U0UCR &= ~U0UCR_START; // Stop bit level = high (U0UCR.STOP = 1) U0UCR |= U0UCR_STOP; // Number of stop bits = 1 (U0UCR.SPB = 0) U0UCR &= ~U0UCR_SPB; // Parity = disabled (U0UCR.PARITY = 0) U0UCR &= ~U0UCR_PARITY; // 9-bit data enable = 8 bits transfer (U0UCR.BIT9 = 0) U0UCR &= ~U0UCR_BIT9; // Level of bit 9 = 0 (U0UCR.D9 = 0), used when U0UCR.BIT9 = 1 // Level of bit 9 = 1 (U0UCR.D9 = 1), used when U0UCR.BIT9 = 1 // Parity = Even (U0UCR.D9 = 0), used when U0UCR.PARITY = 1 // Parity = Odd (U0UCR.D9 = 1), used when U0UCR.PARITY = 1 U0UCR &= ~U0UCR_D9; // Flow control = disabled (U0UCR.FLOW = 0) U0UCR &= ~U0UCR_FLOW; // Bit order = LSB first (U0GCR.ORDER = 0) U0GCR &= ~U0GCR_ORDER; /*************************************************************************** * Transfer UART data */ uint16 uartRxIndex; // Enable UART0 RX (U0CSR.RE = 1) U0CSR |= U0CSR_RE; // Clear any pending RX interrupt request (set U0CSR.RX_BYTE = 0) U0CSR &= ~U0CSR_RX_BYTE; // Loop: receive each UART0 sample from the UART0 RX line BSP_TURN_OFF_LED1(); BSP_TURN_OFF_LED2() ; // Wait until data received (U0CSR.RX_BYTE = 1) while( !(U0CSR&U0CSR_RX_BYTE) ); BSP_TURN_OFF_LED1(); BSP_TURN_ON_LED2() ; // Read UART0 RX buffer /* Build the message */ msg=U0DBUF; for( uint8_t x = 0; x < NUM_TX_RETRIES; x++ ) { SMPL_Send(sLinkID, &msg, sizeof(msg)); /* Turn on RX. default is RX Idle. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); if( sSemaphore ) break; } /* Radio IDLE to save power */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0); } } /*********************************************************************************** * @fn sSlave * * @brief Waits for packet from Master and acknowledge this. * Red led lit means linked to master * Blinking green led indicates packet received * Adjust output power dynamically * * @param none * * @return none */ static void sSlave(void) { P0DIR=0xC3; uint8_t radioMsg[2], len,msg; ioctlRadioSiginfo_t info; sCurrentPwrLevel = MAXIMUM_OUTPUT_POWER; sRequestPwrLevel = MAXIMUM_OUTPUT_POWER; SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_SETPWR, &sCurrentPwrLevel); /* Listen for link forever... */ BSP_TURN_ON_LED1(); BSP_TURN_ON_LED2(); while (SMPL_LinkListen(&sLinkID) != SMPL_SUCCESS) { BSP_TOGGLE_LED1(); BSP_TOGGLE_LED2(); } /* Turning on LED2 to show that we have link*/ BSP_TURN_OFF_LED1(); BSP_TURN_ON_LED2(); /* turn on RX. default is RX off. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0 ); while (1) { if( sSemaphore ) /* Acknowledge successfully received */ { /* Radio IDLE to save power */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0); BSP_TURN_ON_LED2(); BSP_TURN_ON_LED1(); SMPL_Receive(sLinkID, &msg, &len); BSP_TURN_OFF_LED2(); BSP_TURN_OFF_LED1(); sSemaphore = 0; /* Build and send acknowledge */ SMPL_Send(sLinkID, &msg, sizeof(msg)); /*********************************************************************************** * CONSTANTS */ uint16 uartRxIndex; // Clear any pending TX interrupt request (set U0CSR.TX_BYTE = 0) U0CSR &= ~U0CSR_TX_BYTE; //Configure USART0 for Alternative 1 => Port P0 (PERCFG.U0CFG = 0) // To avoid potential I/O conflict with USART1: //configure USART1 for Alternative 2 => Port P1 (PERCFG.U1CFG = 1) PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U1CFG; // Configure relevant Port P0 pins for peripheral function: // P0SEL.SELP0_2/3/4/5 = 1 => RX = P0_2, TX = P0_3, CT = P0_4, RT = P0_5 P0SEL |= BIT5 | BIT4 | BIT3 | BIT2; /*************************************************************************** * Configure UART * * The system clock source used is the HS XOSC at 26 MHz speed. */ // Set system clock source to 26 Mhz XSOSC to support maximum transfer speed, // ref. [clk]=>[clk_xosc.c] SLEEP &= ~SLEEP_OSC_PD; while( !(SLEEP & SLEEP_XOSC_S) ); CLKCON = (CLKCON & ~(CLKCON_CLKSPD | CLKCON_OSC)) | CLKSPD_DIV_1; while (CLKCON & CLKCON_OSC); SLEEP |= SLEEP_OSC_PD; // Initialise bitrate = 57.6 kbps (U0BAUD.BAUD_M = 34, U0GCR.BAUD_E = 11) U0BAUD = UART_BAUD_M; U0GCR = (U0GCR&~U0GCR_BAUD_E) | UART_BAUD_E; // Initialise UART protocol (start/stop bit, data bits, parity, etc.): // USART mode = UART (U0CSR.MODE = 1) U0CSR |= U0CSR_MODE; // Start bit level = low => Idle level = high (U0UCR.START = 0) U0UCR &= ~U0UCR_START; // Stop bit level = high (U0UCR.STOP = 1) U0UCR |= U0UCR_STOP; // Number of stop bits = 1 (U0UCR.SPB = 0) U0UCR &= ~U0UCR_SPB; // Parity = disabled (U0UCR.PARITY = 0) U0UCR &= ~U0UCR_PARITY; // 9-bit data enable = 8 bits transfer (U0UCR.BIT9 = 0) U0UCR &= ~U0UCR_BIT9; // Level of bit 9 = 0 (U0UCR.D9 = 0), used when U0UCR.BIT9 = 1 // Level of bit 9 = 1 (U0UCR.D9 = 1), used when U0UCR.BIT9 = 1 // Parity = Even (U0UCR.D9 = 0), used when U0UCR.PARITY = 1 // Parity = Odd (U0UCR.D9 = 1), used when U0UCR.PARITY = 1 U0UCR &= ~U0UCR_D9; // Flow control = disabled (U0UCR.FLOW = 0) U0UCR &= ~U0UCR_FLOW; // Bit order = LSB first (U0GCR.ORDER = 0) U0GCR &= ~U0GCR_ORDER; // Loop: send each UART0 sample on the UART0 TX line U0DBUF = msg;//uartTxBuf[uartTxIndex] while(! (U0CSR&U0CSR_TX_BYTE) ); /* Turn on RX. default is RX off. */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); } } } /*********************************************************************************** * @fn sRxCallback * * @brief * * @param lid - link id message receive at * * @return 0 - frame left for application to read * 1 - frame could be overwritten */ static uint8_t sRxCallback(linkID_t lid) { if(lid) { sSemaphore = 1; /* Radio IDLE to save power */ SMPL_Ioctl( IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXIDLE, 0); } /* Leave frame to be read by application. */ return 0; }