DolphinV4 API  1.6.1.0
Controller Application

Controller application example files

Controller Application file - main.c

/************************************************************************-
EVA Board:
EVA300-3
Input PIN:
ADIO_3 (LEARN button)
When pressing this button the controllers enters to LearnMode.
It is signalised with the RSDADIO_3 (LMI led). In learn mode the controller is
prepared to receive LEARN telegrams with profile definition from the Sensors.
Using the define MAX_SMACK_SENSORS the maximum number of sensors to learn in
can be set. When the ADIO_3 is pressed second time the Controller quits from
LEARN mode
ADIO_4 (CLEAR button)
By pressing this button the controller places an answer for each learned
in sensor to the mailbox. Now press the WAKE_0 on the sensor side
to fetch this reclaim or wait 1 hour until the reclaim is automaticaly fetched
by the sensor. The reclaim process result will the sensor transmit
in the next data telegram.
ADIO_6
for UART communication
Output PIN:
SCSEDIO_0
Signalises every time a data telegram is received and sent through UART.
RSDADIO_3 (LMI led)
Signalises if the sensor is in LEARN mode.
ADIO_7
for UART communication
Description:
The Controller Application Example implements a Controller with a PostMaster role.
The implemented Controller has three tasks:
- stores the learned sensors in it's learn table
- acts as a PostMaster and organises reclaim messages
- acts as a gateway and all received packets transmits to the UART port
In the example it is considered that there is no backbone connected to the Controller.
Therefore reclaim data messages are placed to the mailbox only when the GPIO1
pin button is pushed.
To initialize SmartACK functionality use the DolphinStudio GenericAPP page.
DolphinStudio will add the #smack_init function in EO3100I_INIT macro
in EO3100I_CFG.h file. It will also exchange the isr_timer0 scheduller with the
function #isr_timer0_smack_PM_Init. This smack scheduller is responsible
for the PostMaster functionality.
When the controller is switched to the learn mode by its application, it is
necessary to call #smack_LearnOn and when the learn mode finishes, #smack_LearnOff
has to be called. This is importand for the SmartACK API to correctly react to
received learn telegrams. To get the result of the learn process call #smack_getLearnResult.
And to finalize the learn process call #smack_finalizeLearn.
When the controller receives EnOcean standard telegram from a learned in sensor,
the answer can be put into the post box of the sensor using the #smack_sendDataTelegram
function. When the sensor sends a reclaim, this telegram will automatically be sent to
the sensor. It is necessary to call #smack_processController periodical to
guarantee correct SmartACK functionality.
For more information read the source code of the program.
Simple and advanced learn mode:
-------------------------------
The learn mode is due to customer usability separated into simple and advanced.
Advanced mode is more complex and therefore customer should be explicitly aware of using it.
Simple mode
Only controller can become Post Master. Repeaters are not allowed to become
Post Master. That presumes a direct "good-enough" link between Controller and
Sensor is available.
Advanced mode
A remote Smart Ack device can become Post Master.</li>
Notes:
-************************************************************************/
#include "EO3100I_API.h"
#include "EO3100I_CFG.h"
#include "main.h"
code uint8 VERSION_APP[] = {0xE0,'V','E','R','S','I','O','N',1,0,2,0,'A','S','M','A','C','K','C','O','N','T','R','O','L','L','E','R',0x00,0xE0};
#define LED_ADIO5 SCSEDIO_0 // Rx telegram
#define LED_CH2 SCLKDIO_1 // Data in mailbox
#define LED_LMI RSDADIO_3 // learn mode
#define BTN_LEARN ADIO_3 // learn mode control
#define BTN_CLEAR ADIO_4 // reply data simulation (fill mailbox)
#define ledRxOff() io_setDigital(LED_ADIO5, 0)
#define ledRxToggle() io_togDigital(LED_ADIO5)
#define ledDataToggle() io_togDigital(LED_CH2)
#define ledLmiOn() io_setDigital(LED_LMI, 1)
#define ledLmiOff() io_setDigital(LED_LMI, 0)
LEARN_RESULT xdata smSensors[MAX_SMACK_SENSORS] _at_ 0x100;
#define BTN_ACTIVE 0 // switch to gnd -> ext. 100k pullup
BTN_STRUCT LEARN_BUTTON = { BTN_LEARN, // Pin
BTN_ACTIVE, // Active state
5, // Time the button has to be in 'Active state' to be recognized as pressed
100 };
BTN_STRUCT DATA_BUTTON = { BTN_CLEAR, // Pin
BTN_ACTIVE, // Active state
5, // Time the button has to be in 'Active state' to be recognized as pressed
100 };
uint8 xdata u8ShadowBuffer[256] _at_ 0x0;
uint8 Send_something(void);
uint8 Action_something(void);
uint8 Write_Flash(void);
uint8 GetFunctionCodes(void);
void WaitTime(uint16*);
void main()
{
uint8 u8Count;
bit1 bLearnModeOn = FALSE;
mainInit();
//read the learn table of the application
mem_readFlash((uint8 xdata *)&smSensors,APP_FLASH_LEARN_TABLE,sizeof(smSensors));
//enable radio
ledRxOff();
ledLmiOff();
u8gGERssiDbm = 0x80;
while (1)
{
//If new telegram has arrived pass telegrams to UART
if (radio_getTelegram2(&rTel, &pTel2) == OK)
{
ledRxToggle();
//Setting the serial packet data buffer to the incoming telegram buffer
sTel.u8DataBuffer = &rTel.raw.bytes[0];
memcpy(&sTel.u8DataBuffer[rTel.raw.u8Length], &pTel2.p_rx, 2);
sTel.u16DataLength = rTel.raw.u8Length;
sTel.u8OptionLength = 2;
while (uart_sendPacket(&sTel) != OK);
}
//Check LEARN button, if pressed toggle learn mode
if (btn_getState(&LEARN_BUTTON)==BTN_PRESSED)
{
bLearnModeOn = ~bLearnModeOn;
if (bLearnModeOn)
{
ledLmiOn();
smack_LearnOn(0,30000);
}
else
{
ledLmiOff();
}
}
//When all SMACK learn request telegrams were collected we can start the application learn process
switch(smack_processController(&u8ShadowBuffer))
{
case(RESULT_READY):
{
executeLearn();
break;
}
{
bLearnModeOn = ~bLearnModeOn;
//indicate learn mode
ledLmiOff();
}
default:
break;
}
//Simulate fetching data from the backbone and putting it to the postmaster mailbox
if (btn_getState(&DATA_BUTTON)==BTN_PRESSED)
{
ledDataToggle();
//Check all sensors ID and prepare an answere for all of them
for(u8Count=0; u8Count<MAX_SMACK_SENSORS; u8Count++)
{
//if the sensors ID is used prepare response telegram
if(smSensors[u8Count].u32SensorId != NO_SENSOR_ID)
{
r4bs.t4bs.u8Choice = RADIO_CHOICE_4BS;
//Dummy data
r4bs.t4bs.u8Data3 = 0xAF;
r4bs.t4bs.u8Data2 = 0xFE;
r4bs.t4bs.u8Data1 = 0x00;
r4bs.t4bs.u8Data0 = u8Count;
//take the chip ID
r4bs.t4bs.u32Id = 0x0410007F;
r4bs.t4bs.u8Status = 0x00;
//set the sensor address
pTel.p_tx.u32DestinationId = smSensors[u8Count].u32SensorId;
pTel.p_tx.u8SubTelNum = 0x1;
//place response to the PostMaster mailbox
smack_sendDataTelegram(&r4bs, &pTel);
}
}
}
}
}



Controller Application include file - main.h

#ifndef _TESTMAIN_H_INCLUDED
#define _TESTMAIN_H_INCLUDED
#include "EO3100I_API.h"
#include "string.h"
#include "mod_button.h"
//Table to store the data of the sensors in FLASH
#define APP_FLASH_LEARN_TABLE 0x7600
//maximum number of sensor that can be learned in
#define MAX_SMACK_SENSORS 2
//Define in the flash indicating no ID
#define NO_SENSOR_ID 0xFFFFFFFF
//The time the controller can provide the answer data for the sensors postmaster, in this example dummy value
//because we are the controller and postmaster in one module and we are not connected to a backbone
#define RESPONSE_TIME 0x0080
typedef struct
{
uint32 u32SensorId;
uint32 u32PostMasterId;
uint8 u8LearnCount;
}LEARNED_SENSORS;
extern LEARN_RESULT xdata smSensors[MAX_SMACK_SENSORS];
void executeLearn();
#endif



Controller Application file for learn - executeLearn.c

#include "main.h"
void executeLearn()
{
uint8 u8Count;
LEARN_RESULT smResult;
//Get the result of Smack learn
//Check all sensors ID which should be learned in with the current controller
for(u8Count=0;u8Count<MAX_SMACK_SENSORS;u8Count++)
{
//if the sensors ID was already learned in, then learn them out
if(smSensors[u8Count].u32SensorId==smResult.u32SensorId)
{
//learn out, for the smack_finalizeLearn upon LearnOut no response time is needed so that's why NULL
//delete sensor ID
smSensors[u8Count].u32SensorId = NO_SENSOR_ID;
//store APP leearn table
mem_writeFlash((uint8)smSensors,APP_FLASH_LEARN_TABLE,sizeof(smSensors));
return;
}
}
//Sensor ID not found so the Application needs to learn it in, proove if it is a correct result,
if( (smResult.u8Priority & PF_PLACE_OK)&&(smResult.u8Priority & PF_RSSI_OK))
{
//search for free place in the APP learn table
for(u8Count=0;u8Count<MAX_SMACK_SENSORS;u8Count++)
{
if(smSensors[u8Count].u32SensorId == NO_SENSOR_ID)
break;
}
//if no free place in APP learn table, discard the learn request, no response time is needed
if(u8Count == MAX_SMACK_SENSORS)
{
return;
}
//there is a free place, learn in the sensor
smSensors[u8Count].u32SensorId = smResult.u32SensorId;
smSensors[u8Count].u32CandidateId = smResult.u32CandidateId;
smack_finalizeLearn(&smResult, ACK_CODE_LEARN_IN, RESPONSE_TIME);
//store the APP learn table
mem_writeFlash((uint8)smSensors,APP_FLASH_LEARN_TABLE,sizeof(smSensors));
return;
}
//if(smResult.u8Priority==0)
//If the priorities were incorrect (for example Postmaster had no free place), discard the learn request
if(smResult.u8Priority & PF_RSSI_OK)
else
}



Config file - EO3100I_CFG.h

// Generated on 2013-06-07 15:28:54 by DolphinAPIConfigurator 1.1.0.20
#ifndef _EO3100I_CFG_H_INCLUDED
#define _EO3100I_CFG_H_INCLUDED
void startupInit();
void mainInit();
//*********************SMACK PARAM***************************
#define MAILBOX_COUNT 10
#define MAILBOX_FLASH_ADDR 0x7500
extern volatile MAILBOX_XRAM xdata gMailBoxXRam[MAILBOX_COUNT];
extern uint16 code smack_param[];
extern uint8 code u8gSmartAckFlash[256];
//*********************UART PARAM***************************
#define RX_RING_SIZE 34
#define TX_RING_SIZE 34
extern volatile uint8 xdata u8RxRing[RX_RING_SIZE];
extern volatile uint8 xdata u8TxRing[TX_RING_SIZE];
extern uint8 uart_param[];
//*********************RADIO PARAM***************************
#define RADIO_BUFF_NUM 10
#define RADIO_MATURITY_TIME 100
extern volatile RADIO_BUFFER_TYPE xdata gRadioBuff[RADIO_BUFF_NUM];
//*********************FILTER PARAM***************************
#define FILTER_NUM 1
extern volatile uint32 xdata u32gFilterValue[FILTER_NUM];
extern volatile uint8 xdata u8gFilterCfg[FILTER_NUM];
//*********************IO PARAM******************************
extern uint8 code io_param[];
#endif //_EO3100I_CFG_H_INCLUDED



Config file - EO3100I_CFG.c

// Generated on 2013-06-07 15:29:08 by DolphinAPIConfigurator 1.1.0.20
#include "EO3100I_API.h"
#include "EO3100I_CFG.h"
//*********************API INIT***************************
//Note: Function is called from startup.a51. Global variables are not yet initialized!
void startupInit()
{
io_init(io_param);
}
void mainInit()
{
radio_init(RADIO_BUFF_NUM, RADIO_MATURITY_TIME);
UART_INIT(uart_param, SET_ALL_PARAM);
smack_init(smack_param, SET_ALL_PARAM);
}
//*********************SMACK PARAM***************************
volatile MAILBOX_XRAM xdata gMailBoxXRam[MAILBOX_COUNT];
uint16 code smack_param[] = {
MAILBOX_COUNT, //IDX_MAILBOX_COUNT
MAILBOX_FLASH_ADDR //IDX_MAILBOX_FLASH_ADDR
};
uint8 code u8gSmartAckFlash[256] _at_ MAILBOX_FLASH_ADDR;
//*********************UART PARAM***************************
volatile uint8 xdata u8RxRing[RX_RING_SIZE];
volatile uint8 xdata u8TxRing[TX_RING_SIZE];
uint8 uart_param[] = {
BAUD_57600, //IDX_BAUD
RX_RING_SIZE, //IDX_RX_RING_SIZE
TX_RING_SIZE, //IDX_TX_RING_SIZE
};
//*********************RADIO PARAM***************************
volatile RADIO_BUFFER_TYPE xdata gRadioBuff[RADIO_BUFF_NUM];
//*********************FILTER PARAM***************************
volatile uint32 xdata u32gFilterValue[FILTER_NUM];
volatile uint8 xdata u8gFilterCfg[FILTER_NUM];
//*********************IO PARAM******************************
uint8 code io_param[] = {
0x07, //IDX_GPIO_CONF
0x00, //IDX_GPIO0_CONF
0x04, //IDX_GPIO0_PULL_CONF
0x0B, //IDX_GPIO0_DIR
0x00, //IDX_GPIO1_AN
0x00, //IDX_GPIO1_CONF0
0xC0, //IDX_GPIO1_CONF1
0x03, //IDX_GPIO1_DIG_CONF
0x80, //IDX_GPIO1_DIR
0x7F, //IDX_GPIO1_PULL
0x0C, //IDX_GPIO2_CONF
0x00, //IDX_GPIO2_DIR
0x00, //IDX_GPIO0
0x00, //IDX_GPIO1
0x00, //IDX_GPIO2
};
// I/O Configuration overview
//
// Pin : Interface Direction Pull InitValue Interrupt
// SCSEDIO0 : Digital I/O Out None 0 No
// SCLKDIO1 : Digital I/O Out None 0 No
// WSDADIO2 : Digital I/O In Up 0 No
// RSDADIO3 : Digital I/O Out None 0 No
// ADIO0 : Digital I/O In Up 0 No
// ADIO1 : Digital I/O In Up 0 No
// ADIO2 : Digital I/O In Up 0 No
// ADIO3 : Digital I/O In Up 0 No
// ADIO4 : Digital I/O In Up 0 No
// ADIO5 : Digital I/O In Up 0 No
// ADIO6 : UART In Up 0 No
// ADIO7 : UART Out None 0 No
// WXIDIO : Digital I/O In Up 0 No
// WXODIO : Digital I/O In Up 0 No
// WAKE0 : Digital I/O In None 0 No
// WAKE1 : Digital I/O In None 0 No