Bootloader Jump the Application I2C problem - stm32

I am trying to jump user application from boot code:
Boot code only include below lines:
int main()
{
HAL_Init();
SystemClock_Config();
// Jump proccess start
uint32_t reset_handler_add=*((volatile uint32_t*)(FLASH_APP_START_ADDRESS+4));
void (*app_reset_handler)(void) = (void*)reset_handler_add;
HAL_RCC_DeInit();
HAL_DeInit();
__HAL_RCC_SYSCFG_CLK_DISABLE();
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
__disable_irq();
SCB->VTOR = FLASH_APP_START_ADDRESS;
uint32_t msp_value = *((volatile uint32_t*)(FLASH_APP_START_ADDRESS));
__set_MSP(msp_value);
app_reset_handler();
while(1);
}
Also #define FLASH_APP_START_ADDRESS 0x080A0000 this is application code start address.
But when I jump the User application I2C not working .
In the User application I stuck in while (HAL_I2C_GetState(hi2c) != HAL_I2C_STATE_READY) function when I jump the User App. But If User App work on the base 0x080000000 address everything successfull, When I jump I have problem.
I changed flash.Ld file on User app:
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K
FLASH (rx) : ORIGIN = 0x080A0000, LENGTH = 256K
}
And changed #define VECT_TAB_OFFSET 0xA0000 value.
Where is the faults ?

There is an I2C init problem in stm32 microcontrollers. I dont know if your issue is related to the bootloader code but I had the same symptoms.
The easiest fix I found for this is to init the I2C clk before initializing the SDA and SCL pins:
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(i2cHandle->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_I2C1_CLK_ENABLE(); // <------ move this line here
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
...

Related

The sample code does not work on STM32F103C6

experts.
I am new to STM32.
So I downloaded some sample code from github.
https://github.com/yohanes-erwin/stm32f103-keil
And I download the simple led blinking code of it to the STM32F103C6 developing board but it doesn't work at all.
The original program embedded on the chip had been erased successfully ( originally the led was always on and LCD screen shows some text, but now after I download the code, the led is off and screen off. So I think the downloading is successful.) but the code does not work.
When I download the original code to the chip, it works again. So I think the chip isn't broken.
I think it's because of compatibility of sample code and my chip. The sample code was written for STM32F103C8. But it was a very simple code. What is the reason?
Here is the code.
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
void delay(unsigned int nCount);
GPIO_InitTypeDef GPIO_InitStruct;
int main (void)
{
// Enable clock for GPIOA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// Configure PA4 as push-pull output
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOA, &GPIO_InitStruct);
while (1)
{
/* Toggle LED on PA0 */
// Reset bit will turn on LED (because the logic is interved)
GPIO_ResetBits(GPIOA, GPIO_Pin_4);
delay(1000);
// Set bit will turn off LED (because the logic is interved)
GPIO_SetBits(GPIOA, GPIO_Pin_4);
delay(1000);
}
}
// Delay function
void delay(unsigned int nCount)
{
unsigned int i, j;
for (i = 0; i < nCount; i++)
for (j = 0; j < 0x2AFF; j++);
}

STM32G030F6 starts program in Flash and after a while it ends up unintentionaly in System Memory

My board have PA14-BOOT0 pin connected to SWDCLK and PA13 to SWDIO.
The BOOT0 pin is not pulled up/down.
According to documentation when nBOOT_SEL bit = 1 and nBOOT0 bit = 1 the BOOT0 pin is ignored and microcontroller boots up from Main Flash. This is the factory setup.
The Flash Option Bytes (address 0x1FFF7800) have default value of 0xDFFFE1AA which I have confirmed (nBOOT_SEL=1, nBOOT0=1).
Im running very basic code:
int main(void)
{
/* Configure the system clock */
SystemClock_Config();
volatile int cnt = 0;
while (1)
{
++cnt;
}
}
/**
* #brief System Clock Configuration
* #retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
}
When I step the code or run to breakpoint at ++cnt multiple times everything works fine.
But when I let the program run freely and pause after a second the Program Counter shows address 0x1FFFxxxx which is somewhere in System Memory (Bootloader) and debug fails at that point.
I have checked registers for Reset Reason, I have set breakpoints in any interrupt handler I have found in Startup file, I have checked the VTOR for proper addres but I didnt manage to catch the moment the processor jumps to System Memory.
If I pull down the BOOT0 pin with 100k resistor the program starts to work normally. I can run program freely then pause and I will be at the the position ++cnt as I expect.
The question is WHY I need to pull down BOOT0 down even the documentation states clearly that BOOT0 pin is IGNORED when nBOOT_SEL bit = 1 and nBOOT0 bit = 1? What kind of sorcery ;) is going on here that my program jumps to System Memory in the middle of debugging?

STM32F4 SPI interrupts stop firing with FreeRTOS

I'm trying to make an SPI communication between a F410 MCU and a RPi using SPI.
I post below the code that currently works (without FreeRTOS usage):
main.c
volatile int tx_done = 0;
volatile int rx_done = 0;
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
tx_done = 1;
}
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
rx_done = 1;
}
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_SPI5_Init();
MX_USART2_UART_Init();
const uint8_t BUF_SIZE = 16 * sizeof(uint8_t);
uint8_t buf[16];
// For UART debug
uint8_t dbg_buffer[64];
while (1) {
memset(buf, 0, BUF_SIZE);
HAL_StatusTypeDef ret = HAL_SPI_Receive_IT(&hspi5, (uint8_t*)&buf, BUF_SIZE);
while (rx_done == 0) {};
rx_done = 0;
sprintf((char*) dbg_buffer, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d]\r\n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6],
buf[7], buf[8], buf[9], buf[10], buf[11], buf[12],
buf[13], buf[14], buf[15]);
HAL_UART_Transmit(&huart2, dbg_buffer, strlen((char const*) dbg_buffer), 50);
HAL_SPI_Transmit_IT(&hspi5, (uint8_t*) &buf, BUF_SIZE);
while (tx_done == 0) {};
tx_done = 0;
}
}
stm32f4xx_it.c
/**
* #brief This function handles TIM1 trigger and commutation interrupts and TIM11 global interrupt.
*/
void TIM1_TRG_COM_TIM11_IRQHandler(void)
{
HAL_TIM_IRQHandler(&htim11);
}
/**
* #brief This function handles SPI5 global interrupt.
*/
void SPI5_IRQHandler(void)
{
HAL_SPI_IRQHandler(&hspi5);
}
spi.c
/* SPI5 init function */
void MX_SPI5_Init(void)
{
hspi5.Instance = SPI5;
hspi5.Init.Mode = SPI_MODE_SLAVE;
hspi5.Init.Direction = SPI_DIRECTION_2LINES;
hspi5.Init.DataSize = SPI_DATASIZE_8BIT;
hspi5.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi5.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi5.Init.NSS = SPI_NSS_HARD_INPUT;
hspi5.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi5.Init.TIMode = SPI_TIMODE_DISABLE;
hspi5.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi5.Init.CRCPolynomial = 15;
if (HAL_SPI_Init(&hspi5) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
[...]
HAL_NVIC_SetPriority(SPI5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SPI5_IRQn);
}
This working fine with my test code on the other (raspberry pi) side, sending a SPI frame every second, waiting 100ms and reading the answer from the F410.
Now, when I activate FreeRTOS, I move the while(1) loop content to a task, and creates it with
BaseType_t task1 = xTaskCreate(task_1, "task_1", 512, NULL, tskIDLE_PRIORITY, &xHandle);
and osKernelStart(). I also use the TIM11 as Timebase Source (under SYS tab on CubeMX as advised by the software itself)
Then I have the following behavior: If I place breakpoints inside both Tx/Rx SPI interrupt, I found that a couple (3-4 ?) of them are fired, then never again. If I stop my code I see I'm stucked in the
while (rx_done == 0) {};
loop, confirming that I don't get SPI RX interrupts anymore whereas there is still frame coming on the SPI bus.
To dig a little into that theory, I made another test with this in my task:
while(1) {
memset(buf, 0, 16);
HAL_StatusTypeDef ret = HAL_SPI_Receive_IT(&hspi5, (uint8_t*)&buf, 16);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
// Wait for RX interrupt, task is suspended to give processing time to (incoming) others tasks
vTaskSuspend(NULL);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
}
and in my Rx interrupt, I simply call
xTaskResumeFromISR(task1Handle);
With this code, the first packet sent is read correctly by the STM32F4, and task print it on USART2 and suspend itself again. From then, (checked with a breakpoint inside), the Rx interrupt is never called again, so the task resume inside neither, and my code is frozen...
It really looks like there is a messing between FreeRTOS and STM32 HAL SPI/interrupt handling ?
Any help will be gladly accepted !
Do you call NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); as described in the red text on this page: https://www.freertos.org/RTOS-Cortex-M3-M4.html ?
If you are using an STM32 with the STM32 driver library then ensure all the priority bits are assigned to be preempt priority bits by calling NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 ); before the RTOS is started.

stm32 DMA cannot send data to SPI1 DR (Cannot use DMA to send data to SPI)

I am trying to use DMA to send data to SPI1. SPI1 will then control DAC for voltage update.
The chip used is STM32F407. Therefore, the corresponding channel/stream is: channel3/stream5, as is shown in reference manual. However, when the DMA is enabled, no data is shown in SPI1->DR and there are no results shown in the oscilloscope.
The SPI works fine when SPI1->DR is written by software. Could anyone help to check out what has happened? Here comes the code:
uint16_t DACData[1];
void InitDMA(void)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_Cmd(DMA2_Stream2, DISABLE);
while (DMA2_Stream2->CR & DMA_SxCR_EN);
//SPI1 Tx DMA
DMA_DeInit(DMA2_Stream5);
DMA_StructInit(&DMA_InitStructure);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); //Init DMA clock
DMA_InitStructure.DMA_Channel = DMA_Channel_3;//SPI1 Tx
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(SPI1->DR); //Set the SPI1 Tx
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&DACData; //Set the memory location
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; //
DMA_InitStructure.DMA_BufferSize = 1; //Define the number of bytes to send
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; //Normal mode (not circular)
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; //Operate in 'direct mode'
DMA_InitStructure.DMA_MemoryBurst =DMA_MemoryBurst_Single;
DMA_InitStructure.DMA_PeripheralBurst =DMA_PeripheralBurst_Single;
DMA_Init(DMA2_Stream5, &DMA_InitStructure); //DMA2, Channel 3, stream 5
//Enable the transfer complete interrupt for DMA2 Stream5
DMA_ITConfig(DMA2_Stream5, DMA_IT_TC, ENABLE);
}
Here is how SPI1 initialized
void InitSPI1(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
SPI_InitTypeDef SPI_InitStruct;
// enable clock for used IO pins
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStruct);
// connect SPI1 pins to SPI alternate function
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); //SCK
GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_SPI1); //MISO
GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_SPI1); //MOSI
// enable peripheral clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
/* configure SPI1 in Mode 0
* CPOL = 0 --> clock is low when idle
* CPHA = 0 --> data is sampled at the first edge
*/
SPI_InitStruct.SPI_Direction = SPI_Direction_1Line_Tx; // one line transmission
SPI_InitStruct.SPI_Mode = SPI_Mode_Master; // transmit in master mode, NSS pin has to be always high
SPI_InitStruct.SPI_DataSize = SPI_DataSize_16b; // one packet of data is 16 bits wide
SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; // clock is low when idle
SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; // data sampled at first edge
SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;; // set the NSS management to hardware
SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; // SPI frequency is APB2 frequency / 4 = 21MHz
SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;// data is transmitted MSB first
SPI_Init(SPI1, &SPI_InitStruct);
SPI_Cmd(SPI1, ENABLE); // enable SPI1
}
I try to use these commands to start DMA:
DACData[0]=0xff00;
DMA_Cmd(DMA2_Stream5, ENABLE);
In case it may help, here comes the register values for DMA2, Stream 5
Such a line has been missed:
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx, ENABLE);
It enables SPI1 to use the DMA.
Just to add:
If you want to restart DMA, it seems you'll have to call not just:
DMA_Cmd(DMA2_Stream5, ENABLE);
but
DMA_ClearFlag(DMA1_Stream5, DMA_FLAG_TCIF5);
as well. Even though I didn't enable interrupts it seems this is still required.
Based on a quick look, the first thing that stands out is that you try to use parts of the DMA peripheral before enabling it. Try moving the
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
call before
DMA_Cmd(DMA2_Stream2, DISABLE);
while (DMA2_Stream2->CR & DMA_SxCR_EN);
as it could be eg. getting stuck in the loop. (I'm not sure which way the bits get read if the peripheral is not enabled when reading its registers)
If that doesn't help, leave a comment and I can try looking at it a bit more closely later.
I had a problem but nothing on the internet could help me, my solution was to change this;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
Other than that, my code is almost simliar, I don't get why yours would work.

How to configure the STM32103 for CAN and remapping the pins to PB8 and PB9

I am trying to, at this stage, simply send a transmission using CAN on the STM32F103 V8T6. The chip is implemented on a board that was customized by my company. Looking at the schematic I see that the CAN Tx and Rx pins were remapped to PB9 (Tx) and PB8 (Rx). All that being said, I have been able to use LoopBack mode successfully (using the latest example from STM "V3.5.0") but have have NOT been able to get Normal mode working. Can someone please let me know if they see an obvious flaw in my initial configuration?! I have included only the code related to configuration and left out the transmission function call.
int main (void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannel = CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure CAN pin: RX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
// Remap2 is for PB8 and PB9
GPIO_PinRemapConfig(GPIO_Remap2_CAN1 , ENABLE);
}
Here is my transmit function
void CAN_TransmitMyMsg(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CanTxMsg TxMessage;
uint32_t i = 0;
uint8_t TransmitMailbox = 0;
uint8_t status = 0;
/* CAN register init */
CAN_DeInit(CANx);
CAN_StructInit(&CAN_InitStructure);
/* CAN cell init */
CAN_InitStructure.CAN_TTCM=DISABLE;
CAN_InitStructure.CAN_ABOM=DISABLE;
CAN_InitStructure.CAN_AWUM=DISABLE;
CAN_InitStructure.CAN_NART=DISABLE;
CAN_InitStructure.CAN_RFLM=DISABLE;
CAN_InitStructure.CAN_TXFP=DISABLE;
CAN_InitStructure.CAN_Mode=CAN_Mode_Normal;
/* Baudrate = 125kbps*/
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1=CAN_BS1_2tq;
CAN_InitStructure.CAN_BS2=CAN_BS2_3tq;
CAN_InitStructure.CAN_Prescaler=48;
CAN_Init(CANx, &CAN_InitStructure);
/* CAN filter init */
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
/* transmit */
TxMessage.StdId=0x11;
TxMessage.RTR=CAN_RTR_DATA;
TxMessage.IDE=CAN_ID_STD;
TxMessage.DLC=2;
TxMessage.Data[0]=0xCA;
TxMessage.Data[1]=0xFE;
TransmitMailbox=CAN_Transmit(CANx, &TxMessage);
//wait until CAN transmission is OK
i = 0;
while((status != CANTXOK) && (i != 0xFFFF))
{
status = CAN_TransmitStatus(CANx, TransmitMailbox);
i++;
}
}
This resource has been helpful, but ultimately insufficient.
STM32F103 microcontroller CAN messages
Thanks!
Daniel
I had similar problems. My problem was in bad selection of comm parameters (timequantums and prescaler)
I debug it in this way:
I checked, that RSS pin of CAN transceiver (I used MCP 2551 I/P)
I switched it to loopback and with osciloscope check output signal on TX channel and on CANH to CANL (if the output is configured properly)
I looked to RCC configuration - the prescaler of APB1 clock has been changed to 2 (I excepted 4)
For a successful transmission, the CAN controller expects an 'acknowledge' bit which is part of the CAN protocol. If your CAN monitor (by NI) is in listen mode, there will not be an acknowledge-bit(!), and thus you don't get an indication of a successfull transmission at the sending end.
GPIO_Remap2_CAN1 remaps the CAN1 peripheral to PD0 and PD1, not PB8 and PB9. You want GPIO_Remap1_CAN1.
STD peripheral library is deprecated, but since I couldn't find any better examples, I used your not working code as a base.
Initially, I had the same behavior that it worked only in loopback.
After removing remapping to pins PB8 and PB9 and setting high speed GPIO for TX pin it started working. Here are my GPIO settings for PA11 and PA12
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* Configure CAN pin: RX */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* Configure CAN pin: TX */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = **GPIO_Speed_50MHz**;
GPIO_Init(GPIOA, &GPIO_InitStructure);
The rest I kept the same. (Except changing CANx to CAN1).