Subversion Repositories HomeAutomation

Rev

Rev 1044 | 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  2
  74. #define SIZE_LCD LCD_SIZE_20x2
  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. #if 0
  124.     /*
  125.      * Initialize rotaryencoders and buttons
  126.      */
  127.     // Set as input
  128.     DDRD &= ~(1<<DDD2);
  129.     DDRB &= ~((1<<DDB7)|(1<<DDB0));
  130.     // Enable pull-up
  131.     PORTD |= (1<<PD2);
  132.     PORTB |= (1<<PB7)|(1<<PB0);
  133.     // Enable IO-pin interrupt
  134.     PCICR |= (1<<PCIE2)|(1<<PCIE0);
  135.     // Unmask PB7, PB0 and PD2
  136.     PCMSK2 |= (1<<PCINT18);
  137.     PCMSK0 |= (1<<PCINT7)|(1<<PCINT0);
  138. #endif
  139.    
  140.     // Contrast
  141.     TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
  142.     TCCR0B |= (1<<CS00);
  143.     OCR0B = 0xf0;
  144.     DDRD |= (1<<DDD5);
  145.  
  146. #if 0
  147.     // Backlight
  148.     TCCR1A |= (1<<COM1A1)|(1<<WGM11);
  149.     TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
  150.     ICR1 = 0xFF; // Make it 8 bits
  151.     OCR1A = 0xFF;
  152.     DDRB |= (1<<DDB1);
  153. #endif
  154.  
  155.     Can_Message_t txMsg;
  156.     txMsg.ExtendedFlag=1;
  157.     txMsg.RemoteFlag=0;
  158. // FIXME skicka app startad
  159.     BIOS_CanCallback = &can_receive;
  160.  
  161.     lcd_init( LCD_DISP_ON );
  162.     lcd_clrscr();
  163.     lcd_puts("HomeAutomation\n");
  164.  
  165.     send_dimensions();
  166.     lcd_puts("CAN Connected!\n");
  167.  
  168.     uint8_t cnt=0;
  169.     /* main loop */
  170.     while(1){
  171.         /* check if any messages have been received */
  172.         if(rxMsgFull){
  173.             if (cnt == 0) {
  174.                 lcd_home();
  175.                 lcd_puts(".                   ");
  176.             } else if (cnt == 1) {
  177.                 lcd_home();
  178.                 lcd_puts(" .                  ");
  179.             } else if (cnt == 2) {
  180.                 lcd_home();
  181.                 lcd_puts("  .                 ");
  182.             } else if (cnt == 3) {
  183.                 lcd_home();
  184.                 lcd_puts("   .                ");
  185.             } else if (cnt == 4) {
  186.                 lcd_home();
  187.                 lcd_puts("    .               ");
  188.             } else if (cnt == 5) {
  189.                 lcd_home();
  190.                 lcd_puts("     .              ");
  191.             } else if (cnt == 6) {
  192.                 lcd_home();
  193.                 lcd_puts("      .             ");
  194.             } else if (cnt == 7) {
  195.                 lcd_home();
  196.                 lcd_puts("       .            ");
  197.             } else if (cnt == 8) {
  198.                 lcd_home();
  199.                 lcd_puts("        .           ");
  200.             } else if (cnt == 9) {
  201.                 lcd_home();
  202.                 lcd_puts("         .          ");
  203.             } else if (cnt == 10) {
  204.                 lcd_home();
  205.                 lcd_puts("          .         ");
  206.             } else if (cnt == 11) {
  207.                 lcd_home();
  208.                 lcd_puts("           .        ");
  209.             } else if (cnt == 12) {
  210.                 lcd_home();
  211.                 lcd_puts("            .       ");
  212.             } else if (cnt == 13) {
  213.                 lcd_home();
  214.                 lcd_puts("             .      ");
  215.             } else if (cnt == 14) {
  216.                 lcd_home();
  217.                 lcd_puts("              .     ");
  218.             } else if (cnt == 15) {
  219.                 lcd_home();
  220.                 lcd_puts("               .    ");
  221.             } else if (cnt == 16) {
  222.                 lcd_home();
  223.                 lcd_puts("                .   ");
  224.             } else if (cnt == 17) {
  225.                 lcd_home();
  226.                 lcd_puts("                 .  ");
  227.             } else if (cnt == 18) {
  228.                 lcd_home();
  229.                 lcd_puts("                  . ");
  230.             } else if (cnt == 19) {
  231.                 lcd_home();
  232.                 lcd_puts("                   .");
  233.             }
  234.             cnt += 1;
  235.             if (cnt == 20) {
  236.                 cnt = 0;
  237.             }
  238.            
  239.             uint16_t act_type;
  240.             uint8_t lcdid;
  241.             if ( ((rxMsg.Id & CAN_MASK_CLASS)>>CAN_SHIFT_CLASS) == CAN_ACT){// FIXME ett j�kla herk, st�da upp
  242.                
  243.                
  244.                 act_type =(uint16_t)((rxMsg.Id & CAN_MASK_ACT_TYPE) >> CAN_SHIFT_ACT_TYPE);
  245.            
  246.                 lcdid = (uint8_t)((rxMsg.Id & CAN_MASK_ACT_ID) >> CAN_SHIFT_ACT_ID);
  247.                
  248.  
  249.                 if( act_type == ACT_TYPE_LCD ){ //FIXME add id to check here
  250.                     lcd_action =  rxMsg.Data.bytes[0];
  251.                     switch( lcd_action ){
  252.                     case LCD_ACTION_CLR:
  253.                         // Clear LCD
  254.                         lcd_clrscr();
  255.                     break;
  256.                     case LCD_ACTION_CURS:
  257.                         // Move cursor
  258.                         lcd_gotoxy( rxMsg.Data.bytes[1],rxMsg.Data.bytes[2] );
  259.                     break;
  260.                     case LCD_ACTION_GET_SIZE:
  261.                         // Request LCD dimension
  262.                         send_dimensions();
  263.                     break;
  264.                     case LCD_ACTION_TEXT:
  265.                         // Print text to LCD
  266.                         for(m=1;m<rxMsg.DataLength;m++){
  267.                             lcd_putc( (char)rxMsg.Data.bytes[m] );
  268.                         }
  269.                     break;
  270.                     case LCD_ACTION_SET_CONT:
  271.                         // Set contrast
  272.                         if(rxMsg.DataLength == 1){
  273.                             OCR0B = rxMsg.Data.bytes[1];
  274.                         }
  275.                     break;
  276.                     case LCD_ACTION_SET_BLIGHT:
  277.                         // Set backlight
  278.                         if(rxMsg.DataLength == 2){
  279.                             OCR1AL = rxMsg.Data.bytes[1];
  280.                         }
  281.                     break;
  282.                     case LCD_ACTION_GET_CONT:
  283.                         // Get contrast
  284.                         txMsg.DataLength = 1;
  285.                         //txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_CONT<<LCD_ACTION_BITS )|NODE_ID; FIXME
  286.                         txMsg.Data.bytes[1] = OCR0B;
  287.                         BIOS_CanSend(&txMsg);
  288.                     break;
  289.                     case LCD_ACTION_GET_BLIGHT:
  290.                         // Get backlight
  291.                         txMsg.DataLength = 1;
  292.                         //txMsg.Id = ( CLASS_ACT<<CLASS_MASK_BITS )|( ACT_TYPE_LCD<<ACT_TYPE_BITS )|( LCD_ACTION_SEND_BLIGHT<<LCD_ACTION_BITS )|NODE_ID; FIXME
  293.                         txMsg.Data.bytes[1] = OCR1AL;
  294.                         BIOS_CanSend(&txMsg);
  295.                     break;
  296.                     default:
  297.                     // Take over the world
  298.                     break;
  299.                     }
  300.                 }
  301.             }
  302.             rxMsgFull = 0;
  303.         }
  304.     }
  305. }
  306.  
  307. void send_dimensions(){
  308.     Can_Message_t txMsg;
  309.  
  310.     txMsg.ExtendedFlag=1;
  311.     txMsg.RemoteFlag=0;
  312.     txMsg.Id=0xA000001;
  313.     txMsg.Data.bytes[0] = SIZE_X;
  314.     txMsg.Data.bytes[1] = SIZE_Y;
  315.     txMsg.DataLength = 2;
  316.  
  317.     BIOS_CanSend(&txMsg);
  318. }
  319.  
  320. void rotenc(){
  321.     uint8_t rot_data = 0;
  322.     static uint8_t rot_lastdir = 0, rot_laststate = 0, btn_laststate = 0;
  323.  
  324.     Can_Message_t txMsg;
  325.     txMsg.ExtendedFlag=1;
  326.     txMsg.RemoteFlag=0;
  327.     //txMsg.Id = ( CLASS_SNS<<CLASS_MASK_BITS )|( SNS_ACT_BUTTON<<SNS_TYPE_BITS )|( 0x01<<SNS_ID_BITS )| NODE_ID;//FIXME: borttaget
  328.     txMsg.DataLength=2;
  329.  
  330.     //Take care of button push
  331.     if ((PINB&(1<<PB7)) != btn_laststate){ //The buttonstate has changed! Let's send a message!
  332.         btn_laststate = (PINB&(1<<PB7));
  333.         txMsg.Data.bytes[0] = 5;
  334.         txMsg.Data.bytes[1] = (btn_laststate)?0:1;
  335.         txMsg.DataLength=2;
  336.         BIOS_CanSend(&txMsg);
  337.     }
  338.    
  339.     //Take care of rotary encoder movement
  340.     if(PINB&(1<<PB0)){
  341.         rot_data |= 0x01;
  342.     }
  343.     if(PIND&(1<<PD2)){
  344.         rot_data |= 0x02;
  345.     }
  346.  
  347.     if( rot_data==0 || rot_data==3 ){ // Are both signals high or low?
  348.         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.
  349.             if( rot_lastdir&0x01 ){
  350.                 // Moving right
  351.                 txMsg.Data.bytes[0]=RIGHT;
  352.                 txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
  353.                 txMsg.DataLength=2;
  354.                 BIOS_CanSend(&txMsg);
  355.             }else{
  356.                 // Moving left
  357.                 txMsg.Data.bytes[0]=LEFT;
  358.                 txMsg.Data.bytes[1] = (PINB&(1<<PB7))?0:1;
  359.                 txMsg.DataLength=2;
  360.                 BIOS_CanSend(&txMsg);
  361.             }
  362.         }
  363.         rot_laststate = rot_data;
  364.     } else { // No, only one of the signals are high. We can use this to find out what direction we are moving.
  365.         rot_lastdir = rot_data;
  366.     }
  367. }
  368.  
  369.