Subversion Repositories HomeAutomation

Rev

Rev 1910 | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1.  
  2. #include "act_DotMatrix.h"
  3.  
  4. #if act_DotMatrix_USEEEPROM==1
  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.     0   // crc, must be a correct value, but this will also be handled by the EEPROM module or make scripts
  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 */
  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]);
  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. #if act_DotMatrix_USEEEPROM==1
  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 &&
  172.         StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&
  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.  
  183.                 if (OCR0B != 0xff-((uint16_t)(act_DotMatrix_brightness*act_DotMatrix_PWM_FACT)>>8)) {
  184.                     cli(); 
  185.                     OCR0B=0xff-((uint16_t)(act_DotMatrix_brightness*act_DotMatrix_PWM_FACT)>>8);
  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.     uint32_t HwId=BIOS_GetHwId();
  234.     txMsg.Data[0] = HwId&0xff;
  235.     txMsg.Data[1] = (HwId>>8)&0xff;
  236.     txMsg.Data[2] = (HwId>>16)&0xff;
  237.     txMsg.Data[3] = (HwId>>24)&0xff;
  238.  
  239.     txMsg.Data[4] = NUMBER_OF_MODULES;
  240.     txMsg.Data[5] = ModuleSequenceNumber;
  241.  
  242.     while (StdCan_Put(&txMsg) != StdCan_Ret_OK);
  243. }
  244.