Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * CanSimpleCLCD. Simple version.
  3.  * For HD44780- and KS0073-based LCD displays
  4.  *
  5.  * Contains no intelligence. It just prints what it is told to.
  6.  *
  7.  * @date    2006-12-11
  8.  * @author  Erik Larsson
  9.  * @author  Martin Norden
  10.  *
  11.  */
  12.  
  13. /*-----------------------------------------------------------------------------
  14.  * Includes
  15.  *---------------------------------------------------------------------------*/
  16. /* system files */
  17. #include <avr/io.h>
  18. #include <inttypes.h>
  19. #include <avr/interrupt.h>
  20. #include <stdio.h>
  21. /* lib files */
  22. #include <bios.h>
  23. #include <config.h>
  24. #include <drivers/lcd/clcd/lcd_HD44780.h>
  25.  
  26. #include <string.h> //for memcpy
  27.  
  28.  
  29. /* funcdefs */
  30. //#include <funcdefs/funcdefs.h>
  31.  
  32.  
  33. //a lot of crap from previous funcdefs
  34. /* ACT LCD 12 bits <ACTION><SIZE> 0xFFFL
  35.  *
  36.  * <ACTION>, 4 bits = Type och action.
  37.  * <SIZE>, 8 bits = Size of display.
  38.  */
  39. #define LCD_ACTION_MASK 0xF00L /* bit[12..8] */
  40. #define LCD_SIZE_MASK 0x0FFL /* bit[7..0] */
  41.  
  42. #define LCD_ACTION_BITS 8
  43. #define LCD_SIZE_BITS 0
  44.  
  45.  
  46. /* <ACTION> 4 bits 0xFL */
  47.  
  48. #define LCD_ACTION_CLR          0x0L
  49. #define LCD_ACTION_CURS         0x1L
  50. #define LCD_ACTION_TEXT         0x2L
  51. #define LCD_ACTION_GET_SIZE     0x3L
  52. #define LCD_ACTION_SET_CONT     0x4L
  53. #define LCD_ACTION_SET_BLIGHT   0x5L
  54. #define LCD_ACTION_GET_CONT     0x6L
  55. #define LCD_ACTION_GET_BLIGHT   0x7L
  56.  
  57. #define LCD_ACTION_SEND_CONT    0x8L
  58. #define LCD_ACTION_SEND_BLIGHT  0x9L
  59.  
  60.  
  61.  
  62. /* <SIZE> 8 bits 0xFFL */
  63. #define LCD_SIZE_ALL    0x00L
  64. #define LCD_SIZE_16x2   0x02L
  65. #define LCD_SIZE_20x4   0x10L
  66.  
  67.  
  68.  
  69. /*-----------------------------------------------------------------------------
  70.  * Defines
  71.  *---------------------------------------------------------------------------*/
  72. #define SIZE_X  20
  73. #define SIZE_Y  4
  74. #define SIZE_LCD LCD_SIZE_20x4
  75.  
  76. #define BUFFER_SIZE SIZE_X
  77. #define TRUE 1
  78. #define FALSE 0
  79.  
  80. #define LEFT    0x01
  81. #define RIGHT   0x02
  82.  
  83. volatile Can_Message_t rxMsg;
  84.  
  85. char incoming_text[ BUFFER_SIZE ];
  86. uint8_t rxMsgFull;
  87.  
  88.  
  89. char buffer[ BUFFER_SIZE ];
  90.  
  91. void send_dimensions(void);
  92. void rotenc(void);
  93.  
  94. // CAN message reception callback
  95. // This function runs with interrupts disabled, keep it as short as possible
  96. void can_receive(Can_Message_t *msg){
  97.     if(!rxMsgFull){
  98.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  99.         rxMsgFull = 1;
  100.     }
  101. }
  102.  
  103. ISR( PCINT2_vect ){
  104. // For ROTENC_A and ROTENC_B FIXME Šr inte riktigt rŠtt. Verkar vara bra tycker jag?
  105.     rotenc();
  106. }
  107.  
  108. ISR( PCINT0_vect ){
  109. // For ROTENC_BTN
  110.     rotenc();
  111. }
  112.  
  113. /*-----------------------------------------------------------------------------
  114.  * Main Program
  115.  *---------------------------------------------------------------------------*/
  116. int main(void) {
  117. //  uint32_t act; not used anymoer
  118. //  uint8_t act_type, lcd_size; not used anymore
  119.     uint8_t m, lcd_action;
  120.  
  121.     sei();
  122.  
  123.     /*
  124.      * Initialize rotaryencoders and buttons
  125.      */
  126.     // Set as input
  127.     DDRD &= ~(1<<DDD2);
  128.     DDRB &= ~((1<<DDB7)|(1<<DDB0));
  129.     // Enable pull-up
  130.     PORTD |= (1<<PD2);
  131.     PORTB |= (1<<PB7)|(1<<PB0);
  132.     // Enable IO-pin interrupt
  133.     PCICR |= (1<<PCIE2)|(1<<PCIE0);
  134.     // Unmask PB7, PB0 and PD2
  135.     PCMSK2 |= (1<<PCINT18);
  136.     PCMSK0 |= (1<<PCINT7)|(1<<PCINT0);
  137.  
  138.     // Contrast
  139.     TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
  140.     TCCR0B |= (1<<CS00);
  141.     OCR0B = 0x10;
  142.     DDRD |= (1<<DDD5);
  143.  
  144.     // Backlight
  145.     TCCR1A |= (1<<COM1A1)|(1<<WGM11);
  146.     TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
  147.     ICR1 = 0xFF; // Make it 8 bits
  148.     OCR1A = 0xFF;
  149.     DDRB |= (1<<DDB1);
  150.  
  151.  
  152.     Can_Message_t txMsg;
  153.     txMsg.ExtendedFlag=1;
  154.     txMsg.RemoteFlag=0;
  155. // FIXME skicka app startad
  156.     BIOS_CanCallback = &can_receive;
  157.  
  158.     lcd_init( LCD_DISP_ON );
  159.     lcd_clrscr();
  160.     lcd_puts("HomeAutomation\n");
  161.  
  162.     send_dimensions();
  163.     lcd_puts("CAN Connected!\n");
  164.  
  165.     /* main loop */
  166.     while(1){
  167.         /* check if any messages have been received */
  168.         if(rxMsgFull){
  169.             uint16_t act_type;
  170.             uint8_t lcdid;
  171.             if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){// FIXME ett jŠkla herk, stŠda upp
  172.                
  173.                
  174.                 act_type =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
  175.            
  176.                 lcdid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
  177.                
  178.  
  179.                 if( act_type == ACT_TYPE_LCD ){ //FIXME add id to check here
  180.                     lcd_action =  rxMsg.Data.bytes[0];
  181.                     switch( lcd_action ){
  182.                     case LCD_ACTION_CLR:
  183.                         // Clear LCD
  184.                         lcd_clrscr();
  185.                     break;
  186.                     case LCD_ACTION_CURS:
  187.                         // Move cursor
  188.                         lcd_gotoxy( rxMsg.Data.bytes[1],rxMsg.Data.bytes[2] );
  189.                     break;
  190.                     case LCD_ACTION_GET_SIZE:
  191.                         // Request LCD dimension
  192.                         send_dimensions();
  193.                     break;
  194.                     case LCD_ACTION_TEXT:
  195.                         // Print text to LCD
  196.                         for(m=1;m<rxMsg.DataLength;m++){
  197.                             lcd_putc( (char)rxMsg.Data.bytes[m] );
  198.                         }
  199.                     break;
  200.                     case LCD_ACTION_SET_CONT:
  201.                         // Set contrast
  202.                         if(rxMsg.DataLength == 1){
  203.                             OCR0B = rxMsg.Data.bytes[1];
  204.                         }
  205.                     break;
  206.                     case LCD_ACTION_SET_BLIGHT:
  207.                         // Set backlight
  208.                         if(rxMsg.DataLength == 2){
  209.                             OCR1AL = rxMsg.Data.bytes[1];
  210.                         }
  211.                     break;
  212.                     case LCD_ACTION_GET_CONT:
  213.                         // Get contrast
  214.                         txMsg.DataLength = 1;
  215.                         //txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_CONT<<LCD_ACTION_BITS )|NODE_ID; FIXME
  216.                         txMsg.Data.bytes[1] = OCR0B;
  217.                         BIOS_CanSend(&txMsg);
  218.                     break;
  219.                     case LCD_ACTION_GET_BLIGHT:
  220.                         // Get backlight
  221.                         txMsg.DataLength = 1;
  222.                         //txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_BLIGHT<<LCD_ACTION_BITS )|NODE_ID; FIXME
  223.                         txMsg.Data.bytes[1] = OCR1AL;
  224.                         BIOS_CanSend(&txMsg);
  225.                     break;
  226.                     default:
  227.                     // Take over the world
  228.                     break;
  229.                     }
  230.                 }
  231.             }
  232.             rxMsgFull = 0;
  233.         }
  234.     }
  235. }
  236.  
  237. void send_dimensions(){
  238.     Can_Message_t txMsg;
  239.  
  240.     txMsg.ExtendedFlag=1;
  241.     txMsg.RemoteFlag=0;
  242.     txMsg.Id=0xA000001;
  243.     txMsg.Data.bytes[0] = SIZE_X;
  244.     txMsg.Data.bytes[1] = SIZE_Y;
  245.     txMsg.DataLength = 2;
  246.  
  247.     BIOS_CanSend(&txMsg);
  248. }
  249.  
  250. void rotenc(){
  251.     uint8_t rot_data = 0;
  252.     static uint8_t rot_lastdir = 0, rot_laststate = 0, btn_laststate = 0;
  253.  
  254.     Can_Message_t txMsg;
  255.     txMsg.ExtendedFlag=1;
  256.     txMsg.RemoteFlag=0;
  257.     //txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x01<<SNS_ID_BITS )| NODE_ID;//FIXME: borttaget
  258.     txMsg.DataLength=2;
  259.  
  260.     //Take care of button push
  261.     if ((PINB&(1<<PB7)) != btn_laststate){ //The buttonstate has changed! Let's send a message!
  262.         btn_laststate = (PINB&(1<<PB7));
  263.         txMsg.Data.bytes[0] = 5;
  264.         txMsg.Data.bytes[1] = (btn_laststate)?0:1;
  265.         txMsg.DataLength=2;
  266.         BIOS_CanSend(&txMsg);
  267.     }
  268.    
  269.     //Take care of rotary encoder movement
  270.     if(PINB&(1<<PB0)){
  271.         rot_data |= 0x01;
  272.     }
  273.     if(PIND&(1<<PD2)){
  274.         rot_data |= 0x02;
  275.     }
  276.  
  277.     if( rot_data==0 || rot_data==3 ){ // Are both signals high or low?
  278.         if( rot_data==0 && rot_laststate!=rot_data ){ // Are both signals low? In that case we are finished with one turn and should print out the direction it went.
  279.             if( rot_lastdir&0x01 ){
  280.                 // Moving right
  281.                 txMsg.Data.bytes[0]=RIGHT;
  282.                 txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
  283.                 txMsg.DataLength=2;
  284.                 BIOS_CanSend(&txMsg);
  285.             }else{
  286.                 // Moving left
  287.                 txMsg.Data.bytes[0]=LEFT;
  288.                 txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
  289.                 txMsg.DataLength=2;
  290.                 BIOS_CanSend(&txMsg);
  291.             }
  292.         }
  293.         rot_laststate = rot_data;
  294.     } else { // No, only one of the signals are high. We can use this to find out what direction we are moving.
  295.         rot_lastdir = rot_data;
  296.     }
  297. }
  298.  
  299.