Hi everybody,
I am trying to modify the code of "Demo Application for SimpliciTI" which can establish link between ED and AP and display on the PC. My problem is i can only establish one link. when i try to add more EDs to establish link with AP, it only display one link established on PC.
/* reserve space for the maximum possible peer Link IDs */
static linkID_t sLID[NUM_CONNECTIONS] = {0};
static uint8_t sNumCurrentPeers = 0;
/* callback handler */
static uint8_t sCB(linkID_t);
/* received message handler */
static void processMessage(linkID_t, uint8_t *, uint8_t);
/* Frequency Agility helper functions */
static void checkChangeChannel(void);
static void changeChannel(void);
/* work loop semaphores */
static volatile uint8_t sPeerFrameSem = 0;
static volatile uint8_t sJoinSem = 0;
#ifdef FREQUENCY_AGILITY
/* ************** BEGIN interference detection support */
#define INTERFERNCE_THRESHOLD_DBM (-70)
#define SSIZE 25
#define IN_A_ROW 3
static int8_t sSample[SSIZE];
static uint8_t sChannel = 0;
#endif /* FREQUENCY_AGILITY */
/* blink LEDs when channel changes... */
static volatile uint8_t sBlinky = 0;
/* ************** END interference detection support */
#define SPIN_ABOUT_A_QUARTER_SECOND NWK_DELAY(250)
unsigned char Uart1RxBuf[256];
unsigned char MBRcvCnt;
const char String1[22] = "\nOne Link Establish\r\n";
const char String2[22] = "\nTwo Link Establish\r\n";
const char String3[15] = "\nEnd Device 1\r\n";
const char String4[15] = "\nLink Lost\r\n";
void main (void)
{
bspIState_t intState;
memset(sSample, 0x0, sizeof(sSample));
BSP_Init();
/* If an on-the-fly device address is generated it must be done before the
* call to SMPL_Init(). If the address is set here the ROM value will not
* be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call
* will not take effect. One shot only. The IOCTL call below is conformal.
*/
PMAPPWD = 0x02D52; // Get write-access to port mapping regs
P2MAP6 = PM_UCA0RXD; // Map UCA0RXD output to P2.6
P2MAP7 = PM_UCA0TXD; // Map UCA0TXD output to P2.7
PMAPPWD = 0; // Lock port mapping registers
P2DIR |= BIT7; // Set P2.7 as TX output
P2SEL |= BIT7; // Select P2.6 & P2.7 to UART function
UCA0CTL1 |= UCSWRST; // 8-bit characters
UCA0CTL1 = UCSSEL_1; // CLK = ACLK
UCA0BR0 = 0x03; // 32k/9600=3.41
UCA0BR1 = 0x00;
UCA0MCTL = UCBRS_3+UCBRF_0; // Modulation
UCA0CTL1 &= ~UCSWRST; // Release USCI state machine
DMACTL0 = DMA0TSEL_17; // USCI_A0 TXIFG trigger
__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) String1);
// Source block address
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &UCA0TXBUF);
// Destination single address
DMA0SZ = sizeof(String1); // Block size
DMA0CTL = DMASRCINCR_3+DMASBDB+DMALEVEL; // Repeat, inc src
#ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE
{
addr_t lAddr;
createRandomAddress(&lAddr);
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
}
#endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */
SMPL_Init(sCB);
/* green and red LEDs on solid to indicate waiting for a Join. */
if (!BSP_LED2_IS_ON())
{
toggleLED(2);
}
if (!BSP_LED1_IS_ON())
{
toggleLED(1);
}
/* main work loop */
while (1)
{
/* Wait for the Join semaphore to be set by the receipt of a Join frame from a
* device that supports an End Device.
*
* An external method could be used as well. A button press could be connected
* to an ISR and the ISR could set a semaphore that is checked by a function
* call here, or a command shell running in support of a serial connection
* could set a semaphore that is checked by a function call.
*/
if (sJoinSem && (sNumCurrentPeers < NUM_CONNECTIONS))
{
/* listen for a new connection */
while (1)
{
if(sPeerFrameSem==0)
{
DMA0CTL |= DMAEN;
sPeerFrameSem++;
}
else if(sPeerFrameSem==1)
{
DMACTL0 = DMA0TSEL_17; // USCI_A0 TXIFG trigger
__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) String2);
// Source block address
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &UCA0TXBUF);
// Destination single address
DMA0SZ = sizeof(String2); // Block size
DMA0CTL = DMASRCINCR_3+DMASBDB+DMALEVEL; // Repeat, inc src
DMA0CTL |= DMAEN;
}
if (SMPL_SUCCESS == SMPL_LinkListen(&sLID[sNumCurrentPeers]))
{
break;
}
/* Implement fail-to-link policy here. otherwise, listen again. */
//Write some thing to serial
}
sNumCurrentPeers++;
BSP_ENTER_CRITICAL_SECTION(intState);
sJoinSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
}
/* Have we received a frame on one of the ED connections?
* No critical section -- it doesn't really matter much if we miss a poll
*/
if (sPeerFrameSem)
{
uint8_t msg[MAX_APP_PAYLOAD], len, i;
/* process all frames waiting */
for (i=0; i<sNumCurrentPeers; ++i)
{
if (SMPL_SUCCESS == SMPL_Receive(sLID[i], msg, &len))
{
processMessage(sLID[i], msg, len);
BSP_ENTER_CRITICAL_SECTION(intState);
sPeerFrameSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
}
}
}
if (BSP_BUTTON1())
{
SPIN_ABOUT_A_QUARTER_SECOND; /* debounce */
changeChannel();
}
else
{
checkChangeChannel();
}
BSP_ENTER_CRITICAL_SECTION(intState);
if (sBlinky)
{
if (++sBlinky >= 0xF)
{
sBlinky = 1;
toggleLED(1);
toggleLED(2);
}
}
BSP_EXIT_CRITICAL_SECTION(intState);
}
}
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
{
switch(__even_in_range(UCA0IV,4))
{
case 0:break; // Vector 0 - no interrupt
case 2: // Vector 2 - RXIFG
while (!(UCA0IFG&UCTXIFG)); // USCI_A0 TX buffer ready?
UCA0TXBUF = UCA0RXBUF; // TX -> RXed character
break;
case 4:break; // Vector 4 - TXIFG
default: break;
}
}
void toggleLED(uint8_t which)
{
if (1 == which)
{
BSP_TOGGLE_LED1();
}
else if (2 == which)
{
BSP_TOGGLE_LED2();
}
return;
}
/* Runs in ISR context. Reading the frame should be done in the */
/* application thread not in the ISR thread. */
static uint8_t sCB(linkID_t lid)
{
if (lid)
{
sPeerFrameSem++;
sBlinky = 0;
}
else
{
sJoinSem++;
}
/* leave frame to be read by application. */
return 0;
}
static void processMessage(linkID_t lid, uint8_t *msg, uint8_t len)
{
DMACTL0 = DMA0TSEL_17; // USCI_A0 TXIFG trigger
__data16_write_addr((unsigned short) &DMA0SA,(unsigned long) String3);
// Source block address
__data16_write_addr((unsigned short) &DMA0DA,(unsigned long) &UCA0TXBUF);
// Destination single address
DMA0SZ = sizeof(String3); // Block size
DMA0CTL = DMASRCINCR_3+DMASBDB+DMALEVEL; // Repeat, inc src
DMA0CTL |= DMAEN;
if (len)
{
toggleLED(*msg);
}
return;
}
static void changeChannel(void)
{
#ifdef FREQUENCY_AGILITY
freqEntry_t freq;
if (++sChannel >= NWK_FREQ_TBL_SIZE)
{
sChannel = 0;
}
freq.logicalChan = sChannel;
SMPL_Ioctl(IOCTL_OBJ_FREQ, IOCTL_ACT_SET, &freq);
BSP_TURN_OFF_LED1();
BSP_TURN_OFF_LED2();
sBlinky = 1;
#endif
return;
}
/* implement auto-channel-change policy here... */
static void checkChangeChannel(void)
{
#ifdef FREQUENCY_AGILITY
int8_t dbm, inARow = 0;
uint8_t i;
memset(sSample, 0x0, SSIZE);
for (i=0; i<SSIZE; ++i)
{
/* quit if we need to service an app frame */
if (sPeerFrameSem || sJoinSem)
{
return;
}
NWK_DELAY(1);
SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RSSI, (void *)&dbm);
sSample[i] = dbm;
if (dbm > INTERFERNCE_THRESHOLD_DBM)
{
if (++inARow == IN_A_ROW)
{
changeChannel();
break;
}
}
else
{
inARow = 0;
}
}
#endif
return;
}