Subversion Repositories HomeAutomation

Rev

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

  1. /**
  2.  * CanSensors.
  3.  *
  4.  *
  5.  * @date    2007-10-08
  6.  * @author  Martin Norden
  7.  *
  8.  * TODO: everything, this is release 0.00001. Use /timer.h to read RPM and injectors!
  9.  */
  10.  
  11. #include <inttypes.h>
  12. #include <avr/interrupt.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <config.h> // All configuration parameters
  16. #include <bios.h>   // BIOS interface declarations, including CAN structure and ID defines.
  17. #include <drivers/uart/serial.h>
  18. #include <drivers/timer/timer.h>
  19.  
  20. #define APP_TYPE    0xf001
  21. #define APP_VERSION 0x0002
  22.  
  23. // A simple message "queue", with space for one message only.
  24. // These are declared volatile to tell the compiler not to optimize away accesses.
  25. volatile Can_Message_t rxMsg; // Message storage
  26. volatile uint8_t rxMsgFull;   // Synchronization flag
  27.  
  28. // CAN message reception callback.
  29. // This function runs with interrupts disabled, keep it as short as possible.
  30. void can_receive(Can_Message_t *msg) {
  31.     if (!rxMsgFull) {
  32.         memcpy((void*)&rxMsg, msg, sizeof(rxMsg));
  33.         rxMsgFull = 1;
  34.     }
  35. }
  36.  
  37. uint16_t readvaluez(void);
  38. uint16_t ADValue;
  39. uint8_t activatedSensor;
  40.  
  41. void readSensor(uint8_t sensortoRead, uint8_t transition);
  42. void setADChannel(uint8_t adcchannel);
  43.  
  44. #define LOCSENSOR_BOOST     0x00
  45. #define LOCSENSOR_VOLTAGE   0x01
  46.  
  47. int main(void)
  48. {
  49.     // Enable interrupts as early as possible
  50.     sei();
  51.    
  52.     Timer_Init();
  53.     Serial_Init();
  54.    
  55.  
  56.    
  57.    
  58.     Can_Message_t txMsg;
  59.     txMsg.Id = (CAN_NMT_APP_START << CAN_SHIFT_NMT_TYPE) | (NODE_ID << CAN_SHIFT_NMT_SID);
  60.     txMsg.DataLength = 2;
  61.     txMsg.RemoteFlag = 0;
  62.     txMsg.ExtendedFlag = 1;
  63.     txMsg.Data.words[0] = APP_TYPE;
  64.     txMsg.Data.words[1] = APP_VERSION;
  65.    
  66.     // Set up callback for CAN reception, this is optional if only sending is required.
  67.     BIOS_CanCallback = &can_receive;
  68.     // Send CAN_NMT_APP_START
  69.     BIOS_CanSend(&txMsg);
  70.  
  71.     /* Enable AVcc as Voltage Reference */
  72.     ADMUX |= (1<<REFS0);
  73.     ADMUX &= ~(1<<REFS1);
  74.  
  75.     /* Right adjust the result */
  76.     ADMUX &= ~(1<<ADLAR);
  77.  
  78.     /* Wake up ADC and enable it */
  79.     PRR &= ~(1<<PRADC);
  80.     ADCSRA |= (1<<ADEN);
  81.    
  82.     setADChannel(4);
  83.    
  84.  
  85.     while (1) {
  86.         //Check if one second has passed, in that case: read the next sensor that is not activated
  87.        
  88.         //Read activated sensor and send value to el displayo
  89.         switch (activatedSensor){
  90.         case LOCSENSOR_BOOST:
  91.             ADValue = readvaluez()/8;
  92.             txMsg.Id = ((CAN_SNS << CAN_SHIFT_CLASS) | (SNS_TYPE_PRESSURE << CAN_SHIFT_SNS_TYPE) | (NODE_ID << CAN_SHIFT_SNS_SID));
  93.             txMsg.Id |= (1 << CAN_SHIFT_SNS_ID); /* Set sensor id */
  94.            
  95.             txMsg.Data.bytes[0] = ADValue/255;
  96.             txMsg.Data.bytes[1] = ADValue%255;
  97.            
  98.             BIOS_CanSend(&txMsg);
  99.            
  100.         break;
  101.         }      
  102.        
  103.         if (rxMsgFull) {
  104.             // Ooh! We have a message!
  105.  
  106.             //Message setting active sensor? Let's change the ad-channel!
  107.            
  108.            
  109.             rxMsgFull = 0; //  delete it!
  110.         }
  111.     }
  112.    
  113.     return 0;
  114. }
  115.  
  116. void setADChannel(uint8_t adcchannel){ 
  117.     switch(adcchannel){
  118.     case 0:
  119.         /* Enable ADC0 */
  120.         ADMUX &= ~((1<<MUX0)|(1<<MUX1)|(1<<MUX2)|(1<<MUX3));
  121.     break;
  122.     case 1:
  123.         /* Enable ADC1 */
  124.         ADMUX |= (1<<MUX0);
  125.         ADMUX &= ~((1<<MUX1)|(1<<MUX2)|(1<<MUX3));
  126.     break;
  127.     case 2:
  128.         /* Enable ADC2 */
  129.         ADMUX |= (1<<MUX1);
  130.         ADMUX &= ~((1<<MUX0)|(1<<MUX2)|(1<<MUX3));
  131.     break;
  132.     case 3:
  133.         /* Enable ADC3 */
  134.         ADMUX |= (1<<MUX0)|(1<<MUX1);
  135.         ADMUX &= ~((1<<MUX2)|(1<<MUX3));
  136.     break;
  137.     case 4:
  138.         /* Enable ADC4 */
  139.         ADMUX |= (1<<MUX2);
  140.         ADMUX &= ~((1<<MUX0)|(1<<MUX1)|(1<<MUX3));
  141.     break;
  142.     case 5:
  143.         /* Enable ADC5 */
  144.         ADMUX |= (1<<MUX0)|(1<<MUX2);
  145.         ADMUX &= ~((1<<MUX1)|(1<<MUX3));
  146.     break;
  147.     case 6:
  148.         /* Enable ADC6 */
  149.         ADMUX |= (1<<MUX1)|(1<<MUX2);
  150.         ADMUX &= ~((1<<MUX0)|(1<<MUX3));
  151.     break;
  152.     case 7:
  153.         /* Enable ADC7 (only for TQFP package) */
  154.         ADMUX |= (1<<MUX0)|(1<<MUX1)|(1<<MUX2);
  155.         ADMUX &= ~(1<<MUX3);
  156.     break;
  157.     }  
  158.     /* Make the first conversion (takes 25 ADC clock cycles) and throw away */
  159.     readvaluez();
  160. }
  161.  
  162. uint16_t readvaluez(void)
  163. {
  164.     /* Start measurement (takes 13 ADC clock cycles) */
  165.     ADCSRA |= (1<<ADSC);
  166.  
  167.     while( ADCSRA & (1<<ADSC) ){ /* Wait for conversion to complete */ }
  168.  
  169.     /* Get the result, return */
  170.     return ADCW;
  171. }
  172.  
  173.