Subversion Repositories HomeAutomation

Rev

Rev 1775 | Rev 1910 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
1774 arune 1
 
2
#include "act_DotMatrix.h"
3
 
4
#ifdef act_DotMatrix_USEEEPROM
5
#include "act_DotMatrix_eeprom.h"
6
struct eeprom_act_DotMatrix EEMEM eeprom_act_DotMatrix =
7
{
8
    {
9
        /*TODO: Define initialization values on the EEPROM variables here,
10
        this will generate a *.eep file that can be used to store this values to the node,
11
        can in future be done with a EEPROM module and the make-scrips.
12
        Write the values in the exact same order as the struct is defined in the *.h file.
13
        */
14
        0xAB,       // x
15
        0x1234      // y
16
        0x12345678  // z
17
    },
18
 
19
};
20
#endif
21
 
22
uint8_t act_DotMatrix_framebuf[8][4];
23
uint8_t act_DotMatrix_row_counter=0;
24
uint16_t act_DotMatrix_brightness=0;
25
 
26
/* Write a byte on SPI */
27
void act_DotMatrix_SPIWrite(uint8_t data) {
28
    uint8_t dummy = 0;
29
    /* Wait for empty transmit buffer */
30
    while ( !( UCSR0A & (1<<UDRE0)) );
31
    // write data
32
    dummy = UDR0;
33
    UDR0 = data;
34
    waitspi();
35
}
36
 
37
/* Timer callback run periodically to manage rows.
38
   For each time callback is run, the next row is enabled and the last disabled
39
 */
40
void act_DotMatrix_timer_callback(uint8_t timer)
41
{
42
    /* Increase row counter */
43
    if (act_DotMatrix_row_counter++ == 8) {act_DotMatrix_row_counter = 0;}
44
 
45
    /* Disable all rows */
46
    gpio_clr_pin(act_DotMatrix_ROW_IO1);
47
    gpio_clr_pin(act_DotMatrix_ROW_IO2);
48
    gpio_clr_pin(act_DotMatrix_ROW_IO3);
49
    gpio_clr_pin(act_DotMatrix_ROW_IO4);
50
    gpio_clr_pin(act_DotMatrix_ROW_IO5);
51
    gpio_clr_pin(act_DotMatrix_ROW_IO6);
52
    gpio_clr_pin(act_DotMatrix_ROW_IO7);
53
    gpio_clr_pin(act_DotMatrix_ROW_IO8);
54
 
55
    /* Write one column of frame buffer to shift registers */
1776 arune 56
    act_DotMatrix_SPIWrite(act_DotMatrix_framebuf[7-act_DotMatrix_row_counter][3]);
57
    act_DotMatrix_SPIWrite(act_DotMatrix_framebuf[7-act_DotMatrix_row_counter][2]);
58
    act_DotMatrix_SPIWrite(act_DotMatrix_framebuf[7-act_DotMatrix_row_counter][1]);
59
    act_DotMatrix_SPIWrite(act_DotMatrix_framebuf[7-act_DotMatrix_row_counter][0]);
1774 arune 60
    /* Add more here to support 8-module panels */
61
 
62
    /* Toggle shift register latch */
63
    gpio_clr_pin(act_DotMatrix_LATCHCLOCK_IO);
64
    gpio_set_pin(act_DotMatrix_LATCHCLOCK_IO);
65
 
66
    /* Enable one row */
67
    switch (act_DotMatrix_row_counter)
68
    {
69
        case 0:
70
            gpio_set_pin(act_DotMatrix_ROW_IO1);
71
            break;
72
        case 1:
73
            gpio_set_pin(act_DotMatrix_ROW_IO2);
74
            break;
75
        case 2:
76
            gpio_set_pin(act_DotMatrix_ROW_IO3);
77
            break;
78
        case 3:
79
            gpio_set_pin(act_DotMatrix_ROW_IO4);
80
            break;
81
        case 4:
82
            gpio_set_pin(act_DotMatrix_ROW_IO5);
83
            break;
84
        case 5:
85
            gpio_set_pin(act_DotMatrix_ROW_IO6);
86
            break;
87
        case 6:
88
            gpio_set_pin(act_DotMatrix_ROW_IO7);
89
            break;
90
        case 7:
91
            gpio_set_pin(act_DotMatrix_ROW_IO8);
92
            break;
93
 
94
        default:
95
            break;
96
    }
97
}
98
 
99
void act_DotMatrix_Init(void)
100
{
101
#ifdef act_DotMatrix_USEEEPROM
102
    if (EEDATA_OK)
103
    {
104
      ///TODO: Use stored data to set initial values for the module
105
      blablaX = eeprom_read_byte(EEDATA.x);
106
      blablaY = eeprom_read_word(EEDATA16.y);
107
      blablaZ = eeprom_read_dword(EEDATA32.y);
108
    } else
109
    {   //The CRC of the EEPROM is not correct, store default values and update CRC
110
      eeprom_write_byte_crc(EEDATA.x, 0xAB, WITHOUT_CRC);
111
      eeprom_write_word_crc(EEDATA16.y, 0x1234, WITHOUT_CRC);
112
      eeprom_write_dword_crc(EEDATA32.y, 0x12345678, WITHOUT_CRC);
113
      EEDATA_UPDATE_CRC;
114
    }
115
#endif
116
 
117
    /* Set up row driver IO as low output */
118
    gpio_clr_pin(act_DotMatrix_ROW_IO1);
119
    gpio_set_out(act_DotMatrix_ROW_IO1);
120
    gpio_clr_pin(act_DotMatrix_ROW_IO2);
121
    gpio_set_out(act_DotMatrix_ROW_IO2);
122
    gpio_clr_pin(act_DotMatrix_ROW_IO3);
123
    gpio_set_out(act_DotMatrix_ROW_IO3);
124
    gpio_clr_pin(act_DotMatrix_ROW_IO4);
125
    gpio_set_out(act_DotMatrix_ROW_IO4);
126
    gpio_clr_pin(act_DotMatrix_ROW_IO5);
127
    gpio_set_out(act_DotMatrix_ROW_IO5);
128
    gpio_clr_pin(act_DotMatrix_ROW_IO6);
129
    gpio_set_out(act_DotMatrix_ROW_IO6);
130
    gpio_clr_pin(act_DotMatrix_ROW_IO7);
131
    gpio_set_out(act_DotMatrix_ROW_IO7);
132
    gpio_clr_pin(act_DotMatrix_ROW_IO8);
133
    gpio_set_out(act_DotMatrix_ROW_IO8);
134
 
135
    /* Set up PWM controlling brightness */
136
    TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
137
    TCCR0B |= (1<<CS00);
138
    OCR0B = 0xff-act_DotMatrix_INITIAL_BRIGHTNESS;
139
    DDRD |= (1<<PD5);
140
 
141
    /* Set up output latch clock */
142
    gpio_clr_pin(act_DotMatrix_LATCHCLOCK_IO);
143
    gpio_set_out(act_DotMatrix_LATCHCLOCK_IO);
144
 
145
    /* Initialize USART in SPI-mode */
146
    UBRR0 = 0;
147
    USART_SPI_XCK_DDR |= (1<<USART_SPI_XCK); // xck (sck) output
148
    UCSR0C = (1<<UMSEL01)|(1<<UMSEL00)|(0<<UCPHA0)|(0<<UCPOL0);
149
    UCSR0B = (1<<RXEN0)|(1<<TXEN0);
150
    UBRR0 = 0;
151
 
152
    /* Start timer for row management */
153
    Timer_SetTimeout(act_DotMatrix_ROW_TIMER, act_DotMatrix_ROW_TIME, TimerTypeFreeRunning, &act_DotMatrix_timer_callback);
154
 
155
    /* Clear buffer memory */
156
    for (uint8_t i=0; i<8; i++)
157
    {
158
        for (uint8_t j=0; j<4; j++)
159
        {
160
            act_DotMatrix_framebuf[i][j] = act_DotMatrix_INITIAL_ROW;
161
        }
162
    }
163
}
164
 
165
void act_DotMatrix_Process(void)
166
{
167
}
168
 
169
void act_DotMatrix_HandleMessage(StdCan_Msg_t *rxMsg)
170
{
171
    if (    StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT &&
1775 arune 172
        StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
1774 arune 173
        rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_DOTMATRIX &&
174
        rxMsg->Header.ModuleId == act_DotMatrix_ID)
175
    {
176
        switch (rxMsg->Header.Command)
177
        {
178
        /* If brightness should be adjusted */
179
        case CAN_MODULE_CMD_PHYSICAL_PWM:
180
            if (rxMsg->Length == 3) {
181
                act_DotMatrix_brightness = (rxMsg->Data[1]<<8)+(rxMsg->Data[2]);
182
 
1775 arune 183
                if (OCR0B != 0xff-((uint16_t)(act_DotMatrix_brightness*act_DotMatrix_PWM_FACT)>>8)) {
1774 arune 184
                    cli(); 
1775 arune 185
                    OCR0B=0xff-((uint16_t)(act_DotMatrix_brightness*act_DotMatrix_PWM_FACT)>>8);
1774 arune 186
                    sei();
187
                }
188
            }
189
            break;
190
        /* If data to first module */
191
        case CAN_MODULE_CMD_DOTMATRIX_IMAGEDATAMODULE1:
192
            for (uint8_t i=0; i<8; i++)
193
            {
194
                act_DotMatrix_framebuf[i][0] = rxMsg->Data[i];
195
            }
196
            break;
197
        /* If data to second module */
198
        case CAN_MODULE_CMD_DOTMATRIX_IMAGEDATAMODULE2:
199
            for (uint8_t i=0; i<8; i++)
200
            {
201
                act_DotMatrix_framebuf[i][1] = rxMsg->Data[i];
202
            }
203
            break;
204
        /* If data to third module */
205
        case CAN_MODULE_CMD_DOTMATRIX_IMAGEDATAMODULE3:
206
            for (uint8_t i=0; i<8; i++)
207
            {
208
                act_DotMatrix_framebuf[i][2] = rxMsg->Data[i];
209
            }
210
            break;
211
        /* If data to fourth module */
212
        case CAN_MODULE_CMD_DOTMATRIX_IMAGEDATAMODULE4:
213
            for (uint8_t i=0; i<8; i++)
214
            {
215
                act_DotMatrix_framebuf[i][3] = rxMsg->Data[i];
216
            }
217
            break;
218
        }
219
    }
220
}
221
 
222
void act_DotMatrix_List(uint8_t ModuleSequenceNumber)
223
{
224
    StdCan_Msg_t txMsg;
225
 
226
    StdCan_Set_class(txMsg.Header, CAN_MODULE_CLASS_ACT);
227
    StdCan_Set_direction(txMsg.Header, DIRECTIONFLAG_FROM_OWNER);
228
    txMsg.Header.ModuleType = CAN_MODULE_TYPE_ACT_DOTMATRIX;
229
    txMsg.Header.ModuleId = act_DotMatrix_ID;
230
    txMsg.Header.Command = CAN_MODULE_CMD_GLOBAL_LIST;
231
    txMsg.Length = 6;
232
 
233
    txMsg.Data[0] = NODE_HW_ID_BYTE0;
234
    txMsg.Data[1] = NODE_HW_ID_BYTE1;
235
    txMsg.Data[2] = NODE_HW_ID_BYTE2;
236
    txMsg.Data[3] = NODE_HW_ID_BYTE3;
237
 
238
    txMsg.Data[4] = NUMBER_OF_MODULES;
239
    txMsg.Data[5] = ModuleSequenceNumber;
240
 
241
    while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
242
}