Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * Antenna Display.
  3.  * For controlling of the cAntenna bus using one
  4.  * HD44780 LCD display and som buttons.
  5.  *
  6.  *
  7.  *
  8.  * @date    2007-11-19
  9.  * @author  Erik Larsson
  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. #include <stdlib.h>
  22.  
  23. /* lib files */
  24. #include <bios.h>
  25. #include <config.h>
  26. #include <drivers/timer/timer.h>
  27. #include <drivers/lcd/clcd/lcd_HD44780.h>
  28.  
  29. #include <string.h> //for memcpy
  30.  
  31. /*-----------------------------------------------------------------------------
  32.  * Defines
  33.  *---------------------------------------------------------------------------*/
  34. #define SIZE_X  16
  35. #define SIZE_Y  2
  36.  
  37. #define BUFFER_SIZE SIZE_X
  38.  
  39. #define STOP 0
  40. #define AZIMUTH 1
  41. #define ELEVATION 2
  42. #define SCREEN_NORMAL 3
  43. #define SCREEN_CAL 4
  44.  
  45. #define NORMAL_MODE 0x01
  46. #define CAL_MODE 0x02
  47.  
  48. #define AZIMUTH_PLUS 0x05
  49. #define AZIMUTH_MINUS 0x06
  50. #define ELEVATION_PLUS 0x07
  51. #define ELEVATION_MINUS 0x08
  52. #define AZIMUTH_STOP 0x09
  53. #define ELEVATION_STOP 0x0a
  54. #define GET_CAL 0x0b
  55. #define SET_CAL 0x0c
  56.  
  57.  
  58. #define APP_TYPE    0x1234
  59. #define APP_VERSION 0x0001
  60.  
  61. volatile Can_Message_t rxMsg;
  62.  
  63. //char incoming_text[ BUFFER_SIZE ];
  64. uint8_t rxMsgFull=0;
  65.  
  66. uint8_t mode = NORMAL_MODE;
  67.  
  68. // Buttons
  69. uint8_t azimuth_plus = 0, azimuth_minus = 0;
  70. uint8_t elevation_plus = 0, elevation_minus = 0;
  71. uint8_t calibration = 0;
  72.  
  73.  
  74. //void send_dimensions(void);
  75. //void rotenc(void);
  76.  
  77. //void button(void);
  78.  
  79. void IO_init( void );
  80.  
  81. void print_screen( uint8_t type, uint16_t data );
  82.  
  83. void send_message( uint8_t type, uint16_t data );
  84.  
  85. void calibrate( void );
  86.  
  87. // CAN message reception callback
  88. // This function runs with interrupts disabled, keep it as short as possible
  89. void can_receive(Can_Message_t *msg){
  90.     if(!rxMsgFull){
  91.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  92.         rxMsgFull = 1;
  93.     }
  94. }
  95.  
  96. void read_buttons(uint8_t timer) {
  97.     // Periodicly read buttons
  98.     // Read buttons
  99.         calibration = (PIND & (1<<PD2))?0:1;
  100.         azimuth_plus = (PINB & (1<<PB0))?0:1;
  101.         azimuth_minus = (PINB & (1<<PB7))?0:1;
  102.     elevation_plus = (PINC & (1<<PC1))?0:1;
  103.     elevation_minus = (PINC & (1<<PC0))?0:1;
  104. }
  105.  
  106.  
  107. /*-----------------------------------------------------------------------------
  108.  * Main Program
  109.  *---------------------------------------------------------------------------*/
  110. int main( void ) {
  111.     uint8_t autostop = 0;
  112.  
  113.     sei();
  114.    
  115.     Timer_Init();
  116.  
  117.     IO_init();
  118.  
  119.     Can_Message_t txMsg;
  120.    
  121.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  122.     txMsg.ExtendedFlag=1;
  123.     txMsg.RemoteFlag=0;
  124.     txMsg.DataLength = 4;
  125.    
  126.     txMsg.Data.words[0] = APP_TYPE;
  127.     txMsg.Data.words[1] = APP_VERSION;
  128.    
  129.     // Send startup message
  130.     BIOS_CanSend(&txMsg);
  131.    
  132.     BIOS_CanCallback = &can_receive;
  133.  
  134.     lcd_init( LCD_DISP_ON );
  135.  
  136.         print_screen( SCREEN_NORMAL, 0 );
  137.    
  138.     // Timer for reading buttons
  139.     Timer_SetTimeout(0, 50, TimerTypeFreeRunning, &read_buttons);
  140.     Timer_SetTimeout(1, 500, TimerTypeFreeRunning, 0);
  141.    
  142.     /* main loop */
  143.     while(1){
  144.        
  145.         /* check if any messages have been received */
  146.         if( rxMsgFull ){
  147.  
  148.             if( rxMsg.Id == 0x1f8f0100 ){
  149.                 print_screen( AZIMUTH, rxMsg.Data.words[0] );
  150.             }else if( rxMsg.Id == 0x1f8f0200 ){
  151.                 print_screen( ELEVATION, rxMsg.Data.words[0] );
  152.             }
  153.            
  154.             rxMsgFull = 0;
  155.         }
  156.          
  157.         if (Timer_Expired(1)) {
  158.  
  159.             // Perhaps someone pressed a button
  160.             if( calibration || azimuth_plus || azimuth_minus || elevation_plus || elevation_minus ){
  161.                 if( calibration ){
  162.                     // send all stop
  163.                     send_message( AZIMUTH_STOP, 0);
  164.                     send_message( ELEVATION_STOP, 0);
  165.  
  166.                     // Start calibration
  167.                     calibrate();
  168.  
  169.                 }else{
  170.                     if( azimuth_plus ){
  171.                         //send rotate aximuth plus
  172.                         send_message( AZIMUTH_PLUS, 0 );
  173.                     }else if( azimuth_minus ){
  174.                         //send rotate azimuth minus
  175.                         send_message( AZIMUTH_MINUS, 0 );
  176.                     }else{
  177.                         // send azimuth stop
  178.                         send_message( AZIMUTH_STOP, 0 );
  179.                     }
  180.    
  181.                     if( elevation_plus ){
  182.                         //send elevate plus
  183.                         send_message( ELEVATION_PLUS, 0 );
  184.                     }else if( elevation_minus ){
  185.                         //send elevate minus
  186.                         send_message( ELEVATION_MINUS, 0 );
  187.                     }else{
  188.                         //send elevation stop
  189.                         send_message( ELEVATION_STOP, 0 );
  190.                     }
  191.  
  192.                     autostop = 1; // Stop all rotors when no button is pressed
  193.                 }
  194.  
  195.             }else if ( autostop ){
  196.                 // send all stop
  197.                 send_message( AZIMUTH_STOP, 0);
  198.                 send_message( ELEVATION_STOP, 0);
  199.  
  200.                 autostop = 0;
  201.             }
  202.         }
  203.     }
  204. }
  205.  
  206. void send_message( uint8_t type, uint16_t data ){
  207.     Can_Message_t txMsg;
  208.  
  209.     txMsg.ExtendedFlag=1;
  210.     txMsg.RemoteFlag=0;
  211.  
  212.     switch(type){
  213.    
  214.     case AZIMUTH_PLUS:
  215.         txMsg.Id = 0x11100005UL;
  216.         txMsg.Data.bytes[0] = 0x01;
  217.         txMsg.DataLength = 1;
  218.         break;
  219.    
  220.     case AZIMUTH_MINUS:
  221.         txMsg.Id = 0x11100005UL;
  222.         txMsg.Data.bytes[0] = 0x02;
  223.         txMsg.DataLength = 1;
  224.         break;
  225.    
  226.     case AZIMUTH_STOP:
  227.         txMsg.Id = 0x11100005UL;
  228.         txMsg.Data.bytes[0] = 0x00;
  229.         txMsg.DataLength = 1;
  230.         break;
  231.    
  232.     case ELEVATION_PLUS:
  233.         txMsg.Id = 0x11100015UL;
  234.         txMsg.Data.bytes[0] = 0x01;
  235.         txMsg.DataLength = 1;
  236.         break;
  237.    
  238.     case ELEVATION_MINUS:
  239.         txMsg.Id = 0x111000015UL;
  240.         txMsg.Data.bytes[0] = 0x02;
  241.         txMsg.DataLength = 1;
  242.         break;
  243.    
  244.     case ELEVATION_STOP:
  245.         txMsg.Id = 0x11100015UL;
  246.         txMsg.Data.bytes[0] = 0x00;
  247.         txMsg.DataLength = 1;
  248.         break;
  249.        
  250.     case GET_CAL:
  251.         txMsg.Id = 0x11100002UL; // MSG_CAL_GET
  252.         txMsg.DataLength = 0;
  253.         break;
  254.        
  255.     case SET_CAL:
  256.         txMsg.Id = 0x11100001UL; // MSG_CAL_SET
  257.         txMsg.DataLength = 2;
  258.         txMsg.Data.words[0] = data;
  259.         break;
  260.        
  261.     default:
  262.         // Stop rotating
  263.         txMsg.Id = 0x11100005UL;
  264.         txMsg.Data.bytes[0] = 0x00;
  265.         txMsg.DataLength = 1;
  266.         break;
  267.     }
  268.  
  269.     BIOS_CanSend(&txMsg);
  270. }
  271.  
  272. void print_screen(uint8_t type, uint16_t data){
  273.     char buffer[ BUFFER_SIZE ];
  274.  
  275.     if( SCREEN_NORMAL == type){ // rotation
  276.         lcd_clrscr();
  277.         lcd_puts("Azimuth     ---*\n");
  278.         lcd_puts("Elevation   ---*\n");
  279.  
  280.     }else if( SCREEN_CAL == type){ // calibration
  281.     lcd_clrscr();
  282.         lcd_puts("Cal Azimuth ---*\n");
  283.         lcd_puts("Cal Elevat. ---*\n");
  284.  
  285.     }else if( AZIMUTH == type ){ // azimuth position
  286.         lcd_gotoxy(12,0);
  287.         lcd_puts("   *");
  288.         lcd_gotoxy(12,0);
  289.  
  290.     /*  if( data&0x8000 ){ //Negative position, -360 - 0
  291.             //
  292.             lcd_gotoxy(0,1);
  293.             lcd_puts("     ");
  294.             lcd_gotoxy(0,1);
  295.             snprintf(buffer, BUFFER_SIZE, "%i", data);
  296.             lcd_puts(buffer);
  297.             //
  298.             lcd_gotoxy(12,0);
  299.             lcd_puts("-");
  300.             data = -data;
  301.             snprintf(buffer, BUFFER_SIZE-1, "%i", data);
  302.             lcd_puts(buffer);
  303.         }else{*/ //Positive position, 0 - 360
  304.             snprintf(buffer, BUFFER_SIZE, "%i", data);
  305.                 lcd_puts(buffer);
  306.         //}
  307.  
  308.     }else if( ELEVATION == type ){ // elevation position
  309.         lcd_gotoxy(12,1);
  310.         lcd_puts("   *");
  311.         lcd_gotoxy(12,1);
  312.  
  313.         if( data&0x80 ){ //Negative position, -360 - 0
  314.             lcd_puts("-");
  315.             data = -data;
  316.             snprintf(buffer, BUFFER_SIZE-1, "%i", data);
  317.                 lcd_puts(buffer);
  318.         }else{ //Positive position, 0 - 360
  319.             snprintf(buffer, BUFFER_SIZE, "%i", data);
  320.                 lcd_puts(buffer);
  321.         }
  322.     }
  323. }
  324.  
  325. void IO_init( void )
  326. {
  327.     /*
  328.      * Enable buttons and display light
  329.      */
  330.  
  331.     // Set as inputs
  332.     DDRD &= ~( 1<<DDD2 ); // Calibration
  333.     DDRB &= ~(( 1<<DDB0 )|( 1<<DDB7 )); // Azimuth
  334.     DDRC &= ~(( 1<<DDC0 )|( 1<<DDC1 )); // Elevation
  335.  
  336.     // Enable pull up
  337.     PORTD |= ( 1<<PD2 );
  338.     PORTB |= ( 1<<PB0 )|( 1<<PB7 );
  339.     PORTC |= ( 1<<PC0 )|( 1<<PC1 );
  340.  
  341.     // Contrast
  342.     TCCR0A |= (1<<COM0B1)|(1<<WGM01)|(1<<WGM00);
  343.     TCCR0B |= (1<<CS00);
  344.     OCR0B = 0x02;
  345.     DDRD |= (1<<DDD5);
  346.  
  347.     // Backlight
  348.     TCCR1A |= (1<<COM1A1)|(1<<WGM11);
  349.     TCCR1B |= (1<<WGM13)|(1<<WGM12)|(1<<CS10);
  350.     ICR1 = 0xFF; // Make it 8 bits
  351.     OCR1A = 0xC0;
  352.     DDRB |= (1<<DDB1);
  353. }
  354.  
  355.  
  356. void calibrate( void ){
  357.     int16_t calib_value_az = 0, calib_value_elv = 0;
  358.    
  359.     // flags
  360.     uint8_t received_cal = 0, calibration_mode = 0;
  361.    
  362.     print_screen( SCREEN_CAL, 0 );
  363.    
  364.     send_message( GET_CAL, 0 );
  365.    
  366.     while ( 1 ) {
  367.    
  368.             /* check if any messages have been received */
  369.         if( rxMsgFull ){
  370.             if( rxMsg.Id == 0x111000f2 && rxMsg.DataLength == 2 ){ // MSG_CAL_RET
  371.                 calib_value_az = rxMsg.Data.words[0];
  372.                
  373.                 received_cal = 1;
  374.                 print_screen( AZIMUTH, calib_value_az );
  375.             }
  376.                
  377.             rxMsgFull = 0;
  378.         }
  379.    
  380.         if ( Timer_Expired(1) && received_cal ) {
  381.             if ( !calibration ){// wait for released button
  382.                 calibration_mode = 1;
  383.                
  384.                 if(azimuth_plus){
  385.                     calib_value_az++;
  386.                     print_screen( AZIMUTH, calib_value_az );               
  387.  
  388.                 }else if(azimuth_minus){
  389.                     calib_value_az--;
  390.                     print_screen( AZIMUTH, calib_value_az );
  391.                 }
  392.    
  393.                 if(elevation_plus){
  394.                     calib_value_elv++;
  395.                
  396.                 }else if(elevation_minus){
  397.                     calib_value_elv--;
  398.                 }  
  399.  
  400.             }else if( calibration && calibration_mode ){
  401.                 // Send calibration value to antenna node
  402.                 send_message( SET_CAL, calib_value_az );
  403.                 // return to normal state
  404.                 print_screen( SCREEN_NORMAL, 0 );
  405.                
  406.                 return;
  407.             }
  408.         }
  409.     }
  410. }
  411.