📄 scc_s515.c
字号:
// Message is correct
Start_slave = 1;
// Send ack
CAN_messages[1].Data[0] = 0x00; // Set data byte 0
CAN_messages[1].Data[1] = SLAVE_ID; // Set data byte 1
CAN_messages[1].MCR1 = 0xE7; // Send it
}
else
{
// Not yet received correct message - wait
Start_slave = 0;
}
} while (!Start_slave);
// Start the scheduler
IRCON = 0;
EAL = 1;
}
/*------------------------------------------------------------------*-
SCC_A_SLAVE_Update
This is the scheduler ISR. It is called at a rate
determined by the timer settings in SCC_A_SLAVE_Init().
This Slave is triggered by USART interrupts.
-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Update(void) interrupt INTERRUPT_CAN_c515c
{
tByte Index;
// Reset this when tick is received
Network_error_pin = NO_NETWORK_ERROR;
// Check tick data - send ack if necessary
// NOTE: 'START' message will only be sent after a 'time out'
if (SCC_A_SLAVE_Process_Tick_Message() == SLAVE_ID)
{
SCC_A_SLAVE_Send_Ack_Message_To_Master();
// Feed the watchdog ONLY when a *relevant* message is received
// (noise on the bus, etc, will not stop the watchdog...)
//
// START messages will NOT refresh the slave
// - Must talk to every slave at regular intervals
SCC_A_SLAVE_Watchdog_Refresh();
}
// Check the last error codes on the CAN bus via the status register
if ((CAN_sr & 0x07) != 0)
{
Error_code_G = ERROR_SCH_CAN_BUS_ERROR;
Network_error_pin = NETWORK_ERROR;
// See Infineon c515c manual for error code details
CAN_error_pin0 = ((CAN_sr & 0x01) == 0);
CAN_error_pin1 = ((CAN_sr & 0x02) == 0);
CAN_error_pin2 = ((CAN_sr & 0x04) == 0);
}
else
{
CAN_error_pin0 = 1;
CAN_error_pin1 = 1;
CAN_error_pin2 = 1;
}
// NOTE: calculations are in *TICKS* (not milliseconds)
for (Index = 0; Index < SCH_MAX_TASKS; Index++)
{
// Check if there is a task at this location
if (SCH_tasks_G[Index].pTask)
{
if (SCH_tasks_G[Index].Delay == 0)
{
// The task is due to run
SCH_tasks_G[Index].RunMe = 1; // Set the run flag
if (SCH_tasks_G[Index].Period)
{
// Schedule periodic tasks to run again
SCH_tasks_G[Index].Delay = SCH_tasks_G[Index].Period;
}
}
else
{
// Not yet ready to run: just decrement the delay
SCH_tasks_G[Index].Delay -= 1;
}
}
}
}
/*------------------------------------------------------------------*-
SCC_A_SLAVE_Process_Tick_Message()
The ticks messages are crucial to the operation of this shared-clock
scheduler: the arrival of a tick message (at regular intervals)
invokes the 'Update' ISR, that drives the scheduler.
The tick messages themselves may contain data. These data are
extracted in this function.
-*------------------------------------------------------------------*/
tByte SCC_A_SLAVE_Process_Tick_Message(void)
{
tByte Tick_ID;
if ((CAN_messages[0].MCR1 & 0x0c) == 0x08) // if MSGLST set
{
// Indicates that the CAN controller has stored a new
// message into this object, while NEWDAT was still set,
// i.e. the previously stored message is lost.
// We simply IGNORE this here and reset the flag
CAN_messages[0].MCR1 = 0xf7; // reset MSGLST
}
// The first byte is the ID of the slave for which the data are
// intended
Tick_ID = CAN_messages[0].Data[0]; // Get data byte 0 (Slave ID)
if (Tick_ID == SLAVE_ID)
{
// Only if there is a match do we need to copy these fields
Tick_message_data_G[0] = CAN_messages[0].Data[1];
Tick_message_data_G[1] = CAN_messages[0].Data[2];
Tick_message_data_G[2] = CAN_messages[0].Data[3];
Tick_message_data_G[3] = CAN_messages[0].Data[4];
}
CAN_messages[0].MCR0 = 0xfd; // reset NEWDAT, INTPND
CAN_messages[0].MCR1 = 0xfd;
return Tick_ID;
}
/*------------------------------------------------------------------*-
SCC_A_SLAVE_Send_Ack_Message_To_Master()
Slave must send and 'Acknowledge' message to the master, after
tick messages are received. NOTE: Only tick messages specifically
addressed to this slave should be acknowledged.
The acknowledge message serves two purposes:
[1] It confirms to the master that this slave is alive & well.
[2] It provides a means of sending data to the master and - hence
- to other slaves.
NOTE: Data transfer between slaves is NOT permitted!
-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Send_Ack_Message_To_Master(void)
{
// First byte of message must be slave ID
CAN_messages[1].Data[0] = SLAVE_ID; // data byte 0
CAN_messages[1].Data[1] = Ack_message_data_G[0];
CAN_messages[1].Data[2] = Ack_message_data_G[1];
CAN_messages[1].Data[3] = Ack_message_data_G[2];
CAN_messages[1].Data[4] = Ack_message_data_G[3];
// Send the message on the CAN bus
CAN_messages[1].MCR1 = 0xE7; // TXRQ, reset CPUUPD
}
/*------------------------------------------------------------------*-
SCC_A_SLAVE_Watchdog_Init()
This function sets up the watchdog timer.
If the Master fails (or other error develop),
no tick messages will arrive, and the scheduler
will stop.
To detect this situation, we have a (hardware) watchdog
running in the slave. This watchdog - which should be set to
overflow at around 100ms - is used to set the system into a
known (safe) state. The slave will then wait (indefinitely)
for the problem to be resolved.
NOTE: The slave will not be generating Ack messages in these
circumstances. The Master (if running) will therefore be aware
that there is a problem.
-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Watchdog_Init(void)
{
// Watchdog timer prescaler (1/16) enabled
// Watchdog timer reload value is 0x6B
// Watchdog period is 103.2 ms (10.0 MHz xtal, c515c)
WDTREL = 0xEB;
// Start watchdog timer
WDT = 1;
SWDT = 1;
}
/*------------------------------------------------------------------*-
SCC_A_SLAVE_Watchdog_Refresh()
Feed the watchdog.
-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Watchdog_Refresh(void) reentrant
{
WDT = 1;
SWDT = 1;
}
/*------------------------------------------------------------------*-
SCC_A_SLAVE_Enter_Safe_State()
This is the state enterted by the system when:
(1) The node is powerec up or reset
(2) The Master node fails, and no working backup is available
(3) The network has an error
(4) Tick messages are delayed for any other reason
Try to ensure that the system is in a 'safe' state in these
circumstances.
-*------------------------------------------------------------------*/
void SCC_A_SLAVE_Enter_Safe_State(void)
{
// USER DEFINED
TRAFFIC_LIGHTS_Display_Safe_Output();
}
/*------------------------------------------------------------------*-
---- END OF FILE -------------------------------------------------
-*------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -