Recreate project for CubeMX/STM32forVSCode

This commit is contained in:
jazzpi
2022-06-09 16:33:57 +02:00
commit 6defd164b9
101 changed files with 110273 additions and 0 deletions

114
Core/Src/AMS_CAN.c Normal file
View File

@ -0,0 +1,114 @@
/*
* AMS_CAN.c
*
* Created on: Mar 19, 2022
* Author: jasper
*/
#include "AMS_CAN.h"
#include "BQ_Abstraction_Layer.h"
#include "TMP144.h"
static CAN_HandleTypeDef* handle_ams;
static CAN_HandleTypeDef* handle_car;
void ams_can_init(CAN_HandleTypeDef* ams_handle,
CAN_HandleTypeDef* car_handle) {
handle_ams = ams_handle;
handle_car = car_handle;
// Configure filters
CAN_FilterTypeDef filter_car;
filter_car.FilterBank = 14;
filter_car.FilterMode = CAN_FILTERMODE_IDMASK;
filter_car.FilterScale = CAN_FILTERSCALE_32BIT;
filter_car.FilterIdHigh = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE >> 16;
filter_car.FilterIdLow = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE & 0xFFFF;
filter_car.FilterMaskIdHigh = 0xFFFF;
filter_car.FilterMaskIdLow = 0xFF00;
filter_car.FilterFIFOAssignment = CAN_RX_FIFO0;
filter_car.FilterActivation = ENABLE;
filter_car.SlaveStartFilterBank = 14;
if (HAL_CAN_ConfigFilter(handle_car, &filter_car) != HAL_OK) {
Error_Handler();
}
// Start peripheral
if (HAL_CAN_Start(handle_ams) != HAL_OK) {
Error_Handler();
}
if (HAL_CAN_Start(handle_car) != HAL_OK) {
Error_Handler();
}
// Activate RX notifications
if (HAL_CAN_ActivateNotification(handle_ams, CAN_IT_RX_FIFO0_MSG_PENDING) !=
HAL_OK) {
Error_Handler();
}
if (HAL_CAN_ActivateNotification(handle_car,
CAN_IT_RX_FIFO0_MSG_PENDING | CAN_IT_ERROR |
CAN_IT_LAST_ERROR_CODE) != HAL_OK) {
Error_Handler();
}
}
static int cb_triggered = 0;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef* handle) {
static CAN_RxHeaderTypeDef header;
static uint8_t data[8];
cb_triggered = 1;
if (HAL_CAN_GetRxMessage(handle, CAN_RX_FIFO0, &header, data) != HAL_OK) {
Error_Handler();
}
if (handle == handle_ams) {
ams_can_handle_ams_msg(&header, data);
} else if (handle == handle_car) {
ams_can_handle_car_msg(&header, data);
} else {
Error_Handler();
}
}
void ams_can_handle_ams_msg(CAN_RxHeaderTypeDef* header, uint8_t* data) {}
void ams_can_handle_car_msg(CAN_RxHeaderTypeDef* header, uint8_t* data) {}
void ams_can_send_heartbeat() {
static CAN_TxHeaderTypeDef header;
static uint8_t data[8];
static uint8_t SLAVE_ID = 0;
header.IDE = CAN_ID_STD;
header.DLC = 8;
header.RTR = CAN_RTR_DATA;
header.TransmitGlobalTime = DISABLE;
for (int i = 0; i < N_CELLS / 2; i++) {
header.StdId = CAN_ID_AMS_SLAVE_HEARTBEAT_BASE | (SLAVE_ID) << 4 | i;
uint16_t v1 = cell_voltages[i * 2];
uint16_t v2 = cell_voltages[i * 2 + 1];
data[0] = v1 >> 8;
data[1] = v1 & 0xFF;
data[2] = v2 >> 8;
data[3] = v2 & 0xFF;
uint16_t t1 = temperatures[i * 2];
uint16_t t2 = temperatures[i * 2 + 1];
data[4] = t1 >> 8;
data[5] = t1 & 0xFF;
data[6] = t2 >> 8;
data[7] = t2 & 0xFF;
uint32_t mailbox;
HAL_StatusTypeDef status;
if ((status = HAL_CAN_AddTxMessage(handle_ams, &header, data, &mailbox)) !=
HAL_OK) {
Error_Handler();
} else {
HAL_Delay(100);
}
}
}

View File

@ -0,0 +1,143 @@
/*
* BQ_Abstraction_Layer.c
*
* Created on: 29.01.2022
* Author: max
*/
#include "BQ_Abstraction_Layer.h"
#include "BQ_Communication.h"
#include "BQ_Register_Definitions.h"
#include "stm32f4xx_hal.h"
uint16_t cell_voltages[N_CELLS];
uint8_t bq_status;
uint32_t lastmeasurementtime;
void afe_init(UART_HandleTypeDef* uarthandle) {
// Initialise underlying BQ Communication Functions
init_BQCom(uarthandle);
// Turn the AFE on off on to cycle a full reset
afe_wakeup();
HAL_Delay(10);
afe_shutdown();
HAL_Delay(100);
afe_wakeup();
HAL_Delay(10);
bq_status = BQ_INIT_PHASE;
afe_config_communication();
afe_config_measurement_channels();
afe_config_gpios();
afe_activate_LED();
afe_init_fault_thresholds();
HAL_Delay(1000);
afe_update_Checksum();
afe_clear_all_faults();
HAL_Delay(10);
afe_check_faults();
}
void afe_shutdown() { BQ_Write_Register(DEV_CNTRL, DEV_CNTRL_SIZE, 0x40); }
void afe_wakeup() {
HAL_GPIO_WritePin(WAKEUP_PORT, WAKEUP_PIN, GPIO_PIN_SET);
HAL_Delay(1);
HAL_GPIO_WritePin(WAKEUP_PORT, WAKEUP_PIN, GPIO_PIN_RESET);
}
void afe_measure() {
uint8_t cellvoltagebuffer[2 * N_CELLS];
uint8_t retval = BQ_ReadMeasurements(cellvoltagebuffer, 2 * N_CELLS);
lastmeasurementtime = HAL_GetTick();
if (retval == 0) {
bq_status = BQ_ERROR;
} else {
for (int n = 0; n < N_CELLS; n++) {
cell_voltages[N_CELLS - 1 - n] =
(uint16_t)(cellvoltagebuffer[2 * n] << 8) +
(uint16_t)cellvoltagebuffer[2 * n + 1];
}
}
}
void afe_selftest() {}
void afe_check_faults() {
uint32_t faultflags = 0;
BQ_Read_Register(FAULT_SUM, FAULT_SUM_SIZE, &faultflags);
if (faultflags != 0) {
bq_status = BQ_ERROR;
}
}
void afe_clear_all_faults() {
BQ_Write_Register(FAULT_SUM, FAULT_SUM_SIZE, 0xFFC0); // Clear all Faults
bq_status = BQ_STDBY;
HAL_Delay(1);
afe_check_faults();
if (bq_status == BQ_STDBY) {
bq_status = BQ_RDY;
}
}
void afe_init_fault_thresholds() {
BQ_Write_Register(FO_CTRL, FO_CTRL_SIZE,
0xC3C0); // Include UV Fault OV Fault COMM SYS CHIP GPI
// Faults to Fault Output
BQ_Write_Register(CELL_UV, CELL_UV_SIZE, (CELL_UV_THRESHOLD & 0x03));
BQ_Write_Register(CELL_OV, CELL_OV_SIZE, (CELL_OV_THRESHOLD & 0x03));
}
void afe_update_Checksum() {
uint32_t checksum = 0;
BQ_Read_Register(CSUM_RSLT, CSUM_RSLT_SIZE, &checksum);
BQ_Write_Register(CSUM, CSUM_SIZE, checksum);
}
void afe_config_measurement_channels() {
uint16_t cellmask = 0b1111111111;
uint32_t channelmask = cellmask << 16;
BQ_Write_Register(NCHAN, NCHAN_SIZE, N_CELLS);
uint32_t channels = 0b1111111111 << 16;
BQ_Write_Register(CHANNELS, CHANNELS_SIZE, channels);
BQ_Write_Register(OVERSMPL, OVERSMPL_SIZE,
0xFA); // Oversampling enabled with 4 samples as average
}
void afe_config_communication() {
BQ_Write_Register(
COMCONFIG, COMCONFIG_SIZE,
(1 << 12) |
(1 << 7)); // Enables UART Transceiver Diables Differential UART
}
void afe_config_gpios() { BQ_Write_Register(GPIO_DIR, GPIO_DIR_SIZE, 0x01); }
void afe_activate_LED() { BQ_Write_Register(GPIO_OUT, GPIO_OUT_SIZE, 0x01); }
void afe_config_balancing() {
BQ_Write_Register(CBCONFIG, CBCONFIG_SIZE, 0x10);
}
void afe_balance_channels(uint16_t channelstobalance) {
BQ_Write_Register(CBENBL, CBENBL_SIZE, channelstobalance);
}

239
Core/Src/BQ_Communication.c Normal file
View File

@ -0,0 +1,239 @@
#include "BQ_Communication.h"
#include "String.h"
#include <stdlib.h>
UART_HandleTypeDef* bq_uart;
DMA_HandleTypeDef* bq_dma;
uint8_t numofcells = DEFAULTNUMOFCELLS;
uint8_t numofdietemps = DEFAULTNUMOFDIETEMPS;
const uint16_t crc16_table[256] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 0xC601,
0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 0xCC01, 0x0CC0,
0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 0x0A00, 0xCAC1, 0xCB81,
0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 0xD801, 0x18C0, 0x1980, 0xD941,
0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01,
0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0,
0x1680, 0xD641, 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081,
0x1040, 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 0x3C00,
0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 0xFA01, 0x3AC0,
0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 0x2800, 0xE8C1, 0xE981,
0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 0xEE01, 0x2EC0, 0x2F80, 0xEF41,
0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700,
0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0,
0x2080, 0xE041, 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281,
0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 0xAA01,
0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 0x7800, 0xB8C1,
0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 0xBE01, 0x7EC0, 0x7F80,
0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 0xB401, 0x74C0, 0x7580, 0xB541,
0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101,
0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0,
0x5280, 0x9241, 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481,
0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 0x8801,
0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 0x4E00, 0x8EC1,
0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 0x4400, 0x84C1, 0x8581,
0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 0x8201, 0x42C0, 0x4380, 0x8341,
0x4100, 0x81C1, 0x8081, 0x4040};
/* Defines UART and DMA Handle
* Always use the Init Routine before using any other function of the Libary
*
*
*/
void init_BQCom(UART_HandleTypeDef* uarthandle) { bq_uart = uarthandle; }
/* Input Message Buffer with the Last two Bytes set to 0. The Last Bytes will be
* the CRC after use of the Function
*
* Returns 0 if the buffer is to small
*
* Returns 1 if the Function was successfull
*
*/
uint16_t Calculate_CRC(uint8_t* message_buffer, uint16_t bufferlength) {
uint16_t wCRC = 0;
if (bufferlength < 3) {
return 0;
}
for (uint32_t i = 0; i < (bufferlength - 2); i++) {
wCRC ^= (message_buffer[i]) & 0x00FF;
wCRC = crc16_table[wCRC & 0x00FF] ^ (wCRC >> 8);
}
message_buffer[bufferlength - 1] =
(wCRC >> 8) & 0xFF; // Upper CRC Byte is LSB of CRC
message_buffer[bufferlength - 2] = (wCRC)&0xFF; // Lower CRC Byte is MSB of
// CRC
return 1;
}
/*Checks if the CRC is correct
*
* Returns 0 if the Buffer is too small or the CRC is incorrect
*
* Returns 1 if the CRC is correct
*/
uint16_t Check_CRC(uint8_t* message_buffer, uint16_t bufferlength) {
uint16_t wCRC = 0;
if (bufferlength < 3) {
return 0;
}
for (uint32_t i = 0; i < bufferlength; i++) {
wCRC ^= (message_buffer[i]) & 0x00FF;
wCRC = crc16_table[wCRC & 0x00FF] ^ (wCRC >> 8);
}
message_buffer[bufferlength - 1] =
(wCRC >> 8) & 0xFF; // Upper CRC Byte is LSB of CRC
message_buffer[bufferlength - 2] = (wCRC)&0xFF; // Lower CRC Byte is MSB of
// CRC
if ((message_buffer[bufferlength - 1] == 0) &&
(message_buffer[bufferlength - 2] == 0)) {
return 1;
} else {
return 0;
}
}
/* Writes data to a register of the BQ76
*
* registeraddress specifies the register
* Makros are available in BQ_Register_Definitions.h
*
* registersize defines the register size in bytes
*
* data defines the data written to the BQ
*
*/
uint32_t BQ_Write_Register(uint8_t registeraddress, uint8_t registersize,
uint32_t data) {
uint8_t* message = (uint8_t*)calloc(registersize + 5, sizeof(uint8_t));
message[0] = FRM_WRT_NR | (registersize & 0x07);
message[1] = 0x00;
message[2] = registeraddress;
for (int i = 0; i < registersize; i++) {
int shift_amount = 8 * (registersize - i - 1);
message[3 + i] = (data >> shift_amount) & 0xFF;
}
Calculate_CRC(message, registersize + 5);
BQ_UART_Transmit(message, registersize + 5);
free(message);
return 1;
}
/*Read the Data of a Register specified by its Address
*
* Makros for register names are available in BQ_Register_Definitions.h
*
* registersize defines the register size in bytes
*/
uint8_t BQ_Read_Register(uint8_t registeraddress, uint8_t registersize,
uint32_t* data) {
uint8_t message[6] = {0};
message[0] = FRM_WRT_R;
message[1] = 0;
message[2] = registeraddress;
message[3] = registersize - 1;
Calculate_CRC(message, 6);
BQ_UART_Transmit(message, 6);
uint8_t* recv_message = (uint8_t*)calloc(registersize + 3, sizeof(uint8_t));
BQ_UART_Receive(recv_message, registersize + 3);
uint16_t crccheck = Check_CRC(recv_message, registersize + 3);
if (crccheck == 0) {
free(recv_message);
return 0;
}
data[0] = 0;
if (registersize > 4)
registersize = 4;
for (int n = 0; n < registersize; n++) {
data[0] |= recv_message[1 + n] >> (8 * n);
}
free(recv_message);
return 1;
}
/*Reads Voltage Measurements from the BQ76
*
* Result are Written into the Buffer
* Buffer size should be 2xMeasured Voltages
*
*/
uint32_t BQ_ReadMeasurements(uint8_t* buffer, uint8_t bufferlength) {
uint8_t message[6] = {};
message[0] = FRM_WRT_R;
message[1] = 0x00;
message[2] = 0x02;
message[3] = 0x00;
Calculate_CRC(message, 6);
BQ_UART_Transmit(message, 6);
uint16_t recv_len = 2 * (numofcells + numofdietemps) + 3;
uint8_t* recv_buf = (uint8_t*)calloc(recv_len, sizeof(uint8_t));
uint8_t uartstat = BQ_UART_Receive(recv_buf, recv_len);
if (Check_CRC(recv_buf, recv_len) == 0) {
free(recv_buf);
return 0;
}
if (bufferlength <= 2 * (numofcells + numofdietemps)) {
memcpy(buffer, &recv_buf[1], bufferlength);
}
free(recv_buf);
return 1;
}
/* Hardware Layer Implementation of the UART Transmit
*
*/
uint8_t BQ_UART_Transmit(uint8_t* message_buffer, uint16_t bufferlength) {
HAL_StatusTypeDef uartstate =
HAL_UART_Transmit(bq_uart, message_buffer, bufferlength, BQUARTTIMEOUT);
return (uint8_t)uartstate;
}
/* Hardware Layer Implementation of the UART Receive
*
*/
uint8_t BQ_UART_Receive(uint8_t* message_buffer, uint16_t bufferlength) {
HAL_StatusTypeDef uartstate =
HAL_UART_Receive(bq_uart, message_buffer, bufferlength, BQUARTTIMEOUT);
return (uint8_t)uartstate;
}
/*Resets the Communication Interface of the BQ76
*
*
*/
uint8_t Communication_Reset() { return 0; }

View File

@ -0,0 +1,60 @@
/*
* BatteryManagement.c
*
* Created on: 29.01.2022
* Author: max
*/
#include "BatteryManagement.h"
#include "BQ_Abstraction_Layer.h"
extern uint16_t cell_voltages[N_CELLS];
void ams_init(UART_HandleTypeDef* uarthandle, DMA_HandleTypeDef* uartdma) {
afe_init(uarthandle);
}
void ams_loop_discharging() {
afe_measure();
if (bq_status == BQ_ERROR) {
ams_status = AMS_TIMEOUT_ERROR;
} else {
ams_check_cell_voltages();
}
}
void ams_loop_charging() {}
void ams_check_cell_voltages() {
modulesumvoltage = 0;
highestcell = 0;
lowestcell = 0;
uint16_t lowestvoltage = cell_voltages[0];
uint16_t highestvoltage = cell_voltages[0];
for (int n = 0; n < N_CELLS; n++) {
modulesumvoltage += cell_voltages[n];
if (cell_voltages[n] > highestvoltage)
highestvoltage = cell_voltages[n];
if (cell_voltages[n] < lowestvoltage)
lowestvoltage = cell_voltages[n];
if (cell_voltages[n] > OVERVOLTAGE_LIMIT)
ams_status = AMS_OV_ERROR;
if (cell_voltages[n] < UNDERVOLTAGE_LIMIT)
ams_status = AMS_UV_ERROR;
}
}
void ams_check_cell_temperaures() {}
void ams_step_soc_model() {}
void ams_step_balancing_model() {}
void ams_fan_control() {}

129
Core/Src/SoftI2C.c Normal file
View File

@ -0,0 +1,129 @@
#include "SoftI2C.h"
#include "stm32f4xx_hal.h"
void Soft_I2C_Init() {}
void Soft_I2C_Transmit(uint8_t address, uint8_t* databuffer,
uint8_t bufferlength) {
uint8_t nack = 0;
setSDCLK(); // Generate Start Condition
bitwait();
setSDA(0);
bitwait();
for (int i = 0; i < 8; i++) // Write I2C-Slave Address
{
setSDA((address >> (7 - i) & 0x01));
bitwait();
resetSDCLK();
bitwait();
setSDCLK();
bitwait();
}
SDA_ReadMode();
resetSDCLK();
bitwait();
nack += readSDA();
bitwait();
SDA_WriteMode();
setSDA(0);
setSDCLK();
bitwait();
for (int n = 0; n < bufferlength; n++) // Write Data
{
for (int i = 0; i < 8; i++) {
setSDA((databuffer[n] >> (7 - i) & 0x01));
bitwait();
resetSDCLK();
bitwait();
setSDCLK();
bitwait();
}
SDA_ReadMode();
resetSDCLK();
bitwait();
nack += readSDA();
bitwait();
SDA_WriteMode();
setSDA(0);
setSDCLK();
bitwait();
}
resetSDCLK(); // Generate Stop Condition
bitwait();
setSDA(1);
bitwait();
}
void Soft_I2C_Receive(uint8_t address, uint8_t* databuffer,
uint8_t bufferlength) {
uint8_t nack = 0;
setSDCLK(); // Generate Start Condition
bitwait();
setSDA(0);
bitwait();
for (int i = 0; i < 8; i++) // Write I2C-Slave Address
{
setSDA((address >> (7 - i) & 0x01));
bitwait();
resetSDCLK();
bitwait();
setSDCLK();
bitwait();
}
SDA_ReadMode();
resetSDCLK();
bitwait();
nack += readSDA();
bitwait();
for (int n = 0; n < bufferlength; n++) {
databuffer[n] = 0;
for (int i = 0; i < 8; i++) {
setSDCLK();
bitwait();
resetSDCLK();
bitwait();
databuffer[n] |= readSDA() << (7 - i);
bitwait();
}
setSDCLK();
bitwait();
SDA_WriteMode();
setSDA(0);
bitwait();
resetSDCLK();
bitwait();
SDA_ReadMode();
}
resetSDCLK(); // Generate Stop Condition
bitwait();
setSDA(1);
bitwait();
}
void SDA_WriteMode() {}
void SDA_ReadMode() {}
void setSDA(uint8_t state) {}
uint8_t readSDA() {}
void bitwait() {}
void setSDCLK() {}
void resetSDCLK() {}

210
Core/Src/TMP144.c Normal file
View File

@ -0,0 +1,210 @@
/*
* TMP144.c
*
* Created on: 23 Mar 2022
* Author: Jasper
*/
#include "TMP144.h"
#include "string.h"
static const uint8_t TMP144_SEQ_RESET[] = {0x55, 0xB4};
static const uint8_t TMP144_SEQ_ADDR[] = {0x55, 0x8C, 0x90};
static const uint8_t TMP144_SEQ_READ_TEMPS[] = {0x55, 0xF1};
volatile uint16_t temperatures[N_CELLS];
static volatile TMP144Bus bus_busbar;
static volatile TMP144Bus bus_other;
#define CHECK_STATUS(s) \
{ \
HAL_StatusTypeDef _s = s; \
if (_s != HAL_OK) \
return _s; \
}
HAL_StatusTypeDef tmp144_init(UART_HandleTypeDef* busbar_side,
UART_HandleTypeDef* other_side) {
bus_busbar.handle = busbar_side;
bus_other.handle = other_side;
bus_busbar.state = TMP144_IDLE;
bus_other.state = TMP144_IDLE;
// TODO: Configure this in EEPROM
bus_busbar.n_sensors = 11;
bus_busbar.sensor_mappings[0] = 8;
bus_busbar.sensor_mappings[1] = 8;
bus_busbar.sensor_mappings[2] = 8;
bus_busbar.sensor_mappings[3] = 6;
bus_busbar.sensor_mappings[4] = 6;
bus_busbar.sensor_mappings[5] = 4;
bus_busbar.sensor_mappings[6] = 4;
bus_busbar.sensor_mappings[7] = 4;
bus_busbar.sensor_mappings[8] = 2;
bus_busbar.sensor_mappings[9] = 2;
bus_busbar.sensor_mappings[10] = 2;
bus_other.n_sensors = 13;
bus_other.sensor_mappings[0] = 1;
bus_other.sensor_mappings[1] = 1;
bus_other.sensor_mappings[2] = 1;
bus_other.sensor_mappings[3] = 3;
bus_other.sensor_mappings[4] = 3;
bus_other.sensor_mappings[5] = 5;
bus_other.sensor_mappings[6] = 5;
bus_other.sensor_mappings[7] = 5;
bus_other.sensor_mappings[8] = 5;
bus_other.sensor_mappings[9] = 7;
bus_other.sensor_mappings[10] = 7;
bus_other.sensor_mappings[11] = 9;
bus_other.sensor_mappings[12] = 9;
CHECK_STATUS(tmp144_init_reset(&bus_busbar));
CHECK_STATUS(tmp144_init_reset(&bus_other));
return HAL_OK;
}
HAL_StatusTypeDef tmp144_init_reset(TMP144Bus* bus) {
if (bus->state != TMP144_IDLE) {
return HAL_ERROR;
}
bus->state = TMP144_RESETTING;
CHECK_STATUS(HAL_UART_Receive_IT(bus->handle, bus->rxbuf, 2));
// Keep sending Global Software Reset until it echoes back (as per 7.5.2)
int tries = 0;
do {
if (tries > 10) {
return HAL_TIMEOUT;
}
CHECK_STATUS(HAL_UART_Transmit(bus->handle, TMP144_SEQ_RESET,
sizeof(TMP144_SEQ_RESET), 100));
HAL_Delay(100);
tries++;
} while (bus->state == TMP144_RESETTING);
bus->state = TMP144_INITIALIZING;
CHECK_STATUS(HAL_UART_Receive_IT(bus->handle, bus->rxbuf, 3));
CHECK_STATUS(HAL_UART_Transmit(bus->handle, TMP144_SEQ_ADDR,
sizeof(TMP144_SEQ_ADDR), 100));
return HAL_OK;
}
HAL_StatusTypeDef tmp144_init_post_reset(TMP144Bus* bus) {
if (bus->state != TMP144_RESETTING ||
memcmp(bus->rxbuf, TMP144_SEQ_RESET, sizeof(TMP144_SEQ_RESET)) != 0) {
return HAL_ERROR;
}
bus->state = TMP144_IDLE;
return HAL_OK;
}
HAL_StatusTypeDef tmp144_init_post_addr(TMP144Bus* bus) {
size_t idx_response = sizeof(TMP144_SEQ_ADDR) - 1;
if (bus->state != TMP144_INITIALIZING ||
memcmp(bus->rxbuf, TMP144_SEQ_ADDR, idx_response) != 0) {
return HAL_ERROR;
}
uint8_t n_sensors = bus->rxbuf[idx_response] - TMP144_SEQ_ADDR[idx_response];
if (n_sensors != bus->n_sensors) {
return HAL_ERROR;
}
bus->state = TMP144_IDLE;
return HAL_OK;
}
HAL_StatusTypeDef tmp144_read_temps() {
CHECK_STATUS(tmp144_send_read_temps(&bus_busbar));
CHECK_STATUS(tmp144_send_read_temps(&bus_other));
return HAL_OK;
}
HAL_StatusTypeDef tmp144_send_read_temps(TMP144Bus* bus) {
if (bus->state != TMP144_IDLE) {
return HAL_ERROR;
}
bus->state = TMP144_READING_TEMP;
// HAL_UART_Receive_IT(bus->handle, bus->rxbuf,
// sizeof(TMP144_SEQ_READ_TEMPS) + 2 * bus->n_sensors);
CHECK_STATUS(
HAL_UART_Receive_IT(bus->handle, bus->rxbuf,
sizeof(TMP144_SEQ_READ_TEMPS) + 2 * bus->n_sensors));
CHECK_STATUS(HAL_UART_Transmit(bus->handle, TMP144_SEQ_READ_TEMPS,
sizeof(TMP144_SEQ_READ_TEMPS), 100));
return HAL_OK;
}
HAL_StatusTypeDef tmp144_recv_temps(TMP144Bus* bus) {
if (bus->state != TMP144_READING_TEMP) {
return HAL_ERROR;
}
bus->state = TMP144_IDLE;
size_t headerlen = sizeof(TMP144_SEQ_READ_TEMPS);
if (memcmp(bus->rxbuf, TMP144_SEQ_READ_TEMPS, headerlen) != 0) {
return HAL_ERROR;
}
// Find max temperature for each cell
uint8_t current_cell = bus->sensor_mappings[0];
uint16_t max_temp = 0;
for (size_t i = 0; i < bus->n_sensors; i++) {
uint8_t cell = bus->sensor_mappings[i];
if (cell != current_cell) {
temperatures[current_cell] = max_temp;
current_cell = cell;
max_temp = 0;
}
size_t buf_offset = headerlen + 2 * i;
uint16_t temp =
(bus->rxbuf[buf_offset] >> 4) | (bus->rxbuf[buf_offset + 1] << 4);
if (temp > max_temp) {
max_temp = temp;
}
}
temperatures[current_cell] = max_temp;
return HAL_OK;
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef* handle) {
TMP144Bus* bus;
if (handle == bus_busbar.handle) {
bus = &bus_busbar;
} else if (handle == bus_other.handle) {
bus = &bus_other;
} else {
// TODO
Error_Handler();
}
switch (bus->state) {
case TMP144_IDLE:
// TODO
Error_Handler();
case TMP144_RESETTING:
tmp144_init_post_reset(bus);
break;
case TMP144_INITIALIZING:
tmp144_init_post_addr(bus);
break;
case TMP144_READING_TEMP:
tmp144_recv_temps(bus);
break;
default:
// TODO
Error_Handler();
}
}

463
Core/Src/main.c Normal file
View File

@ -0,0 +1,463 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
CAN_HandleTypeDef hcan1;
CAN_HandleTypeDef hcan2;
I2C_HandleTypeDef hi2c1;
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;
UART_HandleTypeDef huart6;
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_CAN1_Init(void);
static void MX_CAN2_Init(void);
static void MX_I2C1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_USART6_UART_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void) {
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick.
*/
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_CAN1_Init();
MX_CAN2_Init();
MX_I2C1_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init();
MX_USART6_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1) {
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @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_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(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.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_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
Error_Handler();
}
}
/**
* @brief CAN1 Initialization Function
* @param None
* @retval None
*/
static void MX_CAN1_Init(void) {
/* USER CODE BEGIN CAN1_Init 0 */
/* USER CODE END CAN1_Init 0 */
/* USER CODE BEGIN CAN1_Init 1 */
/* USER CODE END CAN1_Init 1 */
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 5;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan1.Init.TimeSeg1 = CAN_BS1_6TQ;
hcan1.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan1.Init.TimeTriggeredMode = DISABLE;
hcan1.Init.AutoBusOff = DISABLE;
hcan1.Init.AutoWakeUp = DISABLE;
hcan1.Init.AutoRetransmission = ENABLE;
hcan1.Init.ReceiveFifoLocked = DISABLE;
hcan1.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan1) != HAL_OK) {
Error_Handler();
}
/* USER CODE BEGIN CAN1_Init 2 */
/* USER CODE END CAN1_Init 2 */
}
/**
* @brief CAN2 Initialization Function
* @param None
* @retval None
*/
static void MX_CAN2_Init(void) {
/* USER CODE BEGIN CAN2_Init 0 */
/* USER CODE END CAN2_Init 0 */
/* USER CODE BEGIN CAN2_Init 1 */
/* USER CODE END CAN2_Init 1 */
hcan2.Instance = CAN2;
hcan2.Init.Prescaler = 5;
hcan2.Init.Mode = CAN_MODE_NORMAL;
hcan2.Init.SyncJumpWidth = CAN_SJW_1TQ;
hcan2.Init.TimeSeg1 = CAN_BS1_6TQ;
hcan2.Init.TimeSeg2 = CAN_BS2_2TQ;
hcan2.Init.TimeTriggeredMode = DISABLE;
hcan2.Init.AutoBusOff = DISABLE;
hcan2.Init.AutoWakeUp = DISABLE;
hcan2.Init.AutoRetransmission = DISABLE;
hcan2.Init.ReceiveFifoLocked = DISABLE;
hcan2.Init.TransmitFifoPriority = DISABLE;
if (HAL_CAN_Init(&hcan2) != HAL_OK) {
Error_Handler();
}
/* USER CODE BEGIN CAN2_Init 2 */
/* USER CODE END CAN2_Init 2 */
}
/**
* @brief I2C1 Initialization Function
* @param None
* @retval None
*/
static void MX_I2C1_Init(void) {
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK) {
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
/**
* @brief USART1 Initialization Function
* @param None
* @retval None
*/
static void MX_USART1_UART_Init(void) {
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK) {
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/**
* @brief USART2 Initialization Function
* @param None
* @retval None
*/
static void MX_USART2_UART_Init(void) {
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 250000;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK) {
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* @brief USART3 Initialization Function
* @param None
* @retval None
*/
static void MX_USART3_UART_Init(void) {
/* USER CODE BEGIN USART3_Init 0 */
/* USER CODE END USART3_Init 0 */
/* USER CODE BEGIN USART3_Init 1 */
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK) {
Error_Handler();
}
/* USER CODE BEGIN USART3_Init 2 */
/* USER CODE END USART3_Init 2 */
}
/**
* @brief USART6 Initialization Function
* @param None
* @retval None
*/
static void MX_USART6_UART_Init(void) {
/* USER CODE BEGIN USART6_Init 0 */
/* USER CODE END USART6_Init 0 */
/* USER CODE BEGIN USART6_Init 1 */
/* USER CODE END USART6_Init 1 */
huart6.Instance = USART6;
huart6.Init.BaudRate = 115200;
huart6.Init.WordLength = UART_WORDLENGTH_8B;
huart6.Init.StopBits = UART_STOPBITS_1;
huart6.Init.Parity = UART_PARITY_NONE;
huart6.Init.Mode = UART_MODE_TX_RX;
huart6.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart6.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart6) != HAL_OK) {
Error_Handler();
}
/* USER CODE BEGIN USART6_Init 2 */
/* USER CODE END USART6_Init 2 */
}
/**
* @brief GPIO Initialization Function
* @param None
* @retval None
*/
static void MX_GPIO_Init(void) {
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC,
STAT_LED1_Pin | STAT_LED2_Pin | STAT_LED3_Pin |
STAT_LED4_Pin | FAN_CONTROL_Pin,
GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB,
BQ_POWER_ACTIVATE_Pin | BQ_VIO_ACTICATE_Pin | BQ_Wakeup_Pin,
GPIO_PIN_RESET);
/*Configure GPIO pins : STAT_LED1_Pin STAT_LED2_Pin STAT_LED3_Pin
STAT_LED4_Pin FAN_CONTROL_Pin */
GPIO_InitStruct.Pin = STAT_LED1_Pin | STAT_LED2_Pin | STAT_LED3_Pin |
STAT_LED4_Pin | FAN_CONTROL_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : BQ_POWER_ACTIVATE_Pin BQ_VIO_ACTICATE_Pin
* BQ_Wakeup_Pin */
GPIO_InitStruct.Pin =
BQ_POWER_ACTIVATE_Pin | BQ_VIO_ACTICATE_Pin | BQ_Wakeup_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : PD2 */
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void) {
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1) {
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line) {
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line
number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file,
line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

View File

@ -0,0 +1,500 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_hal_msp.c
* @brief This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/* DebugMonitor_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DebugMonitor_IRQn, 1, 0);
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
static uint32_t HAL_RCC_CAN1_CLK_ENABLED=0;
/**
* @brief CAN MSP Initialization
* This function configures the hardware resources used in this example
* @param hcan: CAN handle pointer
* @retval None
*/
void HAL_CAN_MspInit(CAN_HandleTypeDef* hcan)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hcan->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspInit 0 */
/* USER CODE END CAN1_MspInit 0 */
/* Peripheral clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_GPIOA_CLK_ENABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* CAN1 interrupt Init */
HAL_NVIC_SetPriority(CAN1_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
/* USER CODE BEGIN CAN1_MspInit 1 */
/* USER CODE END CAN1_MspInit 1 */
}
else if(hcan->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspInit 0 */
/* USER CODE END CAN2_MspInit 0 */
/* Peripheral clock enable */
HAL_RCC_CAN1_CLK_ENABLED++;
if(HAL_RCC_CAN1_CLK_ENABLED==1){
__HAL_RCC_CAN1_CLK_ENABLE();
}
__HAL_RCC_CAN2_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**CAN2 GPIO Configuration
PB13 ------> CAN2_TX
PB5 ------> CAN2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_13|GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_CAN2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* CAN2 interrupt Init */
HAL_NVIC_SetPriority(CAN2_RX0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_RX0_IRQn);
HAL_NVIC_SetPriority(CAN2_RX1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_RX1_IRQn);
HAL_NVIC_SetPriority(CAN2_SCE_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(CAN2_SCE_IRQn);
/* USER CODE BEGIN CAN2_MspInit 1 */
/* USER CODE END CAN2_MspInit 1 */
}
}
/**
* @brief CAN MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hcan: CAN handle pointer
* @retval None
*/
void HAL_CAN_MspDeInit(CAN_HandleTypeDef* hcan)
{
if(hcan->Instance==CAN1)
{
/* USER CODE BEGIN CAN1_MspDeInit 0 */
/* USER CODE END CAN1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_CAN1_CLK_DISABLE();
/**CAN1 GPIO Configuration
PA11 ------> CAN1_RX
PA12 ------> CAN1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* CAN1 interrupt DeInit */
HAL_NVIC_DisableIRQ(CAN1_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN1_RX1_IRQn);
/* USER CODE BEGIN CAN1_MspDeInit 1 */
/* USER CODE END CAN1_MspDeInit 1 */
}
else if(hcan->Instance==CAN2)
{
/* USER CODE BEGIN CAN2_MspDeInit 0 */
/* USER CODE END CAN2_MspDeInit 0 */
/* Peripheral clock disable */
HAL_RCC_CAN1_CLK_ENABLED--;
if(HAL_RCC_CAN1_CLK_ENABLED==0){
__HAL_RCC_CAN1_CLK_DISABLE();
}
__HAL_RCC_CAN2_CLK_DISABLE();
/**CAN2 GPIO Configuration
PB13 ------> CAN2_TX
PB5 ------> CAN2_RX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_13|GPIO_PIN_5);
/* CAN2 interrupt DeInit */
HAL_NVIC_DisableIRQ(CAN2_RX0_IRQn);
HAL_NVIC_DisableIRQ(CAN2_RX1_IRQn);
HAL_NVIC_DisableIRQ(CAN2_SCE_IRQn);
/* USER CODE BEGIN CAN2_MspDeInit 1 */
/* USER CODE END CAN2_MspDeInit 1 */
}
}
/**
* @brief I2C MSP Initialization
* This function configures the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
/**
* @brief I2C MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hi2c: I2C handle pointer
* @retval None
*/
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* hi2c)
{
if(hi2c->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspDeInit 0 */
/* USER CODE END I2C1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C1_CLK_DISABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
/* USER CODE BEGIN I2C1_MspDeInit 1 */
/* USER CODE END I2C1_MspDeInit 1 */
}
}
/**
* @brief UART MSP Initialization
* This function configures the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(huart->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA10 ------> USART1_RX
PA15 ------> USART1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
else if(huart->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspInit 0 */
/* USER CODE END USART3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART3 GPIO Configuration
PC5 ------> USART3_RX
PB10 ------> USART3_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USART3 interrupt Init */
HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspInit 1 */
/* USER CODE END USART3_MspInit 1 */
}
else if(huart->Instance==USART6)
{
/* USER CODE BEGIN USART6_MspInit 0 */
/* USER CODE END USART6_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART6_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PC7 ------> USART6_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_USART6;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USER CODE BEGIN USART6_MspInit 1 */
/* USER CODE END USART6_MspInit 1 */
}
}
/**
* @brief UART MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param huart: UART handle pointer
* @retval None
*/
void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)
{
if(huart->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA10 ------> USART1_RX
PA15 ------> USART1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_10|GPIO_PIN_15);
/* USART1 interrupt DeInit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
else if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_2|GPIO_PIN_3);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
else if(huart->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspDeInit 0 */
/* USER CODE END USART3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART3_CLK_DISABLE();
/**USART3 GPIO Configuration
PC5 ------> USART3_RX
PB10 ------> USART3_TX
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_5);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10);
/* USART3 interrupt DeInit */
HAL_NVIC_DisableIRQ(USART3_IRQn);
/* USER CODE BEGIN USART3_MspDeInit 1 */
/* USER CODE END USART3_MspDeInit 1 */
}
else if(huart->Instance==USART6)
{
/* USER CODE BEGIN USART6_MspDeInit 0 */
/* USER CODE END USART6_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART6_CLK_DISABLE();
/**USART6 GPIO Configuration
PC6 ------> USART6_TX
PC7 ------> USART6_RX
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6|GPIO_PIN_7);
/* USER CODE BEGIN USART6_MspDeInit 1 */
/* USER CODE END USART6_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

303
Core/Src/stm32f4xx_it.c Normal file
View File

@ -0,0 +1,303 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* Copyright (c) 2022 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern CAN_HandleTypeDef hcan1;
extern CAN_HandleTypeDef hcan2;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart3;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1) {
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/**
* @brief This function handles CAN1 RX0 interrupts.
*/
void CAN1_RX0_IRQHandler(void)
{
/* USER CODE BEGIN CAN1_RX0_IRQn 0 */
/* USER CODE END CAN1_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan1);
/* USER CODE BEGIN CAN1_RX0_IRQn 1 */
/* USER CODE END CAN1_RX0_IRQn 1 */
}
/**
* @brief This function handles CAN1 RX1 interrupt.
*/
void CAN1_RX1_IRQHandler(void)
{
/* USER CODE BEGIN CAN1_RX1_IRQn 0 */
/* USER CODE END CAN1_RX1_IRQn 0 */
HAL_CAN_IRQHandler(&hcan1);
/* USER CODE BEGIN CAN1_RX1_IRQn 1 */
/* USER CODE END CAN1_RX1_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles USART3 global interrupt.
*/
void USART3_IRQHandler(void)
{
/* USER CODE BEGIN USART3_IRQn 0 */
/* USER CODE END USART3_IRQn 0 */
HAL_UART_IRQHandler(&huart3);
/* USER CODE BEGIN USART3_IRQn 1 */
/* USER CODE END USART3_IRQn 1 */
}
/**
* @brief This function handles CAN2 RX0 interrupts.
*/
void CAN2_RX0_IRQHandler(void)
{
/* USER CODE BEGIN CAN2_RX0_IRQn 0 */
/* USER CODE END CAN2_RX0_IRQn 0 */
HAL_CAN_IRQHandler(&hcan2);
/* USER CODE BEGIN CAN2_RX0_IRQn 1 */
/* USER CODE END CAN2_RX0_IRQn 1 */
}
/**
* @brief This function handles CAN2 RX1 interrupt.
*/
void CAN2_RX1_IRQHandler(void)
{
/* USER CODE BEGIN CAN2_RX1_IRQn 0 */
/* USER CODE END CAN2_RX1_IRQn 0 */
HAL_CAN_IRQHandler(&hcan2);
/* USER CODE BEGIN CAN2_RX1_IRQn 1 */
/* USER CODE END CAN2_RX1_IRQn 1 */
}
/**
* @brief This function handles CAN2 SCE interrupt.
*/
void CAN2_SCE_IRQHandler(void)
{
/* USER CODE BEGIN CAN2_SCE_IRQn 0 */
/* USER CODE END CAN2_SCE_IRQn 0 */
HAL_CAN_IRQHandler(&hcan2);
/* USER CODE BEGIN CAN2_SCE_IRQn 1 */
/* USER CODE END CAN2_SCE_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

762
Core/Src/system_stm32f4xx.c Normal file
View File

@ -0,0 +1,762 @@
/**
******************************************************************************
* @file system_stm32f4xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f4xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be
*used by the user application to setup the SysTick timer or configure other
*parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
*
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f4xx_system
* @{
*/
/** @addtogroup STM32F4xx_System_Private_Includes
* @{
*/
#include "stm32f4xx.h"
#if !defined(HSE_VALUE)
#define HSE_VALUE \
((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined(HSI_VALUE)
#define HSI_VALUE \
((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Defines
* @{
*/
/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to use external SRAM or SDRAM as
* data memory */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || \
defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || \
defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || \
defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
/* #define DATA_IN_ExtSRAM */
#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || \
STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || \
defined(STM32F439xx) || defined(STM32F446xx) || defined(STM32F469xx) || \
defined(STM32F479xx)
/* #define DATA_IN_ExtSDRAM */
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || \
STM32F446xx || STM32F469xx || STM32F479xx */
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS \
SRAM_BASE /*!< Vector Table base address field. \
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET \
0x00000000U /*!< Vector Table base offset field. \
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS \
FLASH_BASE /*!< Vector Table base address field. \
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET \
0x00000000U /*!< Vector Table base offset field. \
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Variables
* @{
*/
/* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock
frequency Note: If you use this function to configure the system clock; then
there is no need to call the 2 first functions listed above, since
SystemCoreClock variable is updated automatically.
*/
uint32_t SystemCoreClock = 16000000;
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0,
1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
* @{
*/
#if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
static void SystemInit_ExtMemCtl(void);
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system
* Initialize the FPU setting, vector table location and External memory
* configuration.
* @param None
* @retval None
*/
void SystemInit(void) {
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |=
((3UL << 10 * 2) | (3UL << 11 * 2)); /* set CP10 and CP11 Full Access */
#endif
#if defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS |
VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or
* configure other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any
* configuration based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the
* HSI_VALUE(*)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the
* HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the
* HSE_VALUE(**) or HSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file
* (default value 16 MHz) but the real value may vary depending on the
* variations in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file
* (its value depends on the application requirements), user has to ensure that
* HSE_VALUE is same as the real frequency of the crystal used. Otherwise, this
* function may have wrong result.
*
* - The result of this function could be not correct when using
* fractional value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void) {
uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp) {
case 0x00: /* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x04: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x08: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
SYSCLK = PLL_VCO / PLL_P
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
if (pllsource != 0) {
/* HSE used as PLL clock source */
pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
} else {
/* HSI used as PLL clock source */
pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
}
pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> 16) + 1) * 2;
SystemCoreClock = pllvco / pllp;
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
/* Compute HCLK frequency --------------------------------------------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK frequency */
SystemCoreClock >>= tmp;
}
#if defined(DATA_IN_ExtSRAM) && defined(DATA_IN_ExtSDRAM)
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || \
defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f4xx.s before jump to main.
* This function configures the external memories (SRAM/SDRAM)
* This SRAM/SDRAM will be used as program data memory (including heap
* and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void) {
__IO uint32_t tmp = 0x00;
register uint32_t tmpreg = 0, timeout = 0xFFFF;
register __IO uint32_t index;
/* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock
*/
RCC->AHB1ENR |= 0x000001F8;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x00CCC0CC;
GPIOD->AFR[1] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A8A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0FCF;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00CC0CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA828A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC3CF;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0xCCCCCCCC;
GPIOF->AFR[1] = 0xCCCCCCCC;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA800AAA;
/* Configure PFx pins speed to 50 MHz */
GPIOF->OSPEEDR = 0xAA800AAA;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0xCCCCCCCC;
GPIOG->AFR[1] = 0xCCCCCCCC;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0xAAAAAAAA;
/* Configure PGx pins speed to 50 MHz */
GPIOG->OSPEEDR = 0xAAAAAAAA;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/* Connect PHx pins to FMC Alternate function */
GPIOH->AFR[0] = 0x00C0CC00;
GPIOH->AFR[1] = 0xCCCCCCCC;
/* Configure PHx pins in Alternate function mode */
GPIOH->MODER = 0xAAAA08A0;
/* Configure PHx pins speed to 50 MHz */
GPIOH->OSPEEDR = 0xAAAA08A0;
/* Configure PHx pins Output type to push-pull */
GPIOH->OTYPER = 0x00000000;
/* No pull-up, pull-down for PHx pins */
GPIOH->PUPDR = 0x00000000;
/* Connect PIx pins to FMC Alternate function */
GPIOI->AFR[0] = 0xCCCCCCCC;
GPIOI->AFR[1] = 0x00000CC0;
/* Configure PIx pins in Alternate function mode */
GPIOI->MODER = 0x0028AAAA;
/* Configure PIx pins speed to 50 MHz */
GPIOI->OSPEEDR = 0x0028AAAA;
/* Configure PIx pins Output type to push-pull */
GPIOI->OTYPER = 0x00000000;
/* No pull-up, pull-down for PIx pins */
GPIOI->PUPDR = 0x00000000;
/*-- FMC Configuration
* -------------------------------------------------------*/
/* Enable the FMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
FMC_Bank5_6->SDCR[0] = 0x000019E4;
FMC_Bank5_6->SDTR[0] = 0x01115351;
/* SDRAM initialization sequence */
/* Clock enable command */
FMC_Bank5_6->SDCMR = 0x00000011;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
while ((tmpreg != 0) && (timeout-- > 0)) {
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Delay */
for (index = 0; index < 1000; index++)
;
/* PALL command */
FMC_Bank5_6->SDCMR = 0x00000012;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while ((tmpreg != 0) && (timeout-- > 0)) {
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Auto refresh command */
FMC_Bank5_6->SDCMR = 0x00000073;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while ((tmpreg != 0) && (timeout-- > 0)) {
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* MRD register program */
FMC_Bank5_6->SDCMR = 0x00046014;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while ((tmpreg != 0) && (timeout-- > 0)) {
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Set refresh count */
tmpreg = FMC_Bank5_6->SDRTR;
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C << 1));
/* Disable write protection */
tmpreg = FMC_Bank5_6->SDCR[0];
FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || \
defined(STM32F439xx)
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001011;
FMC_Bank1->BTCR[3] = 0x00000201;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
#if defined(STM32F469xx) || defined(STM32F479xx)
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001091;
FMC_Bank1->BTCR[3] = 0x00110212;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F469xx || STM32F479xx */
(void)(tmp);
}
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || \
STM32F469xx || STM32F479xx */
#elif defined(DATA_IN_ExtSRAM) || defined(DATA_IN_ExtSDRAM)
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f4xx.s before jump to main.
* This function configures the external memories (SRAM/SDRAM)
* This SRAM/SDRAM will be used as program data memory (including heap
* and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void) {
__IO uint32_t tmp = 0x00;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || \
defined(STM32F439xx) || defined(STM32F446xx) || defined(STM32F469xx) || \
defined(STM32F479xx)
#if defined(DATA_IN_ExtSDRAM)
register uint32_t tmpreg = 0, timeout = 0xFFFF;
register __IO uint32_t index;
#if defined(STM32F446xx)
/* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
clock */
RCC->AHB1ENR |= 0x0000007D;
#else
/* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
clock */
RCC->AHB1ENR |= 0x000001F8;
#endif /* STM32F446xx */
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
#if defined(STM32F446xx)
/* Connect PAx pins to FMC Alternate function */
GPIOA->AFR[0] |= 0xC0000000;
GPIOA->AFR[1] |= 0x00000000;
/* Configure PDx pins in Alternate function mode */
GPIOA->MODER |= 0x00008000;
/* Configure PDx pins speed to 50 MHz */
GPIOA->OSPEEDR |= 0x00008000;
/* Configure PDx pins Output type to push-pull */
GPIOA->OTYPER |= 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOA->PUPDR |= 0x00000000;
/* Connect PCx pins to FMC Alternate function */
GPIOC->AFR[0] |= 0x00CC0000;
GPIOC->AFR[1] |= 0x00000000;
/* Configure PDx pins in Alternate function mode */
GPIOC->MODER |= 0x00000A00;
/* Configure PDx pins speed to 50 MHz */
GPIOC->OSPEEDR |= 0x00000A00;
/* Configure PDx pins Output type to push-pull */
GPIOC->OTYPER |= 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOC->PUPDR |= 0x00000000;
#endif /* STM32F446xx */
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x000000CC;
GPIOD->AFR[1] = 0xCC000CCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xA02A000A;
/* Configure PDx pins speed to 50 MHz */
GPIOD->OSPEEDR = 0xA02A000A;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00000CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA800A;
/* Configure PEx pins speed to 50 MHz */
GPIOE->OSPEEDR = 0xAAAA800A;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0xCCCCCCCC;
GPIOF->AFR[1] = 0xCCCCCCCC;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA800AAA;
/* Configure PFx pins speed to 50 MHz */
GPIOF->OSPEEDR = 0xAA800AAA;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0xCCCCCCCC;
GPIOG->AFR[1] = 0xCCCCCCCC;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0xAAAAAAAA;
/* Configure PGx pins speed to 50 MHz */
GPIOG->OSPEEDR = 0xAAAAAAAA;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || \
defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx)
/* Connect PHx pins to FMC Alternate function */
GPIOH->AFR[0] = 0x00C0CC00;
GPIOH->AFR[1] = 0xCCCCCCCC;
/* Configure PHx pins in Alternate function mode */
GPIOH->MODER = 0xAAAA08A0;
/* Configure PHx pins speed to 50 MHz */
GPIOH->OSPEEDR = 0xAAAA08A0;
/* Configure PHx pins Output type to push-pull */
GPIOH->OTYPER = 0x00000000;
/* No pull-up, pull-down for PHx pins */
GPIOH->PUPDR = 0x00000000;
/* Connect PIx pins to FMC Alternate function */
GPIOI->AFR[0] = 0xCCCCCCCC;
GPIOI->AFR[1] = 0x00000CC0;
/* Configure PIx pins in Alternate function mode */
GPIOI->MODER = 0x0028AAAA;
/* Configure PIx pins speed to 50 MHz */
GPIOI->OSPEEDR = 0x0028AAAA;
/* Configure PIx pins Output type to push-pull */
GPIOI->OTYPER = 0x00000000;
/* No pull-up, pull-down for PIx pins */
GPIOI->PUPDR = 0x00000000;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || \
STM32F469xx || STM32F479xx */
/*-- FMC Configuration
* -------------------------------------------------------*/
/* Enable the FMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable SDRAM bank1 */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCR[0] = 0x00001954;
#else
FMC_Bank5_6->SDCR[0] = 0x000019E4;
#endif /* STM32F446xx */
FMC_Bank5_6->SDTR[0] = 0x01115351;
/* SDRAM initialization sequence */
/* Clock enable command */
FMC_Bank5_6->SDCMR = 0x00000011;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
while ((tmpreg != 0) && (timeout-- > 0)) {
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Delay */
for (index = 0; index < 1000; index++)
;
/* PALL command */
FMC_Bank5_6->SDCMR = 0x00000012;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while ((tmpreg != 0) && (timeout-- > 0)) {
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Auto refresh command */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCMR = 0x000000F3;
#else
FMC_Bank5_6->SDCMR = 0x00000073;
#endif /* STM32F446xx */
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while ((tmpreg != 0) && (timeout-- > 0)) {
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* MRD register program */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCMR = 0x00044014;
#else
FMC_Bank5_6->SDCMR = 0x00046014;
#endif /* STM32F446xx */
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
timeout = 0xFFFF;
while ((tmpreg != 0) && (timeout-- > 0)) {
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Set refresh count */
tmpreg = FMC_Bank5_6->SDRTR;
#if defined(STM32F446xx)
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C << 1));
#else
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C << 1));
#endif /* STM32F446xx */
/* Disable write protection */
tmpreg = FMC_Bank5_6->SDCR[0];
FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
#endif /* DATA_IN_ExtSDRAM */
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || \
STM32F446xx || STM32F469xx || STM32F479xx */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || \
defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || \
defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || \
defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
#if defined(DATA_IN_ExtSRAM)
/*-- GPIOs Configuration
* -----------------------------------------------------*/
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR |= 0x00000078;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x00CCC0CC;
GPIOD->AFR[1] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A8A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0FCF;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00CC0CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA828A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC3CF;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0x00CCCCCC;
GPIOF->AFR[1] = 0xCCCC0000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA000AAA;
/* Configure PFx pins speed to 100 MHz */
GPIOF->OSPEEDR = 0xFF000FFF;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0x00CCCCCC;
GPIOG->AFR[1] = 0x000000C0;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x00085AAA;
/* Configure PGx pins speed to 100 MHz */
GPIOG->OSPEEDR = 0x000CAFFF;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/*-- FMC/FSMC Configuration
* --------------------------------------------------*/
/* Enable the FMC/FSMC interface clock */
RCC->AHB3ENR |= 0x00000001;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || \
defined(STM32F439xx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001011;
FMC_Bank1->BTCR[3] = 0x00000201;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
#if defined(STM32F469xx) || defined(STM32F479xx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001091;
FMC_Bank1->BTCR[3] = 0x00110212;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F469xx || STM32F479xx */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || \
defined(STM32F417xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
/* Configure and enable Bank1_SRAM2 */
FSMC_Bank1->BTCR[2] = 0x00001011;
FSMC_Bank1->BTCR[3] = 0x00000201;
FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || \
STM32F412Zx || STM32F412Vx */
#endif /* DATA_IN_ExtSRAM */
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || \
STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || \
STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */
(void)(tmp);
}
#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/