- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How do I make a CAN basic mailbox that does not acknowledge messages? I want to set it up so that a few message IDs are acknowledged and the rest are still processed, but silently. I thought I could do this by setting up full mailboxes for the few IDs I'm supposed to be acking and one basic one to process the rest.
So far I've set up a CAN component with a basic mailbox and a ReceiveMsg_Callback() that does not call CAN_RX_ACK_MESSAGE. I don't see any APIs for explicitly not acking. After doing this, an oscilloscope shows that the tx pin is still going low during the ack window for every frame. I'd expect it to do nothing.
Solved! Go to Solution.
- Labels:
-
PSoC 5 Device Programming
-
PSoC 5LP
- Tags:
- can
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If the Full Custom internal ISR is unchecked, the component generates complete ISR code for each of the interrupts that you enable in the component. With the default ISR code for Message received interrupt, CAN_MsgRXIsr() in CAN_INT.c is called. This in turn calls CAN_ReceiveMsg(uint8 rxMailbox) . This function does the following
1. Interrupt is cleared
2. Message is acked
void CAN_ReceiveMsg(uint8 rxMailbox)
{
#if (CY_PSOC3 || CY_PSOC5)
if ((CAN_RX[rxMailbox].rxcmd.byte[0u] & CAN_RX_ACK_MSG) != 0u)
#else /* CY_PSOC4 */
if ((CAN_RX_CMD_REG(rxMailbox) & CAN_RX_ACK_MSG) != 0u)
#endif /* CY_PSOC3 || CY_PSOC5 */
{
/* `#START MESSAGE_BASIC_RECEIVED` */
/* `#END` */
#ifdef CAN_RECEIVE_MSG_CALLBACK
CAN_ReceiveMsg_Callback();
#endif /* CAN_RECEIVE_MSG_CALLBACK */
#if (CY_PSOC3 || CY_PSOC5)
CAN_RX[rxMailbox].rxcmd.byte[0u] |= CAN_RX_ACK_MSG;
#else /* CY_PSOC4 */
CAN_RX_CMD_REG(rxMailbox) |= CAN_RX_ACK_MSG;
#endif /* CY_PSOC3 || CY_PSOC5 */
}
}
ReceiveMsg_Callback() is called from this function and hence ACK can not be avoided if you use default ISR.
You need to create a custom ISR for what you want to achieve. To do so,
1. Under Interrupt tab check the Full custom internal ISR and message received checkbox.
2. Configure a Basic message box and enable IRQ.
3. Set up a custom ISR using CyIntSetVector()
/* Set CAN interrupt handler to local routine */
CyIntSetVector(CAN_ISR_NUMBER, ISR_CAN);
4. CAN_ISR
CY_ISR(ISR_CAN)
{
/* Clear Receive Message flag */
CAN_INT_SR_REG.byte[1u] = CAN_RX_MESSAGE_MASK;
/* Set the isrFlag */
isrFlag = 1u;
/* Acknowledges receipt of new message */
CAN_RX_ACK_MESSAGE(CAN_RX_MAILBOX_0); // Do not call this if you do not want to ACK
}
But please note that this option requires to you to completely write the ISR for all the events. You can use CAN_ISR.c for reference.
Regards,
Bragadeesh
Bragadeesh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If the Full Custom internal ISR is unchecked, the component generates complete ISR code for each of the interrupts that you enable in the component. With the default ISR code for Message received interrupt, CAN_MsgRXIsr() in CAN_INT.c is called. This in turn calls CAN_ReceiveMsg(uint8 rxMailbox) . This function does the following
1. Interrupt is cleared
2. Message is acked
void CAN_ReceiveMsg(uint8 rxMailbox)
{
#if (CY_PSOC3 || CY_PSOC5)
if ((CAN_RX[rxMailbox].rxcmd.byte[0u] & CAN_RX_ACK_MSG) != 0u)
#else /* CY_PSOC4 */
if ((CAN_RX_CMD_REG(rxMailbox) & CAN_RX_ACK_MSG) != 0u)
#endif /* CY_PSOC3 || CY_PSOC5 */
{
/* `#START MESSAGE_BASIC_RECEIVED` */
/* `#END` */
#ifdef CAN_RECEIVE_MSG_CALLBACK
CAN_ReceiveMsg_Callback();
#endif /* CAN_RECEIVE_MSG_CALLBACK */
#if (CY_PSOC3 || CY_PSOC5)
CAN_RX[rxMailbox].rxcmd.byte[0u] |= CAN_RX_ACK_MSG;
#else /* CY_PSOC4 */
CAN_RX_CMD_REG(rxMailbox) |= CAN_RX_ACK_MSG;
#endif /* CY_PSOC3 || CY_PSOC5 */
}
}
ReceiveMsg_Callback() is called from this function and hence ACK can not be avoided if you use default ISR.
You need to create a custom ISR for what you want to achieve. To do so,
1. Under Interrupt tab check the Full custom internal ISR and message received checkbox.
2. Configure a Basic message box and enable IRQ.
3. Set up a custom ISR using CyIntSetVector()
/* Set CAN interrupt handler to local routine */
CyIntSetVector(CAN_ISR_NUMBER, ISR_CAN);
4. CAN_ISR
CY_ISR(ISR_CAN)
{
/* Clear Receive Message flag */
CAN_INT_SR_REG.byte[1u] = CAN_RX_MESSAGE_MASK;
/* Set the isrFlag */
isrFlag = 1u;
/* Acknowledges receipt of new message */
CAN_RX_ACK_MESSAGE(CAN_RX_MAILBOX_0); // Do not call this if you do not want to ACK
}
But please note that this option requires to you to completely write the ISR for all the events. You can use CAN_ISR.c for reference.
Regards,
Bragadeesh
Bragadeesh