cancel
Showing results for 
Search instead for 
Did you mean: 

Where are all the hardware register addresses defined?

JoniS
Senior

Hi, the title pretty much says what i'm after.

Used CubeMx to generate the startup code and hardware inits to get fast start.

Sure the periephals works and got the micro running, but i want to get bit closer to hardware and decided to start from Can RX interrupt, just cant figure where or how most of the registers are defined or am i expecting too much when i think those should be defined by default with same names as in datasheet.

the MCU in question is STM32F446RE if that matters, and i'm using VISUALGDB

EDIT: or do i need to do it like -> "#define CAN_RI0R (CAN_BASE) + (offset from datasheet)" since there is no definition for it by default?

17 REPLIES 17

Snap. I still use ATTINYs a lot but some projects need a lot more grunt and Microchip/Atmel's ARM products are a but sluggish compared with ST. Quite why ST couldn't have standardised on Visual Studio as well is beyond me - it would have been great to have all my development on one IDE.

I just use the reference manual and ask questions here when something doesn't work.

Which receive FIFO did you mean, there's quite a few around.

I do mean the bxcan hardware receive fifo(or well 3 mailboxes organized as fifo like st says), it should have space for 3 messages, but there are only 2 interrupts(for message in box 1 and box 2) and the registers only let access to those 2 aswell, so I do assume that the third message can't be directly accessed at first, but is shifted in one of the others, depending which was cleared first, but making such assumption could cause alot of messages to be missed if it does not work like that, sadly I don't have any commercial can logger to test if I'm correct or not.

ah I don't use CAN so no idea sorry

Yes, the names are then different, and ST should sync those definitions with the RM

I have a 2334-line ever-growing hand-typed text file which among other things lists omissions like this in the ST docs. The mismatches between the RM and .h file names/values, but my (least) favorite is completely inside the RMs themselves, where, for instance, the labels in clock tree diagrams give no reference to the registers/bits needed to control each hardware component.

It took 10 years until ST added the "xxxPos" definitions

And there's the useless definitions of bits in multiple-bit fields:

 #define GPIO_CRL_MODE3_0                    (0x1U << GPIO_CRL_MODE3_Pos)     /*!< 0x00001000 */
 #define GPIO_CRL_MODE3_1                    (0x2U << GPIO_CRL_MODE3_Pos)     /*!< 0x00002000 */

How is:

GPIOC->CRL = GPIO_CRL_CNF3_0 | GPIO_CRL_CNF3_1;

any clearer, understandable, debug-able, or self-documenting than:

GPIOC->CRL = 0b11 << GPIO_CRL_CNF3_Pos;

much less what's really needed:

GPIOC->CRL = GPIO_CRL_CNF3_AF_OPENDRAIN;

(Note that I don't know what the CMSIS standards say about this.)

There's also the fact that all the structs are typedef'd but not given struct names. Because of this you can't forward-declare pointers to them, for example in user header files, so the entire stm32[fhl]NNNyy.h file has to be included in each one.

I could go on, but instead I'll just mention again that anyone is free to check out https://github.com/thanks4opensource/regbits_stm for a completely different approach that (I claim) solves all these problems, and more.

ST's stance is, that you ought to click in CubeMX and don't ask questions.

Yes, that's the conclusion I've come to.

 

MikeDB
Lead

"ST's stance is, that you ought to click in CubeMX and don't ask questions."

Well since CubeMX doesn't produce valid code for the H7, does that mean we shouldn't use those processors ?

Also base addresses can (usually) be found in the reference manual.

In the "memory and bus architecture" / "memory map".

You define the destination FIFO in the CAN filter.

Actually, that's two receive FIFOs with 3 messages each. It serves as kind of 2 priority queues.

The transmit mailboxes only hold one message.

yeah i actually figured its like that, did remenber wrong when wrote the earlier message.

extern "C" void CAN1_RX0_IRQHandler() {
	// check if ID is basic or extended and store it */
	if((CAN1->sFIFOMailBox->RIR & (1 << CAN_RI0R_IDE_Msk)) == 1) {
		message.setIdentifier((CAN1->sFIFOMailBox->RIR & CAN_RI0R_EXID));
	} else {
		message.setIdentifier(CAN1->sFIFOMailBox->RIR & CAN_RI0R_STID);
	}
	/* set payload size */
	message.setPayloadSize(CAN1->sFIFOMailBox->RDTR & CAN_DLC_BIT);
	/* copy the whole register, do processing elsewhere based on DLC */
	message.setPayload(CAN1->sFIFOMailBox->RDLR, CAN1->sFIFOMailBox->RDHR);	
	
	/* add the message to the box for later use */
	messageBox.addNew(message);
	/* Release FIFO 0 output mailbox */
	CAN1->RF0R |= (1 << CAN_RFxM_BIT);
}

Don't know if i got it right thought, program is freezing after 2 interrupts exact every single time, but it might be that its related to other part of the code and not the interrupt.