Giter Site home page Giter Site logo

Comments (12)

nopnop2002 avatar nopnop2002 commented on August 25, 2024

Advanced use of BxCan

Skip if you don't need advanced usage.
Advanced usage has different purposes depending on the requirements of the application.
So I can't give you a concrete code example.

About transmission

STM32 has three transmit(TX) mailboxes.
Three TX mailboxes are provided to the software for setting up messages.
This sample code uses only the first TX mailbox and blocks the application until the send is successfully completed.
There are two ways to know if the send was successful without blocking.
Read the reference manual carefully and modify the source code as needed.

  • Uses a transmission completion interrupt
    You need to set the CAN interrupt enable register (CAN_IER) appropriately.

  • Check TX mailbox space before sending
    An application can store transmission requests in three TX mailboxes simultaneously.
    When there are requests for multiple TX mailboxes, the transmission scheduler decides which mailbox has to be transmitted first.
    You can specify which mailbox has priority using the CAN Master Control Register (CAN_MCR).
    You can tell if a mailbox is free using the CAN Transmit Status Register (CAN_TSR).
    When all three TX mailboxes are pending, no new messages can be sent until the transmit is canceled or completed.
    When all three TX mailboxes are pending, you can choose to cancel the pending transmission, wait until the transmission is complete, or give up on the new transmission.
    This choice depends on your application requirements.
    When all three TX mailboxes are pending for a long time, it could be a transmission error.
    CAN Error Status Register (CAN_ESR) should be checked.

About reception

STM32 has two receive(RX) mailboxes.
Each RX Mailbox allows access to a 3-level depth FIFO, the access being offered only to the oldest received message in the FIFO.
This sample code uses only the first RX mailbox.
The RX mailbox is closely related to the receive filter settings.
By properly setting the receive filter, you can sort the received messages into two RX Mailboxes.
For example, high priority messages can be stored in the first RX MailBox and low priority messages can be stored in the second RX MailBox.
Read the reference manual carefully and modify the source code as needed.

from arduino-stm32-can.

i-make-robots avatar i-make-robots commented on August 25, 2024

Thank you! That seems to match what I read and gives me confidence to proceed.

from arduino-stm32-can.

i-make-robots avatar i-make-robots commented on August 25, 2024

I've had much success now. Thank you for your help.

I've been reading the RM0090 manual for the STM32F405 as you suggested. One thing still eludes me - how do I create an interrupt for bxCAN? I want to catch arriving messages before the three mailboxes overflow. ChatGPT only tells me how to interrupt on a pin change :(
I'm sorry to take up your valuable time. Is there an example in the files that I missed?

from arduino-stm32-can.

nopnop2002 avatar nopnop2002 commented on August 25, 2024

First of all, to write a conclusion, you cannot use bxCan interrupts with Arduino core support for STM32.

The following steps should get the transmit interrupt working, but then it stops.

Add this in CANInit()

  CAN1->IER  |=   0x1UL;                // Set to Transmit mailbox empty interrupt enable

Add this in Setup()

  NVIC_SetPriority(CAN1_TX_IRQn, 1);
  NVIC_EnableIRQ(CAN1_TX_IRQn);

Transmit interrupts are now enabled.

STM32F4 Interrupt handlers are defined with the following names.

  .word     CAN1_TX_IRQHandler                /* CAN1 TX                      */
  .word     CAN1_RX0_IRQHandler               /* CAN1 RX0                     */
  .word     CAN1_RX1_IRQHandler               /* CAN1 RX1                     */
  .word     CAN1_SCE_IRQHandler               /* CAN1 SCE                     */


  .word     CAN2_TX_IRQHandler                /* CAN2 TX                      */
  .word     CAN2_RX0_IRQHandler               /* CAN2 RX0                     */
  .word     CAN2_RX1_IRQHandler               /* CAN2 RX1                     */
  .word     CAN2_SCE_IRQHandler               /* CAN2 SCE                     */

This is a week function, so you can replace it.

extern "C" void CAN1_TX_IRQHandler (void)
{
  Serial.println("CAN1_TX_IRQHandler");  
}

This interrupt function is called when transmission is completed, but when this function ends, it becomes HALT.

You can use a debugger with Arduino IDE 2.x.

You can see that this function is called by setting BreakPoint to this function.

It crashes when I proceed with StepOver.
It has been reported to STM, but no countermeasures have been taken yet.

from arduino-stm32-can.

i-make-robots avatar i-make-robots commented on August 25, 2024

Interesting! Here's what I did MarginallyClever/Daisy-Driver-2.0-firmware@465ec3d

in Arduino 2.2.1 with https://github.com/stm32duino/BoardManagerFiles/raw/master/package_stmicroelectronics_index.json

void CANInit() {
  // ...

  // attach message pending interrupt method
  NVIC_SetPriority(CAN1_RX_IRQn, 1);
  NVIC_EnableIRQ(CAN1_RX_IRQn);

  // Enable FIFO Message Pending Interrupt 
  CAN1->IER |= CAN_IER_FMPIE0 | CAN_IER_FMPIE1;
  DEBUGLN("CAN1 interrupt enabled.");

  return true;
}

int CANstate2,CANstate1;
void CAN1_RX0_IRQHandler(void) {
  light.setColor(0,CANstate1,CANstate2);
  CANstate2 = (CANstate2==0? 255 : 0);
  CAN1->RF0R |= CAN_RF0R_RFOM0;  // release FIFO
  CAN1->IER |= CAN_IER_FMPIE0;  // enable interrupt
}

void CAN1_RX1_IRQHandler(void) {
  light.setColor(0,CANstate2,CANstate2);
  CANstate1 = (CANstate1==0? 255 : 0);
  CAN1->RF1R |= CAN_RF1R_RFOM1;  // release FIFO
  CAN1->IER |= CAN_IER_FMPIE1;  // enable interrupt
}

I confirm this problem case. No response from STM tells me nobody write the firmware this way because
a) stm32cubeide is what most people use or
b) polling should be enough or
c) almost nobody writes CAN stuff for this board.

from arduino-stm32-can.

nopnop2002 avatar nopnop2002 commented on August 25, 2024

Does light.setColor() run correctly?

from arduino-stm32-can.

i-make-robots avatar i-make-robots commented on August 25, 2024

on it's own, sure. it's just banging the pins.

void LED::setColor(uint8_t r,uint8_t g,uint8_t b) {
  analogWrite(PIN_PWM_RGB_R,r);
  analogWrite(PIN_PWM_RGB_G,g);
  analogWrite(PIN_PWM_RGB_B,b);
}

in the interrupt? no. the light turns on once and then stays there.

from arduino-stm32-can.

nopnop2002 avatar nopnop2002 commented on August 25, 2024

CAN1_RX0_IRQHandler is a C language function.
When using in C++, You need to change:

//void CAN1_RX0_IRQHandler(void) {
extern "C" void CAN1_RX0_IRQHandler(void) {
  digitalWrite(LED, HIGH);
}

LED will turn on.
But HALT occurs when exiting from an interrupt function.

from arduino-stm32-can.

i-make-robots avatar i-make-robots commented on August 25, 2024

from arduino-stm32-can.

i-make-robots avatar i-make-robots commented on August 25, 2024

Any idea why HALT occurs?

from arduino-stm32-can.

nopnop2002 avatar nopnop2002 commented on August 25, 2024

Probably the default Week function implementation included in the core library is incomplete.

I think the problem can be solved by changing the interrupt vector and using your own interrupt function will solve the problem, but I don't know how to change the interrupt vector from default.

STM is not proactive in resolving this issue.
I have asked STM to suggest a solution, but have not received any response.
Please Ask STM to suggest a solution.

from arduino-stm32-can.

i-make-robots avatar i-make-robots commented on August 25, 2024

I have. https://community.st.com/t5/stm32-mcus-products/stm32f405-can-rx-interrupt-halts/m-p/592491

from arduino-stm32-can.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.