/*------------------------------------------------------------------*- SCI_TICK1_SLAVE_Init() Scheduler initialisation function. Prepares scheduler data structures and sets up timer interrupts at required rate. Must call this function before using the scheduler. -*------------------------------------------------------------------*/ void SCI_TICK1_SLAVE_Init(void) { tByte i; // Sort out the tasks for (i = 0; i < SCH_MAX_TASKS; i++) { SCH_Delete_Task(i); } // Reset the global error variable // - SCH_Delete_Task() will generate an error code, // (because the task array is empty) Error_code_G = 0; // ---------- External interrupt 0 ---------- // The slave is driven by an interrupt input // The interrupt is enabled // It is triggered by a falling edge at pin P3.2 IT0 = 1; EX0 = 1; // Start the watchdog SCI_TICK1_SLAVE_Watchdog_Init(); }
void setup_scheduler(void) { unsigned short int i; for (i = 0; i < SCH_MAX_TASKS; ++i) { SCH_Delete_Task(i); } }
/*------------------------------------------------------------------*- SCH_Dispatch_Tasks() This is the 'dispatcher' function. When a task (function) is due to run, SCH_Dispatch_Tasks() will run it. This function must be called (repeatedly) from the main loop. -*------------------------------------------------------------------*/ void SCH_Dispatch_Tasks(void) { tByte Index; // Dispatches (runs) the next task (if one is ready) for (Index = 0; Index < SCH_MAX_TASKS; Index++) { if (SCH_tasks_G[Index].RunMe > 0) { (*SCH_tasks_G[Index].pTask)(); // Run the task SCH_tasks_G[Index].RunMe -= 1; // Reset / reduce RunMe flag // Periodic tasks will automatically run again // - if this is a 'one shot' task, remove it from the array if (SCH_tasks_G[Index].Period == 0) { SCH_Delete_Task(Index); } } } // Report system status SCH_Report_Status(); // The scheduler enters idle mode at this point SCH_Go_To_Sleep(); }
/*------------------------------------------------------------------*- SCH_Init_T2() Scheduler initialisation function. Prepares scheduler data structures and sets up timer interrupts at required rate. Must call this function before using the scheduler. -*------------------------------------------------------------------*/ void SCH_Init_T2(void) { tByte i; for (i = 0; i < SCH_MAX_TASKS; i++) { SCH_Delete_Task(i); } // Reset the global error variable // - SCH_Delete_Task() will generate an error code, // (because the task array is empty) Error_code_G = 0; // Now set up Timer 2 // 16-bit timer function with automatic reload // Crystal is assumed to be 12 MHz // The Timer 2 resolution is 0.000001 seconds (1 µs) // The required Timer 2 overflow is 0.001 seconds (1 ms) // - this takes 1000 timer ticks // Reload value is 65536 - 1000 = 64536 (dec) = 0xFC18 T2CON = 0x04; // load Timer 2 control register T2MOD = 0x00; // load Timer 2 mode register TH2 = 0xFC; // load timer 2 high byte RCAP2H = 0xFC; // load timer 2 reload capture reg, high byte TL2 = 0x18; // load timer 2 low byte RCAP2L = 0x18; // load timer 2 reload capture reg, low byte ET2 = 1; // Timer 2 interrupt is enabled TR2 = 1; // Start Timer 2 }
void Init_timer0() { int i =0; for (i=0;i< SCH_MAX_TASKS ;i++) { SCH_Delete_Task(i); } // initialising the timer and start the timer T0CON |= 0x86;// prescaler 128 and start the timer // initialisation of the interrupt INTCON |= 0xA0; //ResetTimer0(); }
void SCH_Dispatcher_Tasks() { unsigned int index; for(index =0; index < SCH_MAX_TASKS;index++ ) { if (SCH_Tasks_G[index].RunMe >0) { (*SCH_Tasks_G[index].pTask)(); //SCH_Tasks_G[index].RunMe -= 1; --SCH_Tasks_G[index].RunMe; if(SCH_Tasks_G[index].Repeat ==0) SCH_Delete_Task(index); } } enter_sleep_state(); }
/*------------------------------------------------------------------*- SCH_Init_T0() Scheduler initialisation function. Prepares scheduler data structures and sets up timer interrupts at required rate. Must call this function before using the scheduler. -*------------------------------------------------------------------*/ void SCH_Init_T0(void) { tByte i; for (i = 0; i < SCH_MAX_TASKS; i++) { SCH_Delete_Task(i); } // Reset the global error variable // - SCH_Delete_Task() will generate an error code, // (because the task array is empty) Error_code_G = 0; // Using Timer 0, 16-bit manual reload TMOD &= 0xF0; // Clear all T0 bits (T1 left unchanged) TMOD |= 0x01; // Set required T0 bits (T1 left unchanged) // Sets up timer reload values SCH_Manual_Timer0_Reload(); // Interrupt Timer 0 enabled ET0 = 1; }
/*------------------------------------------------------------------*- SCH_Init_T2() Scheduler initialisation function. Prepares scheduler data structures and sets up timer interrupts at required rate. Must call this function before using the scheduler. -*------------------------------------------------------------------*/ void SCH_Init_T2(void) { tByte i; // Sort out the tasks for (i = 0; i < SCH_MAX_TASKS; i++) { SCH_Delete_Task(i); } // Reset the global error variable // - SCH_Delete_Task() will generate an error code, // (because the task array is empty) Error_code_G = 0; // Now set up Timer 2 // 16-bit timer function with automatic reload // Crystal is assumed to be 10 MHz // Using c515c, so timer can be incremented at 1/6 crystal frequency // if prescalar is not used // Prescaler not used -> Crystal/6 T2PS = 0; // The Timer 2 resolution is 0.0000006 seconds (0.6 µs) // The required Timer 2 overflow is 0.001 seconds (1 ms) // - this takes 1666.666666667 timer ticks (can't get precise timing) // Reload value is 65536 - 1667 = 63869 (dec) = 0xF97D TH2 = 0xF9; TL2 = 0x7D; // Compare/capture Channel 0 // Disabled // Compare Register CRC on: 0x0000; CRCH = 0xF9; CRCL = 0x7D; // Mode 0 for all channels T2CON |= 0x11; // timer 2 overflow interrupt is enabled ET2 = 1; // timer 2 external reload interrupt is disabled EXEN2 = 0; // CC0/ext3 interrupt is disabled EX3 = 0; // Compare/capture Channel 1-3 // Disabled CCL1 = 0x00; CCH1 = 0x00; CCL2 = 0x00; CCH2 = 0x00; CCL3 = 0x00; CCH3 = 0x00; // Interrupts Channel 1-3 // Disabled EX4 = 0; EX5 = 0; EX6 = 0; // all above mentioned modes for Channel 0 to Channel 3 CCEN = 0x00; // ------ Set up Timer 2 (end) ---------------------------------- }
/*------------------------------------------------------------------*- SCC_A_SLAVE_Init_CAN() Scheduler initialisation function. Prepares scheduler data structures and sets up timer interrupts at required rate. Must call this function before using the scheduler. -*------------------------------------------------------------------*/ void SCC_A_SLAVE_Init_CAN(void) { tByte i; tByte Message; // Sort out the tasks for (i = 0; i < SCH_MAX_TASKS; i++) { SCH_Delete_Task(i); } // Reset the global error variable // - SCH_Delete_Task() will generate an error code, // (because the task array is empty) Error_code_G = 0; // Set the network error pin (reset when tick message received) Network_error_pin = NETWORK_ERROR; // ------ SYSCON Register // The access to XRAM and CAN controller is enabled. // The signals !RD and !WR are not activated during accesses // to the XRAM/CAN controller. // ALE generation is enabled. SYSCON = 0x20; // ------------ CAN Control/Status Register -------------- // Start to init the CAN module CAN_cr = 0x41; // INIT and CCE // ------------ Bit Timing Register --------------------- // Baudrate = 333.333 kbaud // - Need 308+ kbaud plus for 1ms ticks, 8 data bytes // - See text for details // // There are 5 time quanta before sample point // There are 4 time quanta after sample point // The (re)synchronization jump width is 2 time quanta CAN_btr1 = 0x34; // Bit Timing Register CAN_btr0 = 0x42; CAN_gms1 = 0xFF; // Global Mask Short Register 1 CAN_gms0 = 0xFF; // Global Mask Short Register 0 CAN_ugml1 = 0xFF; // Upper Global Mask Long Register 1 CAN_ugml0 = 0xFF; // Upper Global Mask Long Register 0 CAN_lgml1 = 0xF8; // Lower Global Mask Long Register 1 CAN_lgml0 = 0xFF; // Lower Global Mask Long Register 0 // ------ Configure 'Tick' Message Object // Message object 1 is valid // enable receive interrupt CAN_messages[0].MCR1 = 0x55; // Message Ctrl. Reg. 1 CAN_messages[0].MCR0 = 0x99; // Message Ctrl. Reg. 0 // message direction is receive // extended 29-bit identifier CAN_messages[0].MCFG = 0x04; // Message Config. Reg. CAN_messages[0].UAR1 = 0x00; // Upper Arbit. Reg. 1 CAN_messages[0].UAR0 = 0x00; // Upper Arbit. Reg. 0 CAN_messages[0].LAR1 = 0x00; // Lower Arbit. Reg. 1 CAN_messages[0].LAR0 = 0x00; // Lower Arbit. Reg. 0 // ------ Configure 'Ack' Message Object CAN_messages[1].MCR1 = 0x55; // Message Ctrl. Reg. 1 CAN_messages[1].MCR0 = 0x95; // Message Ctrl. Reg. 0 // Message direction is transmit // extended 29-bit identifier // 5 valid data bytes CAN_messages[1].MCFG = 0x5C; // Message Config. Reg. CAN_messages[1].UAR1 = 0x00; // Upper Arbit. Reg. 1 CAN_messages[1].UAR0 = 0x00; // Upper Arbit. Reg. 0 CAN_messages[1].LAR1 = 0xF8; // Lower Arbit. Reg. 1 CAN_messages[1].LAR0 = 0x07; // Lower Arbit. Reg. 0 CAN_messages[1].Data[0] = 0x00; // data byte 0 CAN_messages[1].Data[1] = 0x00; // data byte 1 CAN_messages[1].Data[2] = 0x00; // data byte 2 CAN_messages[1].Data[3] = 0x00; // data byte 3 CAN_messages[1].Data[4] = 0x00; // data byte 4 // ------ Configure other objects ------------------------------ // Configure remaining message objects (2-14) - none are valid for (Message = 2; Message <= 14; ++Message) { CAN_messages[Message].MCR1 = 0x55; // Message Ctrl. Reg. 1 CAN_messages[Message].MCR0 = 0x55; // Message Ctrl. Reg. 0 } // ------------ CAN Ctrl. Reg. --------------------- // reset CCE and INIT // enable interrupt generation from CAN Modul // enable CAN-interrupt of Controller CAN_cr = 0x02; IEN2 |= 0x02; // Start the watchdog SCC_A_SLAVE_Watchdog_Init(); }