Subversion Repositories HomeAutomation

Rev

Rev 1978 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1266 pengi 1
 
2
#include "chn_ChnMaster.h"
3
 
4
struct chn_ChnMaster_listener_t {
5
    uint16_t channel_id;
6
    void (*update_func)(uint16_t, uint16_t); /* channel, value */
7
};
8
 
9
struct chn_ChnMaster_listener_t chn_ChnMaster_listeners[ chn_ChnMaster_MAX_LISTENERS ];
10
uint8_t chn_ChnMaster_listenCount = 0;
11
 
1726 pengi 12
struct chn_ChnMaster_buffer_t {
13
    uint16_t channel_id;
14
    uint16_t value;
15
} chn_ChnMaster_buffer[ chn_ChnMaster_BUFFER_SIZE ];
1266 pengi 16
 
1726 pengi 17
volatile uint8_t chn_ChnMaster_buf_in_pos = 0; // next to write
18
volatile uint8_t chn_ChnMaster_buf_out_pos = 0; // next to read
1266 pengi 19
 
1978 arune 20
#if chn_ChnMaster_USEEEPROM==1
1266 pengi 21
#include "chn_ChnMaster_eeprom.h"
22
struct eeprom_chn_ChnMaster EEMEM eeprom_chn_ChnMaster =
23
{
24
    {
25
        ///TODO: Define initialization values on the EEPROM variables here, this will generate a *.eep file that can be used to store this values to the node, can in future be done with a EEPROM module and the make-scrips. Write the values in the exact same order as the struct is defined in the *.h file. 
26
        0xAB,    // x
27
        0x1234    // y
28
    },
29
 
30
};
31
#endif
32
 
33
void chn_ChnMaster_RegisterListener( uint16_t channel_id, void (*update_func)(uint16_t, uint16_t) ) {
34
    chn_ChnMaster_listeners[ chn_ChnMaster_listenCount ].update_func = update_func;
35
    chn_ChnMaster_listeners[ chn_ChnMaster_listenCount ].channel_id = channel_id;
36
    chn_ChnMaster_listenCount++;
37
}
38
 
39
void chn_ChnMaster_UpdateChannel( uint16_t channel_id, uint16_t value ) {
40
    StdCan_Msg_t txMsg;
41
    txMsg.Id = 0;
42
    StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_CHN);
43
 
2032 pengi 44
    txMsg.Id |= ((uint32_t)channel_id) << 8;
1266 pengi 45
    txMsg.Id |= chn_ChnMaster_ID;
46
 
47
    txMsg.Length = 2;
48
    txMsg.Data[0] = (value     >>8)&0xFF;
49
    txMsg.Data[1] = (value        )&0xFF;
50
 
51
    while( StdCan_Put(&txMsg) != StdCan_Ret_OK );
52
}
53
 
54
 
1726 pengi 55
void chn_ChnMaster_Init(void) {
1266 pengi 56
}
57
 
58
void chn_ChnMaster_Process(void)
59
{
1726 pengi 60
    uint16_t value;
61
    uint16_t channel_id;
62
    uint8_t i;
63
    while( chn_ChnMaster_buf_out_pos != chn_ChnMaster_buf_in_pos ) {
64
        value      = chn_ChnMaster_buffer[chn_ChnMaster_buf_out_pos].value;
65
        channel_id = chn_ChnMaster_buffer[chn_ChnMaster_buf_out_pos].channel_id;
66
 
67
        for( i=0; i<chn_ChnMaster_listenCount; i++ ) {
68
            if( chn_ChnMaster_listeners[i].channel_id == channel_id ) {
69
                (*chn_ChnMaster_listeners[i].update_func)( channel_id, value );
70
            }
71
        }
72
 
73
        chn_ChnMaster_buf_out_pos = (chn_ChnMaster_buf_out_pos+1)%chn_ChnMaster_BUFFER_SIZE;
74
    }
1266 pengi 75
    ///TODO: Stuff that needs doing is done here
76
}
77
 
78
void chn_ChnMaster_HandleMessage(StdCan_Msg_t *rxMsg)
79
{
1726 pengi 80
    uint8_t j;
1266 pengi 81
    uint16_t channel_id;
82
    uint16_t value;
83
    if ( StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_CHN)
84
    {
1726 pengi 85
        channel_id = (rxMsg->Id >> 8) & 0xFFFF;
1266 pengi 86
        if( (rxMsg->Id & (1L<<24)) == 0 ) { /* Value */
87
            for( j=0; j<(rxMsg->Length&~1); j+=2 ) {
88
                value      = (rxMsg->Data[j]<<8) | rxMsg->Data[j+1];
1726 pengi 89
/*
1266 pengi 90
                for( i=0; i<chn_ChnMaster_listenCount; i++ ) {
91
                    if( chn_ChnMaster_listeners[i].channel_id == channel_id ) {
92
                        (*chn_ChnMaster_listeners[i].update_func)( channel_id, value );
93
                    }
94
                }
1726 pengi 95
                */
96
                chn_ChnMaster_buffer[chn_ChnMaster_buf_in_pos].channel_id = channel_id;
97
                chn_ChnMaster_buffer[chn_ChnMaster_buf_in_pos].value = value;
98
                chn_ChnMaster_buf_in_pos = (chn_ChnMaster_buf_in_pos+1)%chn_ChnMaster_BUFFER_SIZE;
1266 pengi 99
                channel_id++;
100
            }
101
        } else { /* Metadata */
102
        }
103
    }
104
}
105
 
106
void chn_ChnMaster_List(uint8_t ModuleSequenceNumber)
107
{
108
    StdCan_Msg_t txMsg;
109
 
110
    StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_CHN);
111
    StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
112
    txMsg.Header.ModuleType = CAN_MODULE_TYPE_CHN_CHNMASTER;
113
    txMsg.Header.ModuleId = chn_ChnMaster_ID;
114
    txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
115
    txMsg.Length = 6;
116
 
1910 arune 117
    uint32_t HwId=BIOS_GetHwId();
118
    txMsg.Data[0] = HwId&0xff;
119
    txMsg.Data[1] = (HwId>>8)&0xff;
120
    txMsg.Data[2] = (HwId>>16)&0xff;
121
    txMsg.Data[3] = (HwId>>24)&0xff;
1266 pengi 122
 
123
    txMsg.Data[4] = NUMBER_OF_MODULES;
124
    txMsg.Data[5] = ModuleSequenceNumber;
125
 
126
    while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
127
}