Subversion Repositories HomeAutomation

Rev

Rev 344 | Rev 349 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | SVN | RSS feed

  1. /**
  2.  * CanCLCD. Simple version.
  3.  * For HD44780- and KS0073-based LCD displays
  4.  *
  5.  * @date    2006-12-11
  6.  * @author  Erik Larsson
  7.  *
  8.  */
  9.  
  10. /*-----------------------------------------------------------------------------
  11.  * Includes
  12.  *---------------------------------------------------------------------------*/
  13. /* system files */
  14. #include <avr/io.h>
  15. #include <avr/interrupt.h>
  16. #include <stdio.h>
  17. /* lib files */
  18. #include <bios.h>
  19. #include <lcd_HD44780.h>
  20. /* funcdefs */
  21. #include <funcdefs.h>
  22.  
  23. /* defines */
  24. #define SIZE_X  20
  25. #define SIZE_Y  4
  26. #define SIZE_LCD LCD_SIZE_20x4
  27.  
  28. #define BUFFER_SIZE SIZE_X
  29. #define TRUE 1
  30. #define FALSE 0
  31.  
  32. #define LEFT    0x01
  33. #define RIGHT   0x02
  34.  
  35. Can_Message_t txMsg;
  36.  
  37. char incoming_text[ BUFFER_SIZE ];
  38. uint8_t msg_received = FALSE;
  39.  
  40. uint8_t rot_lastdir = 0,
  41.         rot_laststate = 0;
  42.  
  43.     char buffer[ BUFFER_SIZE ];
  44.  
  45. void send_dimensions();
  46.  
  47. void can_receive(Can_Message_t *msg){
  48.     uint32_t act;
  49.     uint8_t m, act_type, lcd_action, lcd_size;
  50.     if( ((msg->Id & CLASS_MASK)>> CLASS_MASK_BITS) == CLASS_ACT ){
  51.         act = (msg->Id & TYPE_MASK) >> TYPE_MASK_BITS;
  52.         act_type = (act & ACT_TYPE_MASK) >> ACT_TYPE_BITS;
  53.         lcd_action = (act & LCD_ACTION_MASK) >> LCD_ACTION_BITS;
  54.         lcd_size = (act & LCD_SIZE_MASK) >> LCD_SIZE_BITS;
  55.     }
  56.  
  57.     if( act_type == ACT_TYPE_LCD && (lcd_size == SIZE_LCD || lcd_size == LCD_SIZE_ALL)){
  58.         switch( lcd_action ){
  59.             case LCD_ACTION_CLR:
  60.                     // Clear LCD
  61.                     lcd_clrscr();
  62.                 break;
  63.             case LCD_ACTION_CURS:
  64.                     // Move cursor
  65.                     lcd_gotoxy( msg->Data.bytes[0],msg->Data.bytes[1] );
  66.                 break;
  67.             case LCD_ACTION_GET_SIZE:
  68.                     // Request LCD dimension
  69.                     send_dimensions();
  70.                 break;
  71.             case LCD_ACTION_TEXT:
  72.                 // Print text to LCD
  73.                 for(m=0;m<msg->DataLength;m++){
  74.                     lcd_putc( (char)msg->Data.bytes[m] );
  75.                 }
  76.                 break;
  77.             case LCD_ACTION_SET_CONT:
  78.                 // Set contrast
  79.                 if(msg->DataLength == 1){
  80.                     OCR0B = msg->Data.bytes[0];
  81.                 }
  82.                 break;
  83.             case LCD_ACTION_SET_BLIGHT:
  84.                 // Set backlight
  85.                 if(msg->DataLength == 1){
  86.                     OCR1AL = msg->Data.bytes[0];
  87.                 }
  88.                 break;
  89.             case LCD_ACTION_GET_CONT:
  90.                 // Get contrast
  91.                 txMsg.DataLength = 1;
  92.                 txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_CONT<<LCD_ACTION_BITS )|NODE_ID;
  93.                 txMsg.Data.bytes[0] = OCR0B;
  94.                 bios->can_send(&txMsg);
  95.                 break;
  96.             case LCD_ACTION_GET_BLIGHT:
  97.                 // Get backlight
  98.                 txMsg.DataLength = 1;
  99.                 txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_BLIGHT<<LCD_ACTION_BITS )|NODE_ID;
  100.                 txMsg.Data.bytes[0] = OCR1AL;
  101.                 bios->can_send(&txMsg);
  102.                 break;
  103.             default:
  104.                 // Take over the world
  105.                 break;
  106.         }
  107.     }
  108. }
  109.  
  110.  
  111. ISR( PCINT0_vect ){ // For ROTENC_A and ROTENC_B
  112.     uint8_t rot_data = 0;
  113.  
  114.     txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x01<<SNS_ID_BITS )| NODE_ID;
  115.     txMsg.DataLength=2;
  116.  
  117.     if(PINB&(1<<PB7)){
  118.         rot_data |= 0x01;
  119.     }
  120.     if(PINB&(1<<PB0)){
  121.         rot_data |= 0x02;
  122.     }
  123.  
  124.     if( rot_data==0 || rot_data==3 ){
  125.         if( rot_data==0 && rot_laststate!=rot_data ){
  126.             if( rot_lastdir&0x01 ){
  127.                 // Moving right
  128.                 txMsg.Data.bytes[0]=RIGHT;
  129.                 txMsg.Data.bytes[1] = (PIND&(1<<PD2))?0:1;
  130.                 bios->can_send(&txMsg);
  131.                 // For testing TODO remove
  132.                 if(OCR1A<0xFF){
  133.                     OCR1A++;
  134.                 }
  135.             }else{
  136.                 // Moving left
  137.                 txMsg.Data.bytes[0]=LEFT;
  138.                 txMsg.Data.bytes[1] = (PIND&(1<<PD2))?0:1;
  139.                 bios->can_send(&txMsg);
  140.                 // For testing TODO remove
  141.                 if(OCR1A>0){
  142.                     OCR1A--;
  143.                 }
  144.             }
  145.         }
  146.         rot_laststate = rot_data;
  147.     }else{
  148.         rot_lastdir = rot_data;
  149.     }
  150. }
  151.  
  152. ISR( PCINT2_vect ){ // For ROTENC_BTN
  153.     txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x02<<SNS_ID_BITS )| NODE_ID;
  154.     txMsg.Data.bytes[0] = (PIND&(1<<PD2))?0:1; // Check if buton is pressed or not
  155.     txMsg.DataLength=1;
  156.     bios->can_send(&txMsg);
  157. }
  158.  
  159.  
  160. /*-----------------------------------------------------------------------------
  161.  * Main Program
  162.  *---------------------------------------------------------------------------*/
  163. int main(void) {
  164.  
  165.     /*
  166.      * Initialize rotaryencoders and buttons
  167.      */
  168.     /* Set as input */
  169.     DDRD &= ~(1<<DDD2);
  170.     DDRB &= ~((1<<DDB7)|(1<<DDB0));
  171.     /* Enable pull-up */
  172.     PORTD |= (1<<PD2);
  173.     PORTB |= (1<<PB7)|(1<<PB0);
  174.     /* Enable IO-pin interrupt */
  175.     PCICR |= (1<<PCIE2)|(1<<PCIE0);
  176.     /* Unmask PB7, PB0 and PD2 */
  177.     PCMSK2 |= (1<<PCINT18);
  178.     PCMSK0 |= (1<<PCINT7)|(1<<PCINT0);
  179.  
  180.     /* Contrast */
  181.     TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
  182.     TCCR0B |= (1<<CS00);
  183.     OCR0B = 0x20;
  184.     DDRD |= (1<<DDD5);
  185.  
  186.     /* Backlight */
  187.     TCCR1A |= (1<<COM1A1)|(1<<WGM11);
  188.     TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
  189.     ICR1 = 0xFF; // Make it 8 bits
  190.     OCR1A = 0x20;
  191.     DDRB |= (1<<DDB1);
  192.  
  193.  
  194.     txMsg.ExtendedFlag=1;
  195.     txMsg.RemoteFlag=0;
  196.  
  197.     sei();
  198.     bios->can_callback = &can_receive;
  199.  
  200.     lcd_init( LCD_DISP_ON );
  201.     lcd_clrscr();
  202.     lcd_puts("HomeAutomation\n");
  203.  
  204.     send_dimensions();
  205.     lcd_puts("Very nice!\n");
  206.  
  207.     /* main loop */
  208.     while(1){
  209.         /* check if any messages have been received */
  210.         if(msg_received){
  211.  
  212.             msg_received = FALSE;
  213.         }
  214.     }
  215. }
  216.  
  217. void send_dimensions(){
  218.     txMsg.Id=0xA000001;
  219.     txMsg.Data.bytes[0] = SIZE_X;
  220.     txMsg.Data.bytes[1] = SIZE_Y;
  221.     txMsg.DataLength = 2;
  222.     bios->can_send(&txMsg);
  223. }
  224.