Subversion Repositories HomeAutomation

Rev

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

  1. /*********************************************************************
  2.  *
  3.  *                  Main application
  4.  *
  5.  *********************************************************************
  6.  * FileName:        Main.c
  7.  *
  8.  * Author               Date    Comment
  9.  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10.  * Johan Böhlin     21-10-06    Original        (Rev 1.0)
  11.  ********************************************************************/
  12.  
  13. #include <compiler.h>
  14. #include <stackTasks.h>
  15. #include <CANdefs.h>
  16. #include <CAN.h>
  17. #include <Tick.h>
  18.  
  19. #ifdef USE_CAN
  20.     #include <CAN.h>
  21. #endif
  22.  
  23. static CAN_PROTO_MESSAGE cm;
  24. static BYTE ful=0;
  25. static DWORD cnt =0;
  26.  
  27. static void mainInit(void);
  28. static BOOL canGetPacket(void);
  29.  
  30. #define PACKET_TIMEOUT (TICK_SECOND/20)
  31. #define BOOTLOADER_INIT_TIMOUT (TICK_SECOND*5)
  32.  
  33. void main()
  34. {
  35.     static PROGRAM_STATE pgs = pgsWATING_START;
  36.     static TICK t = 0;
  37.     static WORD programmerSid=0;
  38.    
  39.     static BYTE errMsg = ERR_NO_ERROR;
  40.     static PROGRAM_STATE afterAckPgs = pgsWATING_START;
  41.     static DWORD pgmAddress = 0;
  42.     static BYTE bytesReceived = 0;
  43.  
  44.     static BYTE tmp;
  45.  
  46.     // Inits
  47.  
  48.     mainInit();
  49.  
  50.     #ifdef USE_CAN
  51.         canInit();
  52.     #endif
  53.  
  54.  
  55.  
  56.     tickInit();
  57.  
  58.    
  59.  
  60.     for(;;)
  61.     {
  62.         CAN_PROTO_MESSAGE outCm;
  63.         BOOL hasPacket = canGetPacket();
  64.  
  65.         if (hasPacket)
  66.         {
  67.                 tmp=5;
  68.         }
  69.  
  70.         switch(pgs)
  71.         {
  72.             case pgsWATING_START:
  73.                 // Check if there is bootloader start packet
  74.                 if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_INIT && cm.data[RID_INDEX]==MY_ID && cm.nid==MY_NID)
  75.                 {
  76.                     // Has new start packet
  77.                     pgmAddress      = (((DWORD)cm.data[ADDRU_INDEX])<<16)+(((DWORD)cm.data[ADDRH_INDEX])<<8)+((DWORD)cm.data[ADDRL_INDEX]);
  78.                     programmerSid   = cm.sid;
  79.                     t               = tickGet();
  80.                     errMsg          = ERR_NO_ERROR;
  81.                     afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
  82.                     pgs             = pgsSEND_ACK;
  83.                 }
  84.  
  85.                 // TODO TIMEOUT!
  86.                 // tBoot = tickGet();
  87.                 // if ((tickGet()-tBoot)>BOOTLOADER_INIT_TIMOUT) goto userprgm;
  88.             break;         
  89.  
  90.             case pgsSEND_ACK:
  91.                 // send ack
  92.                 outCm.funct             = FUNCT_BOOTLOADER;
  93.                 outCm.funcc             = FUNCC_BOOT_ACK;
  94.                 outCm.nid               = MY_NID;
  95.                 outCm.sid               = MY_ID;
  96.                 outCm.data_length       = 8;
  97.                 outCm.remote_request    = FALSE;
  98.                 outCm.data[ERR_INDEX]   = errMsg;
  99.                 t                       = tickGet();
  100.                 pgs                     = afterAckPgs;
  101.  
  102.                 while(!canSendMessage(outCm,PRIO_HIGH));
  103.             break;
  104.  
  105.  
  106.             case pgsWAIT_FIRST_PGM_PACKET:
  107.                 // wait for first pgm packet.
  108.                 if ((tickGet()-t)>PACKET_TIMEOUT)
  109.                 {
  110.                     // Timeout, resend ack.
  111.                     errMsg          = ERR_NO_ERROR;
  112.                     afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
  113.                     pgs             = pgsSEND_ACK;
  114.                 }
  115.  
  116.                 // If programming packet...
  117.                 if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_PGM && cm.nid==MY_NID && cm.sid==programmerSid)
  118.                 {
  119.                     // Save bytes in memory, setup start adress etc..
  120.                     bytesReceived   = 8;
  121.                     pgs             = pgsWAIT_PGM_PACKET;
  122.                 }
  123.  
  124.  
  125.             break;
  126.  
  127.  
  128.             case pgsWAIT_PGM_PACKET:
  129.        
  130.            
  131.                 // If programming packet...
  132.                 if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_PGM && cm.nid==MY_NID && cm.sid==programmerSid)
  133.                 {
  134.                     // Save bytes in memory, inc received bytes.
  135.                     bytesReceived   += 8;
  136.                     pgs              = pgsWAIT_PGM_PACKET;
  137.                 }
  138.  
  139.                 // If adress packet (control packet)..
  140.                 if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_ADDR && cm.nid==MY_NID && cm.sid==programmerSid)
  141.                 {
  142.                     // Send ack and goto wait first packet.
  143.                     errMsg          = ERR_NO_ERROR;
  144.                     afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
  145.                     pgs             = pgsSEND_ACK;
  146.                 }
  147.                
  148.                 // If end packet...
  149.                 if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_DONE && cm.nid==MY_NID && cm.sid==programmerSid)
  150.                 {
  151.                     // write program.
  152.                     // If no bytes received at all, assume end.
  153.                     // If not 64 bytes received, send error ack and wait for first packet.
  154.                     // If 64, write.
  155.  
  156.                     if (bytesReceived==0)
  157.                     {
  158.                         // No received, done.
  159.                         errMsg          = ERR_NO_ERROR;
  160.                         afterAckPgs     = pgsDONE;
  161.                         pgs             = pgsSEND_ACK;
  162.                     }
  163.                     else if (bytesReceived!=64)
  164.                     {
  165.                         errMsg          = ERR_ERROR;
  166.                         afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
  167.                         pgs             = pgsSEND_ACK;
  168.                     }
  169.                     else
  170.                     {
  171.                         pgs              = pgsWRITE_PROGRAM;
  172.                         afterAckPgs     = pgsDONE;
  173.                     }
  174.                 }
  175.  
  176.                 // If bytes received 64, write..
  177.                 if (bytesReceived==64)
  178.                 {
  179.                     LED0_IO=~LED0_IO;
  180.                     pgs              = pgsWRITE_PROGRAM;
  181.                     afterAckPgs     = pgsWAIT_PGM_PACKET;
  182.                     // TODO! Send ack more than once..
  183.                 }
  184.  
  185.  
  186.             break;
  187.  
  188.  
  189.             case pgsWRITE_PROGRAM:
  190.  
  191.                 // Write program and send ack.
  192.                 pgmAddress     += 64;
  193.                 bytesReceived   = 0;
  194.                 errMsg          = ERR_NO_ERROR;
  195.                 pgs             = pgsSEND_ACK;
  196.  
  197.             break;
  198.  
  199.  
  200.             case pgsDONE:
  201.                 // Goto main program.
  202.                 if ((tickGet()-t)>=TICK_SECOND/4)
  203.                 {
  204.                    
  205.                     LED0_IO=~LED0_IO;
  206.                     t=tickGet();
  207.                 }
  208.             break;
  209.  
  210.        
  211.  
  212.  
  213.             default:
  214.                 pgs = pgsWATING_START;
  215.             break;
  216.         }
  217.    
  218.  
  219.     }
  220. }
  221.  
  222.  
  223. #pragma interruptlow HighISR
  224. void HighISR(void)
  225. {
  226.     tickUpdate();
  227. }
  228. #pragma code highVector=0x08
  229. void HighVector (void)
  230. {
  231.     _asm goto HighISR _endasm
  232. }
  233. #pragma code // Return to default code section
  234.  
  235.  
  236.  
  237. #pragma interruptlow LowISR
  238. void LowISR(void)
  239. {
  240.  
  241. }
  242. #pragma code lowVector=0x18
  243. void LowVector (void)
  244. {
  245.     _asm goto LowISR _endasm
  246. }
  247. #pragma code // Return to default code section
  248.  
  249.  
  250. /*
  251. *   Function: mainInit
  252. *
  253. *   Input:  none
  254. *   Output: none
  255. *   Pre-conditions: none
  256. *   Affects: Se code
  257. *   Depends: none.
  258. */
  259. void mainInit()
  260. {
  261.     LED0_TRIS=0;   
  262.  
  263.     // Enable internal PORTB pull-ups
  264.     INTCON2bits.RBPU = 0;
  265.    
  266.     // Enable Interrupts
  267.     INTCONbits.GIEH = 1;
  268.     INTCONbits.GIEL = 1;
  269.  
  270.     // Enable interrupt prirority
  271.     RCONbits.IPEN=1;
  272.    
  273.  
  274. }
  275.  
  276.  
  277.  
  278. /// CAN-------------------------------------------------------
  279.  
  280.  
  281. #ifdef USE_CAN
  282.  
  283.  
  284. /*
  285. *   Function: canInit
  286. *
  287. *   Input:  none
  288. *   Output: none
  289. *   Pre-conditions: none
  290. *   Affects: Changes can registers.
  291. *   Depends: none.
  292. */
  293. void canInit()
  294. {
  295.     CANCON = 0x80; //request config mode
  296.     while ((CANSTAT & 0xE0) != 0x80 ); //wait for config mode request
  297.  
  298.     // BAUD AND TQS
  299.  
  300.     BRGCON1=0;
  301.    
  302.     // Sync_Seq = 2 x TQ = 1
  303.     BRGCON1bits.SJW1=0;
  304.     BRGCON1bits.SJW0=1;
  305.    
  306.     // Setting BRP.
  307.     BRGCON1=BRGCON1|CAN_BRP;
  308.    
  309.     // Maximum PHEG1
  310.     BRGCON2bits.SEG2PHTS = 1;
  311.    
  312.     // Phase_Seg1 = 2 x TQ = 1
  313.     BRGCON2bits.SEG1PH2 = 0;
  314.     BRGCON2bits.SEG1PH1 = 0;
  315.     BRGCON2bits.SEG1PH0 = 1;
  316.    
  317.     // Prop_Seq = 2 x TQ = 1
  318.     BRGCON2bits.PRSEG2 = 0;
  319.     BRGCON2bits.PRSEG1 = 0;
  320.     BRGCON2bits.PRSEG0 = 1;
  321.    
  322.     //  Enableing bus wake-up
  323.     BRGCON3bits.WAKDIS = 0;
  324.    
  325.     // Dont use filter when wakeup
  326.     BRGCON3bits.WAKFIL = 0;
  327.    
  328.     // Phase_Seg2 = 2 x TQ = 1
  329.     BRGCON3bits.SEG2PH2 = 0;
  330.     BRGCON3bits.SEG2PH1 = 0;
  331.     BRGCON3bits.SEG2PH0 = 1;
  332.  
  333.     ECANCON=0;
  334.     ECANCONbits.MDSEL1 = 0;
  335.     ECANCONbits.MDSEL0 = 1;
  336.  
  337.  
  338.     // FILTERS AND MASKS
  339.     RXB0CONbits.RXM1=1;
  340.     RXB0CONbits.RXM0=0;
  341.  
  342.  
  343.     // INTERRUPTS
  344.    
  345.     // Diable transmit interrupt
  346.     TXBIE = 0;
  347.  
  348.     //rx no interrupt
  349.     PIR3 = 0;
  350.     PIE3 = 0;
  351.  
  352.  
  353.     // Programmable no buffers interrupt
  354.     BIE0  = 0x00;  
  355.  
  356.  
  357.     //loopback mode or not
  358.     #ifdef CAN_LOOPBACK_MODE
  359.         CANCON = 0x40;//request loopback mode
  360.         while ((CANSTAT & 0xE0) != 0x40 );//wait for loopback mode
  361.     #else
  362.         CANCON = 0x00;//request normal mode
  363.         while ((CANSTAT & 0xE0) != 0x00 );//wait for normal mode
  364.     #endif
  365.  
  366. }
  367.  
  368.  
  369.  
  370.  
  371. /*
  372. *   Function: canGetPacket
  373. *
  374. *   Input:  none
  375. *   Output: none
  376. *   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
  377. *   Affects: Calls canParse() function in main for parsing received packet.
  378. *   Depends: none.
  379. */
  380. BOOL canGetPacket()
  381. {
  382.  
  383.         // Get which buffer that is ful.
  384.              if (RXB0CONbits.RXFUL) { ECANCON=(ECANCON&0b00000)|0b10000;  }
  385.         else if (RXB1CONbits.RXFUL) { ECANCON=(ECANCON&0b00000)|0b10001;  }
  386.         else if (B0CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10010;  }
  387.         else if (B1CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10011;  }
  388.         else if (B2CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10100;  }
  389.         else if (B3CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10101;  }
  390.         else if (B4CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10110;  }
  391.         else if (B5CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10111;  }
  392.         else return FALSE;
  393.  
  394.  
  395.         //RXB0SIDH 28 27 26 25 24 23 22 21
  396.         //RXB0SIDL 20 19 18 xx xx xx 17 16
  397.         //RXB0EIDH 15 14 13 12 11 10 09 08
  398.         //RXB0EIDL 07 06 05 04 03 02 01 00
  399.  
  400.         //funct xx xx xx xx 28 27 26 25
  401.         //funcc xx xx xx xx xx xx 24 23 22 21 20 19 18 17 16 15
  402.         //nid   xx xx 14 13 12 11 10 09
  403.         //sid   xx xx xx xx xx xx xx 08 07 06 05 04 03 02 01 00
  404.  
  405.  
  406.         cm.funct=((RXB0SIDH & 0xF0)>>4);
  407.         cm.funcc=(((WORD)(RXB0SIDH & 0x0F))<<6)+(((WORD)(RXB0SIDL & 0xE0))>>2)+(((WORD)(RXB0SIDL & 0x03))<<1)+(((WORD)(RXB0EIDH & 0x80))>>7);
  408.         cm.nid=((RXB0EIDH & 0x7E)>>1);
  409.         cm.sid=(((WORD)(RXB0EIDH & 0x01))<<8)+RXB0EIDL;
  410.  
  411.  
  412.         // Data length
  413.         cm.data_length=(RXB0DLCbits.DLC3<<3)+(RXB0DLCbits.DLC2<<2)+(RXB0DLCbits.DLC1<<1)+RXB0DLCbits.DLC0;
  414.  
  415.         // Remote request
  416.         cm.remote_request=(RXB0DLCbits.RXRTR==0?FALSE:TRUE);
  417.  
  418.         // Data one bye one, for speed
  419.         cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
  420.         cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
  421.         cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
  422.         cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
  423.  
  424.         // Clear ful status
  425.         RXB0CONbits.RXFUL=0;
  426.  
  427.         return TRUE;
  428. }
  429.  
  430.  
  431. /*
  432. *   Function: canSendMessage
  433. *
  434. *   Input:  CAN_MESSAGE to send
  435. *   Output: True if packet scheduled sucess, false otherwise.
  436. *   Pre-conditions: canInit
  437. *   Affects: ..
  438. *   Depends: ..
  439. */
  440. BOOL canSendMessage(CAN_PROTO_MESSAGE cm,CAN_PRIORITY prio)
  441. {
  442.    
  443.     if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
  444.     if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
  445.     if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
  446.     // None of the transmit buffers were empty.
  447.     else { return FALSE;}
  448.  
  449.     if (prio<0 || prio>3) prio = 0;
  450.  
  451.  
  452.         //RXB0SIDH 28 27 26 25 24 23 22 21
  453.         //RXB0SIDL 20 19 18 xx xx xx 17 16
  454.         //RXB0EIDH 15 14 13 12 11 10 09 08
  455.         //RXB0EIDL 07 06 05 04 03 02 01 00
  456.  
  457.         //funct xx xx xx xx 28 27 26 25
  458.         //funcc xx xx xx xx xx xx 24 23 22 21 20 19 18 17 16 15
  459.         //nid   xx xx 14 13 12 11 10 09
  460.         //sid   xx xx xx xx xx xx xx 08 07 06 05 04 03 02 01 00
  461.  
  462.         RXB0SIDH = (BYTE)((cm.funct & 0x0F)<<4)+(BYTE)((cm.funcc & 0x03C0)>>6);
  463.         RXB0SIDL = (BYTE)((cm.funcc & 0x003F)<<2)+(BYTE)((cm.funcc & 0x0006)>>1);
  464.         RXB0EIDH = (BYTE)((cm.funcc & 0x0001)<<7)+(BYTE)((cm.nid & 0x3F)<<1)+(BYTE)((cm.sid & 0x0100)>>8);
  465.         RXB0EIDL = (BYTE)((cm.sid & 0x00FF));
  466.  
  467.         // Data length
  468.         RXB0DLC = 0;
  469.         if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
  470.        
  471.         // Remote request
  472.         if (cm.remote_request==TRUE)
  473.         {
  474.             _asm
  475.                 bsf RXB0DLC, 6, 0
  476.             _endasm
  477.         }
  478.         else
  479.         {
  480.             _asm
  481.                 bcf RXB0DLC, 6, 0
  482.             _endasm
  483.         }
  484.  
  485.         // Data one bye one, for speed
  486.         RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
  487.         RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
  488.         RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
  489.         RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
  490.  
  491.         // set extended or not
  492.         RXB0SIDLbits.EXID=1;
  493.  
  494.         // Priority
  495.         RXB0CON = (RXB0CON & 0b11111100) | prio;
  496.  
  497.         // mark as redy to transmit
  498.         _asm
  499.             bsf RXB0CON, 3, 0
  500.         _endasm
  501.  
  502.         return TRUE;
  503.  
  504. }
  505.  
  506.  
  507.  
  508. #endif //USE_CAN
  509.