bare modbus init
This commit is contained in:
commit
b34c84171a
116
Modbus/crc_algs.c
Normal file
116
Modbus/crc_algs.c
Normal file
@ -0,0 +1,116 @@
|
||||
#include "crc_algs.h"
|
||||
|
||||
|
||||
uint32_t CRC_calc;
|
||||
uint32_t CRC_ref;
|
||||
|
||||
//uint16_t CRC_calc;
|
||||
//uint16_t CRC_ref;
|
||||
|
||||
|
||||
// left this global for debug
|
||||
uint8_t uchCRCHi = 0xFF;
|
||||
uint8_t uchCRCLo = 0xFF;
|
||||
unsigned uIndex;
|
||||
|
||||
|
||||
uint32_t crc32(uint8_t *data, uint32_t data_size)
|
||||
{
|
||||
static const unsigned int crc32_table[] =
|
||||
{
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
unsigned int crc = 0xFFFFFFFF;
|
||||
while (data_size--)
|
||||
{
|
||||
crc = (crc >> 8) ^ crc32_table[(crc ^ *data) & 255];
|
||||
data++;
|
||||
}
|
||||
return crc^0xFFFFFFFF;
|
||||
}
|
||||
|
||||
|
||||
uint16_t crc16(uint8_t *data, uint32_t data_size)
|
||||
{
|
||||
/*Table of CRC values for high order byte*/
|
||||
static unsigned char auchCRCHi[]=
|
||||
{
|
||||
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
|
||||
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
|
||||
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
|
||||
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
|
||||
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
|
||||
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
|
||||
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
|
||||
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
|
||||
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
|
||||
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
|
||||
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
|
||||
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
|
||||
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
|
||||
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
|
||||
0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
|
||||
0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
|
||||
};
|
||||
/*Table of CRC values for low order byte*/
|
||||
static char auchCRCLo[] =
|
||||
{
|
||||
0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04,
|
||||
0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8,
|
||||
0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,
|
||||
0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10,
|
||||
0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
|
||||
0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38,
|
||||
0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,
|
||||
0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,
|
||||
0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,
|
||||
0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
|
||||
0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,
|
||||
0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,
|
||||
0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
|
||||
0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,
|
||||
0x88,0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
|
||||
0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40,
|
||||
};
|
||||
uchCRCHi = 0xFF;
|
||||
uchCRCLo = 0xFF;
|
||||
/* CRC Generation Function */
|
||||
while( data_size--) /* pass through message buffer */
|
||||
{
|
||||
uIndex = uchCRCHi ^ *data++; /* calculate the CRC */
|
||||
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
|
||||
uchCRCLo = auchCRCLo[uIndex];
|
||||
}
|
||||
return uchCRCHi | uchCRCLo<<8;
|
||||
}
|
9
Modbus/crc_algs.h
Normal file
9
Modbus/crc_algs.h
Normal file
@ -0,0 +1,9 @@
|
||||
#include "modbus_config.h"
|
||||
|
||||
// extern here to use in bootloader.c
|
||||
extern uint32_t CRC_calc;
|
||||
extern uint32_t CRC_ref;
|
||||
|
||||
|
||||
uint16_t crc16(uint8_t *data, uint32_t data_size);
|
||||
uint32_t crc32(uint8_t *data, uint32_t data_size);
|
957
Modbus/modbus.c
Normal file
957
Modbus/modbus.c
Normal file
@ -0,0 +1,957 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file modbus.c
|
||||
* @brief Модуль для реализации MODBUS.
|
||||
**************************************************************************
|
||||
* @details Файл содержит реализацию функций работы с Modbus, включая:
|
||||
* - доступ к coils и registers;
|
||||
* - обработку команд протокола;
|
||||
* - взаимодействие с RS-каналом (UART);
|
||||
* - инициализацию.
|
||||
*
|
||||
* @section Функции и макросы
|
||||
*
|
||||
* ### Доступ к coils:
|
||||
* - MB_Set_Coil_Local() — Установить coil по локальному адресу.
|
||||
* - MB_Reset_Coil_Local() — Сбросить coil по локальному адресу.
|
||||
* - MB_Toogle_Coil_Local() — Инвертировать coil по локальному адресу.
|
||||
* - MB_Read_Coil_Local() — Прочитать coil по локальному адресу.
|
||||
* - MB_Write_Coil_Global() — Установить/сбросить coil по глобальному адресу.
|
||||
* - MB_Read_Coil_Global() — Прочитать coil по глобальному адресу.
|
||||
*
|
||||
* ### Обработка команд Modbus:
|
||||
* - MB_DefineRegistersAddress() — Определить начальный адрес регистра.
|
||||
* - MB_DefineCoilsAddress() — Определить начальный адрес coils.
|
||||
* - MB_Check_Address_For_Arr() — Проверить, принадлежит ли адрес массиву.
|
||||
* - Основные команды Modbus:
|
||||
* - MB_Read_Coils()
|
||||
* - MB_Read_Hold_Regs()
|
||||
* - MB_Write_Single_Coil()
|
||||
* - MB_Write_Miltuple_Coils()
|
||||
* - MB_Write_Miltuple_Regs()
|
||||
*
|
||||
* ### Функции для работы с RS-каналом:
|
||||
* - RS_Parse_Message() / RS_Collect_Message() — Парсинг и сборка сообщения.
|
||||
* - RS_Response() — Отправка ответа.
|
||||
* - RS_Define_Size_of_RX_Message() — Определение размера принимаемого сообщения.
|
||||
* - RS_Init() — Инициализация RS-подсистемы и handler.
|
||||
*
|
||||
* ### Инициализация:
|
||||
* - MODBUS_FirstInit() — Инициализация модуля Modbus.
|
||||
*
|
||||
* @section Структура данных Modbus
|
||||
*
|
||||
* #### Holding/Input Registers:
|
||||
* - Регистры — 16-битные слова. Доступ к регистрам осуществляется через указатель.
|
||||
* Таким образом, сами регистры могут представлять собой как массив так и структуру.
|
||||
*
|
||||
* #### Coils:
|
||||
* - Coils — это биты, упакованные в 16-битные слова. Доступ к коилам осуществляется через указатель.
|
||||
* Таким образом, сами коилы могут представлять собой как массив так и структуру.
|
||||
*
|
||||
* @section Инструкция по подключению
|
||||
* Для корректной работы надо подключить обработчики RS_UART_Handler(), RS_TIM_Handler(),
|
||||
* в соответствубщие низкоуровневые прерываниф UART_IRQHandler, TIM_IRQHandler. После HAL'овского обработчика
|
||||
*
|
||||
* Также необходимо в modbus_config.h настроить дефайны для нужной работы UART
|
||||
* После для запуска Modbus:
|
||||
* @verbatim
|
||||
//----------------Прием модбас----------------//
|
||||
#include "rs_message.h"
|
||||
MODBUS_FirstInit();
|
||||
RS_Receive_IT(&hmodbus1, &MODBUS_MSG);
|
||||
* @endverbatim
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "rs_message.h"
|
||||
uint32_t dbg_temp, dbg_temp2, dbg_temp3; // for debug
|
||||
/* MODBUS HANDLES */
|
||||
extern UART_HandleTypeDef rs_huart;
|
||||
extern TIM_HandleTypeDef rs_htim;
|
||||
RS_HandleTypeDef hmodbus1;
|
||||
|
||||
/* DEFINE REGISTERS/COILS */
|
||||
MB_DeviceIdentificationTypeDef MB_INFO;
|
||||
MB_DataStructureTypeDef MB_DATA;
|
||||
RS_MsgTypeDef MODBUS_MSG;
|
||||
|
||||
uint32_t delay_scide = 1;
|
||||
uint32_t numb_scide = 10;
|
||||
//-------------------------------------------------------------------
|
||||
//-----------------------------FOR USER------------------------------
|
||||
/**
|
||||
* @brief First set up of MODBUS.
|
||||
* @details Первый инит модбас. Заполняет структуры и инициализирует таймер и юарт для общения по модбас.
|
||||
* @note This called from main
|
||||
*/
|
||||
void MODBUS_FirstInit(void)
|
||||
{
|
||||
MB_DevoceInentificationInit();
|
||||
//-----------SETUP MODBUS-------------
|
||||
// set up modbus: MB_RX_Size_NotConst and Timeout enable
|
||||
hmodbus1.ID = MODBUS_DEVICE_ID;
|
||||
hmodbus1.sRS_Timeout = MODBUS_TIMEOUT;
|
||||
hmodbus1.sRS_Mode = SLAVE_ALWAYS_WAIT;
|
||||
hmodbus1.sRS_RX_Size_Mode = RS_RX_Size_NotConst;
|
||||
|
||||
// INIT
|
||||
hmodbus1.RS_STATUS = RS_Init(&hmodbus1, &rs_huart, &rs_htim, 0);
|
||||
|
||||
RS_EnableReceive();
|
||||
}
|
||||
/**
|
||||
* @brief Set or Reset Coil at its global address.
|
||||
* @param Addr - адрес коила.
|
||||
* @param WriteVal - Что записать в коил: 0 или 1.
|
||||
* @return ExceptionCode - Код исключения если коила по адресу не существует, и NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
||||
Вне зависимости от того как коилы размещены в памяти.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
MB_ExceptionTypeDef Exception = NO_ERRORS;
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
|
||||
//------------WRITE COIL-------------
|
||||
Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 1);
|
||||
if(Exception == NO_ERRORS)
|
||||
{
|
||||
switch(WriteVal)
|
||||
{
|
||||
case SET_COIL:
|
||||
*coils |= (1<<start_shift);
|
||||
break;
|
||||
|
||||
case RESET_COIL:
|
||||
*coils &= ~(1<<start_shift);
|
||||
break;
|
||||
|
||||
case TOOGLE_COIL:
|
||||
*coils ^= (1<<start_shift);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
return Exception;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Read Coil at its global address.
|
||||
* @param Addr - адрес коила.
|
||||
* @param Exception - Указатель на переменную для кода исключения, в случа неудачи при чтении.
|
||||
* @return uint16_t - Возвращает весь регистр с маской на запрошенном коиле.
|
||||
*
|
||||
* @details Позволяет обратиться к любому коилу по его глобальному адрессу.
|
||||
Вне зависимости от того как коилы размещены в памяти.
|
||||
*/
|
||||
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
MB_ExceptionTypeDef Exception_tmp;
|
||||
if(Exception == NULL) // if exception is not given to func fill it
|
||||
Exception = &Exception_tmp;
|
||||
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
|
||||
//------------READ COIL--------------
|
||||
*Exception = MB_DefineCoilsAddress(&coils, Addr, 1, &start_shift, 0);
|
||||
if(*Exception == NO_ERRORS)
|
||||
{
|
||||
return ((*coils)&(1<<start_shift));
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
|
||||
/**
|
||||
* @brief Check is address valid for certain array.
|
||||
* @param Addr - начальный адресс.
|
||||
* @param Qnt - количество запрашиваемых элементов.
|
||||
* @param R_ARR_ADDR - начальный адресс массива R_ARR.
|
||||
* @param R_ARR_NUMB - количество элементов в массиве R_ARR.
|
||||
* @return ExceptionCode - ILLEGAL DATA ADRESS если адресс недействителен, и NO_ERRORS если все ок.
|
||||
*
|
||||
* @details Позволяет определить, принадлежит ли адресс Addr массиву R_ARR:
|
||||
* Если адресс Addr находится в диапазоне адрессов массива R_ARR, то возвращаем NO_ERROR.
|
||||
* Если адресс Addr находится за пределами адрессов массива R_ARR - ILLEGAL_DATA_ADDRESSю.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB)
|
||||
{
|
||||
// if address from this array
|
||||
if(Addr >= R_ARR_ADDR)
|
||||
{
|
||||
// if quantity too big return error
|
||||
if ((Addr - R_ARR_ADDR) + Qnt > R_ARR_NUMB)
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
// if all ok - return no errors
|
||||
return NO_ERRORS;
|
||||
}
|
||||
// if address isnt from this array return error
|
||||
else
|
||||
return ILLEGAL_DATA_ADDRESS; // return exception code
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for Input/Holding Registers
|
||||
* @param pRegs - указатель на указатель регистров.
|
||||
* @param Addr - адрес начального регистра.
|
||||
* @param Qnt - количество запрашиваемых регистров.
|
||||
* @param WriteFlag - флаг регистр нужны для чтения или записи.
|
||||
* @return ExceptionCode - Код исключения если есть, и NO_ERRORS если нет.
|
||||
*
|
||||
* @details Определение адреса начального регистра.
|
||||
* @note WriteFlag пока не используется.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType)
|
||||
{
|
||||
/* check quantity error */
|
||||
if (Qnt > 125)
|
||||
{
|
||||
return ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
if(RegisterType == RegisterType_Holding)
|
||||
{
|
||||
// Устаки для тестера
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_SETTINGS_ADDR, R_SETTINGS_QNT) == NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.HoldRegs, Addr); // начало регистров хранения/входных
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else if(RegisterType == RegisterType_Input)
|
||||
{
|
||||
// Измеренные параметры диода
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, R_MEASURED_ADDR, R_MEASURED_QNT) == NO_ERRORS)
|
||||
{
|
||||
*pRegs = MB_Set_Register_Ptr(&MB_DATA.InRegs, Addr); // начало регистров хранения/входных
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ILLEGAL_FUNCTION;
|
||||
}
|
||||
// if found requeried array return no err
|
||||
return NO_ERRORS; // return no errors
|
||||
}
|
||||
/**
|
||||
* @brief Define Address Origin for coils
|
||||
* @param pCoils - указатель на указатель коилов.
|
||||
* @param Addr - адресс начального коила.
|
||||
* @param Qnt - количество запрашиваемых коилов.
|
||||
* @param start_shift - указатель на переменную содержащую сдвиг внутри регистра для начального коила.
|
||||
* @param WriteFlag - флаг коилы нужны для чтения или записи.
|
||||
* @return ExceptionCode - Код исключения если есть, и NO_ERRORS если нет.
|
||||
*
|
||||
* @details Определение адреса начального регистра запрашиваемых коилов.
|
||||
* @note WriteFlag используется для определния регистров GPIO: ODR или IDR.
|
||||
*/
|
||||
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag)
|
||||
{
|
||||
/* check quantity error */
|
||||
if (Qnt > 2000)
|
||||
{
|
||||
return ILLEGAL_DATA_VALUE; // return exception code
|
||||
}
|
||||
|
||||
// tester settings coils
|
||||
if(MB_Check_Address_For_Arr(Addr, Qnt, C_SETTINGS_ADDR, C_SETTINGS_QNT) == NO_ERRORS)
|
||||
{
|
||||
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr);
|
||||
}// tester control coils
|
||||
else if(MB_Check_Address_For_Arr(Addr, Qnt, C_CONTROL_ADDR, C_CONTROL_QNT) == NO_ERRORS)
|
||||
{
|
||||
*pCoils = MB_Set_Coil_Reg_Ptr(&MB_DATA.Coils, Addr);
|
||||
}
|
||||
// if address doesnt match any array - return illegal data address response
|
||||
else
|
||||
{
|
||||
return ILLEGAL_DATA_ADDRESS;
|
||||
}
|
||||
|
||||
*start_shift = Addr % 16; // set shift to requested coil
|
||||
// if found requeried array return no err
|
||||
return NO_ERRORS; // return no errors
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Proccess command Read Coils (01 - 0x01).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Read Coils.
|
||||
*/
|
||||
uint8_t MB_Read_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 0);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------READING COIL------------
|
||||
// setup output message data size
|
||||
modbus_msg->ByteCnt = Divide_Up(modbus_msg->Qnt, 8);
|
||||
// create mask for coils
|
||||
uint16_t mask_for_coils = 0; // mask for coils that've been chosen
|
||||
uint16_t setted_coils = 0; // value of setted coils
|
||||
uint16_t temp_reg = 0; // temp register for saving coils that hasnt been chosen
|
||||
uint16_t coil_cnt = 0; // counter for processed coils
|
||||
|
||||
// cycle until all registers with requered coils would be processed
|
||||
int shift = start_shift; // set shift to first coil in first register
|
||||
int ind = 0; // index for coils registers and data
|
||||
for(; ind <= Divide_Up(start_shift + modbus_msg->Qnt, 16); ind++)
|
||||
{
|
||||
//----SET MASK FOR COILS REGISTER----
|
||||
mask_for_coils = 0;
|
||||
for(; shift < 0x10; shift++)
|
||||
{
|
||||
mask_for_coils |= 1<<(shift); // choose certain coil
|
||||
if(++coil_cnt >= modbus_msg->Qnt)
|
||||
break;
|
||||
}
|
||||
shift = 0; // set shift to zero for the next step
|
||||
|
||||
//-----------READ COILS--------------
|
||||
modbus_msg->DATA[ind] = (*(coils+ind)&mask_for_coils) >> start_shift;
|
||||
if(ind > 0)
|
||||
modbus_msg->DATA[ind-1] |= ((*(coils+ind)&mask_for_coils) << 16) >> start_shift;
|
||||
|
||||
}
|
||||
// т.к. DATA 16-битная, для 8-битной передачи, надо поменять местами верхний и нижний байты
|
||||
for(; ind >= 0; --ind)
|
||||
modbus_msg->DATA[ind] = ByteSwap16(modbus_msg->DATA[ind]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Read Holding Registers (03 - 0x03).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Read Holding Registers.
|
||||
*/
|
||||
uint8_t MB_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
//-----------READING REGS------------
|
||||
// setup output message data size
|
||||
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
|
||||
// read data
|
||||
int i;
|
||||
for (i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
modbus_msg->DATA[i] = *(pHoldRegs++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Read Input Registers (04 - 0x04).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Read Input Registers.
|
||||
*/
|
||||
uint8_t MB_Read_Input_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
// get origin address for data
|
||||
uint16_t *pInRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pInRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Input); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
//-----------READING REGS------------
|
||||
// setup output message data size
|
||||
modbus_msg->ByteCnt = modbus_msg->Qnt*2; // *2 because we transmit 8 bits, not 16 bits
|
||||
// read data
|
||||
int i;
|
||||
for (i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
if(*((int16_t *)pInRegs) > 0)
|
||||
modbus_msg->DATA[i] = (*pInRegs++);
|
||||
else
|
||||
modbus_msg->DATA[i] = (*pInRegs++);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/**
|
||||
* @brief Proccess command Write Single Coils (05 - 0x05).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Single Coils.
|
||||
*/
|
||||
uint8_t MB_Write_Single_Coil(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
if ((modbus_msg->Qnt != 0x0000) && (modbus_msg->Qnt != 0xFF00))
|
||||
{
|
||||
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||
return 0;
|
||||
}
|
||||
// define position of coil
|
||||
uint16_t *coils;
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, 0, &start_shift, 1);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
|
||||
//----------WRITTING COIL------------
|
||||
if(modbus_msg->Qnt == 0xFF00)
|
||||
*(coils) |= 1<<start_shift; // write flags corresponding to received data
|
||||
else
|
||||
*(coils) &= ~(1<<start_shift); // write flags corresponding to received data
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Write Single Register (06 - 0x06).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Single Register.
|
||||
*/
|
||||
uint8_t MB_Write_Single_Reg(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, 1, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------WRITTING REG------------
|
||||
*(pHoldRegs) = modbus_msg->Qnt;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Write Multiple Coils (15 - 0x0F).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Multiple Coils.
|
||||
*/
|
||||
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
if (modbus_msg->ByteCnt != Divide_Up(modbus_msg->Qnt, 8))
|
||||
{ // if quantity too large OR if quantity and bytes count arent match
|
||||
modbus_msg->Except_Code = ILLEGAL_DATA_VALUE;
|
||||
return 0;
|
||||
}
|
||||
// define position of coil
|
||||
uint16_t *coils; // pointer to coils
|
||||
uint16_t start_shift = 0; // shift in coils register
|
||||
modbus_msg->Except_Code = MB_DefineCoilsAddress(&coils, modbus_msg->Addr, modbus_msg->Qnt, &start_shift, 1);
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//----------WRITTING COILS-----------
|
||||
// create mask for coils
|
||||
uint16_t mask_for_coils = 0; // mask for coils that've been chosen
|
||||
uint32_t setted_coils = 0; // value of setted coils
|
||||
uint16_t temp_reg = 0; // temp register for saving coils that hasnt been chosen
|
||||
uint16_t coil_cnt = 0; // counter for processed coils
|
||||
|
||||
// cycle until all registers with requered coils would be processed
|
||||
int shift = start_shift; // set shift to first coil in first register
|
||||
for(int ind = 0; ind <= Divide_Up(start_shift + modbus_msg->Qnt, 16); ind++)
|
||||
{
|
||||
//----SET MASK FOR COILS REGISTER----
|
||||
mask_for_coils = 0;
|
||||
for(; shift < 0x10; shift++)
|
||||
{
|
||||
mask_for_coils |= 1<<(shift); // choose certain coil
|
||||
if(++coil_cnt >= modbus_msg->Qnt)
|
||||
break;
|
||||
}
|
||||
shift = 0; // set shift to zero for the next step
|
||||
|
||||
|
||||
|
||||
//-----------WRITE COILS-------------
|
||||
// get current coils
|
||||
temp_reg = *(coils+ind);
|
||||
// set coils
|
||||
setted_coils = ByteSwap16(modbus_msg->DATA[ind]) << start_shift;
|
||||
if(ind > 0)
|
||||
{
|
||||
setted_coils |= ((ByteSwap16(modbus_msg->DATA[ind-1]) << start_shift) >> 16);
|
||||
}
|
||||
// write coils
|
||||
|
||||
*(coils+ind) = setted_coils & mask_for_coils;
|
||||
// restore untouched coils
|
||||
*(coils+ind) |= temp_reg&(~mask_for_coils);
|
||||
|
||||
|
||||
if(coil_cnt >= modbus_msg->Qnt) // if all coils written - break cycle
|
||||
break; // *kind of unnecessary
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Proccess command Write Multiple Registers (16 - 0x10).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Multiple Registers.
|
||||
*/
|
||||
uint8_t MB_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
//---------CHECK FOR ERRORS----------
|
||||
if (modbus_msg->Qnt*2 != modbus_msg->ByteCnt)
|
||||
{ // if quantity and bytes count arent match
|
||||
modbus_msg->Except_Code = 3;
|
||||
return 0;
|
||||
}
|
||||
// get origin address for data
|
||||
uint16_t *pHoldRegs;
|
||||
modbus_msg->Except_Code = MB_DefineRegistersAddress(&pHoldRegs, modbus_msg->Addr, modbus_msg->Qnt, RegisterType_Holding); // определение адреса регистров
|
||||
if(modbus_msg->Except_Code != NO_ERRORS)
|
||||
return 0;
|
||||
|
||||
//-----------WRITTING REGS-----------
|
||||
for (int i = 0; i<modbus_msg->Qnt; i++)
|
||||
{
|
||||
*(pHoldRegs++) = modbus_msg->DATA[i];
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void MB_WriteObjectToMessage(char *mbdata, unsigned *ind, MB_DeviceObjectTypeDef *obj)
|
||||
{
|
||||
mbdata[(*ind)++] = obj->length;
|
||||
for (int i = 0; i < obj->length; i++)
|
||||
{
|
||||
mbdata[(*ind)++] = obj->name[i];
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @brief Proccess command Read Device Identification (43/14 - 0x2B/0E).
|
||||
* @param modbus_msg - указатель на структуру собщения modbus.
|
||||
* @return fMessageHandled - статус о результате обработки комманды.
|
||||
* @details Обработка команды Write Single Register.
|
||||
*/
|
||||
uint8_t MB_Read_Device_Identification(RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
char *mbdata = (char *)modbus_msg->DATA;
|
||||
unsigned ind = 0;
|
||||
switch(modbus_msg->DevId.ReadDevId)
|
||||
{
|
||||
case MB_BASIC_IDENTIFICATION:
|
||||
mbdata[ind++] = 0x00;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.VendorName);
|
||||
mbdata[ind++] = 0x01;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ProductCode);
|
||||
mbdata[ind++] = 0x02;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.Revision);
|
||||
modbus_msg->DevId.NumbOfObj = 3;
|
||||
break;
|
||||
case MB_REGULAR_IDENTIFICATION:
|
||||
mbdata[ind++] = 0x03;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.VendorUrl);
|
||||
mbdata[ind++] = 0x04;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ProductName);
|
||||
mbdata[ind++] = 0x05;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.ModelName);
|
||||
mbdata[ind++] = 0x06;
|
||||
MB_WriteObjectToMessage(mbdata, &ind, &MB_INFO.UserApplicationName);
|
||||
modbus_msg->DevId.NumbOfObj = 4;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
modbus_msg->ByteCnt = ind;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Respond accord to received message.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о результате ответа на комманду.
|
||||
* @details Обработка принятой комманды и ответ на неё.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg)
|
||||
{
|
||||
RS_StatusTypeDef MB_RES = 0;
|
||||
hmodbus->f.MessageHandled = 0;
|
||||
hmodbus->f.EchoResponse = 0;
|
||||
RS_Reset_TX_Flags(hmodbus); // reset flag for correct transmit
|
||||
|
||||
if(modbus_msg->Func_Code < ERR_VALUES_START)// if no errors after parsing
|
||||
{
|
||||
switch (modbus_msg->Func_Code)
|
||||
{
|
||||
// Read Coils
|
||||
case MB_R_COILS:
|
||||
hmodbus->f.MessageHandled = MB_Read_Coils(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
// Read Hodling Registers
|
||||
case MB_R_HOLD_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Read_Hold_Regs(hmodbus->pMessagePtr);
|
||||
break;
|
||||
case MB_R_IN_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Read_Input_Regs(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
|
||||
// Write Single Coils
|
||||
case MB_W_COIL:
|
||||
hmodbus->f.MessageHandled = MB_Write_Single_Coil(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
hmodbus->f.EchoResponse = 1;
|
||||
hmodbus->RS_Message_Size -= 2; // echo response if write ok (minus 2 cause of two CRC bytes)
|
||||
}
|
||||
break;
|
||||
|
||||
case MB_W_HOLD_REG:
|
||||
hmodbus->f.MessageHandled = MB_Write_Single_Reg(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
hmodbus->f.EchoResponse = 1;
|
||||
hmodbus->RS_Message_Size -= 2; // echo response if write ok (minus 2 cause of two CRC bytes)
|
||||
}
|
||||
break;
|
||||
|
||||
// Write Multiple Coils
|
||||
case MB_W_COILS:
|
||||
hmodbus->f.MessageHandled = MB_Write_Miltuple_Coils(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
hmodbus->f.EchoResponse = 1;
|
||||
hmodbus->RS_Message_Size = 6; // echo response if write ok (withous data bytes)
|
||||
}
|
||||
break;
|
||||
|
||||
// Write Multiple Registers
|
||||
case MB_W_HOLD_REGS:
|
||||
hmodbus->f.MessageHandled = MB_Write_Miltuple_Regs(hmodbus->pMessagePtr);
|
||||
if(hmodbus->f.MessageHandled)
|
||||
{
|
||||
hmodbus->f.EchoResponse = 1;
|
||||
hmodbus->RS_Message_Size = 6; // echo response if write ok (withous data bytes)
|
||||
}
|
||||
break;
|
||||
|
||||
case MB_R_DEVICE_INFO:
|
||||
hmodbus->f.MessageHandled = MB_Read_Device_Identification(hmodbus->pMessagePtr);
|
||||
break;
|
||||
|
||||
|
||||
/* unknown func code */
|
||||
default: modbus_msg->Except_Code = 0x01; /* set exception code: illegal function */
|
||||
}
|
||||
|
||||
if(hmodbus->f.MessageHandled == 0)
|
||||
{
|
||||
modbus_msg->Func_Code += ERR_VALUES_START;
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// if we need response - check that transmit isnt busy
|
||||
if( RS_Is_TX_Busy(hmodbus) )
|
||||
RS_Abort(hmodbus, ABORT_TX); // if tx busy - set it free
|
||||
|
||||
// Transmit right there, or sets (fDeferredResponse) to transmit response in main code
|
||||
MB_RES = RS_Handle_Transmit_Start(hmodbus, modbus_msg);
|
||||
|
||||
hmodbus->RS_STATUS = MB_RES;
|
||||
return MB_RES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Collect message in buffer to transmit it.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @param msg_uart_buff - указатель на буффер UART.
|
||||
* @return RS_RES - статус о результате заполнения буфера.
|
||||
* @details Заполнение буффера UART из структуры сообщения.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
|
||||
{
|
||||
int ind = 0; // ind for modbus-uart buffer
|
||||
|
||||
if(hmodbus->f.EchoResponse && hmodbus->f.MessageHandled) // if echo response need
|
||||
ind = hmodbus->RS_Message_Size;
|
||||
else
|
||||
{
|
||||
//------INFO ABOUT DATA/MESSAGE------
|
||||
//-----------[first bytes]-----------
|
||||
// set ID of message/user
|
||||
modbus_uart_buff[ind++] = modbus_msg->MbAddr;
|
||||
|
||||
// set dat or err response
|
||||
modbus_uart_buff[ind++] = modbus_msg->Func_Code;
|
||||
|
||||
if (modbus_msg->Func_Code < ERR_VALUES_START) // if no error occur
|
||||
{
|
||||
// fill modbus header
|
||||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // devide identification header
|
||||
{
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.MEI_Type;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.ReadDevId;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.Conformity;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.MoreFollows;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.NextObjId;
|
||||
modbus_uart_buff[ind++] = modbus_msg->DevId.NumbOfObj;
|
||||
|
||||
if (modbus_msg->ByteCnt > DATA_SIZE*2) // if ByteCnt less than DATA_SIZE
|
||||
{
|
||||
return RS_COLLECT_MSG_ERR;
|
||||
}
|
||||
|
||||
|
||||
//---------------DATA----------------
|
||||
//-----------[data bytes]------------
|
||||
uint8_t *tmp_data_addr = (uint8_t *)modbus_msg->DATA;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
||||
{ // set data
|
||||
modbus_uart_buff[ind++] = *tmp_data_addr;
|
||||
tmp_data_addr++;
|
||||
}
|
||||
|
||||
}
|
||||
else // modbus data header
|
||||
{
|
||||
// set size of received data
|
||||
if (modbus_msg->ByteCnt <= DATA_SIZE*2) // if ByteCnt less than DATA_SIZE
|
||||
modbus_uart_buff[ind++] = modbus_msg->ByteCnt;
|
||||
else // otherwise return data_size err
|
||||
{
|
||||
return RS_COLLECT_MSG_ERR;
|
||||
}
|
||||
|
||||
//---------------DATA----------------
|
||||
//-----------[data bytes]------------
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // filling buffer with data
|
||||
{ // set data
|
||||
if (i%2 == 0) // HI byte
|
||||
modbus_uart_buff[ind++] = (*tmp_data_addr)>>8;
|
||||
else // LO byte
|
||||
{
|
||||
modbus_uart_buff[ind++] = *tmp_data_addr;
|
||||
tmp_data_addr++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
else // if some error occur
|
||||
{ // send expection code
|
||||
modbus_uart_buff[ind++] = modbus_msg->Except_Code;
|
||||
}
|
||||
}
|
||||
//---------------CRC----------------
|
||||
//---------[last 16 bytes]----------
|
||||
// calc crc of received data
|
||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||
// write crc to message structure and modbus-uart buffer
|
||||
modbus_msg->MB_CRC = CRC_VALUE;
|
||||
modbus_uart_buff[ind++] = CRC_VALUE;
|
||||
modbus_uart_buff[ind++] = CRC_VALUE >> 8;
|
||||
|
||||
hmodbus->RS_Message_Size = ind;
|
||||
|
||||
return RS_OK; // returns ok
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse message from buffer to process it.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @param msg_uart_buff - указатель на буффер UART.
|
||||
* @return RS_RES - статус о результате заполнения структуры.
|
||||
* @details Заполнение структуры сообщения из буффера UART.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hmodbus, RS_MsgTypeDef *modbus_msg, uint8_t *modbus_uart_buff)
|
||||
{
|
||||
uint32_t check_empty_buff;
|
||||
int ind = 0; // ind for modbus-uart buffer
|
||||
//-----INFO ABOUT DATA/MESSAGE-------
|
||||
//-----------[first bits]------------
|
||||
// get ID of message/user
|
||||
modbus_msg->MbAddr = modbus_uart_buff[ind++];
|
||||
if(modbus_msg->MbAddr != hmodbus->ID)
|
||||
return RS_SKIP;
|
||||
|
||||
// get func code
|
||||
modbus_msg->Func_Code = modbus_uart_buff[ind++];
|
||||
if(modbus_msg->Func_Code == MB_R_DEVICE_INFO) // if it device identification request
|
||||
{
|
||||
modbus_msg->DevId.MEI_Type = modbus_uart_buff[ind++];
|
||||
modbus_msg->DevId.ReadDevId = modbus_uart_buff[ind++];
|
||||
modbus_msg->DevId.NextObjId = modbus_uart_buff[ind++];
|
||||
modbus_msg->ByteCnt = 0;
|
||||
}
|
||||
else // if its classic modbus request
|
||||
{
|
||||
// get address from CMD
|
||||
modbus_msg->Addr = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->Addr |= modbus_uart_buff[ind++];
|
||||
|
||||
// get address from CMD
|
||||
modbus_msg->Qnt = modbus_uart_buff[ind++] << 8;
|
||||
modbus_msg->Qnt |= modbus_uart_buff[ind++];
|
||||
}
|
||||
if(hmodbus->f.RX_Half == 0) // if all message received
|
||||
{
|
||||
//---------------DATA----------------
|
||||
// (optional)
|
||||
if (modbus_msg->ByteCnt != 0)
|
||||
{
|
||||
ind++; // increment ind for data_size byte
|
||||
//check that data size is correct
|
||||
if (modbus_msg->ByteCnt > DATA_SIZE*2)
|
||||
{
|
||||
modbus_msg->Func_Code += ERR_VALUES_START;
|
||||
return RS_PARSE_MSG_ERR;
|
||||
}
|
||||
uint16_t *tmp_data_addr = (uint16_t *)modbus_msg->DATA;
|
||||
for(int i = 0; i < modbus_msg->ByteCnt; i++) // /2 because we transmit 8 bits, not 16 bits
|
||||
{ // set data
|
||||
if (i%2 == 0)
|
||||
*tmp_data_addr = ((uint16_t)modbus_uart_buff[ind++] << 8);
|
||||
else
|
||||
{
|
||||
*tmp_data_addr |= modbus_uart_buff[ind++];
|
||||
tmp_data_addr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//---------------CRC----------------
|
||||
//----------[last 16 bits]----------
|
||||
// calc crc of received data
|
||||
uint16_t CRC_VALUE = crc16(modbus_uart_buff, ind);
|
||||
// get crc of received data
|
||||
modbus_msg->MB_CRC = modbus_uart_buff[ind++];
|
||||
modbus_msg->MB_CRC |= modbus_uart_buff[ind++] << 8;
|
||||
// compare crc
|
||||
if (modbus_msg->MB_CRC != CRC_VALUE)
|
||||
{
|
||||
modbus_msg->Func_Code += ERR_VALUES_START;
|
||||
}
|
||||
// hmodbus->MB_RESPONSE = MB_CRC_ERR; // set func code - error about wrong crc
|
||||
|
||||
// check is buffer empty
|
||||
check_empty_buff = 0;
|
||||
for(int i=0; i<ind;i++)
|
||||
check_empty_buff += modbus_uart_buff[i];
|
||||
// if(check_empty_buff == 0)
|
||||
// hmodbus->MB_RESPONSE = MB_EMPTY_MSG; //
|
||||
}
|
||||
|
||||
return RS_OK;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Define size of RX Message that need to be received.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param rx_data_size - указатель на переменную для записи кол-ва байт для принятия.
|
||||
* @return RS_RES - статус о корректности рассчета кол-ва байт для принятия.
|
||||
* @details Определение сколько байтов надо принять по протоколу.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hmodbus, uint32_t *rx_data_size)
|
||||
{
|
||||
RS_StatusTypeDef MB_RES = 0;
|
||||
|
||||
MB_RES = RS_Parse_Message(hmodbus, hmodbus->pMessagePtr, hmodbus->pBufferPtr);
|
||||
if(MB_RES == RS_SKIP) // if message not for us
|
||||
return MB_RES; // return
|
||||
|
||||
|
||||
if ((hmodbus->pMessagePtr->Func_Code & ~ERR_VALUES_START) < 0x0F)
|
||||
{
|
||||
hmodbus->pMessagePtr->ByteCnt = 0;
|
||||
*rx_data_size = 1;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
hmodbus->pMessagePtr->ByteCnt = hmodbus->pBufferPtr[RX_FIRST_PART_SIZE-1]; // get numb of data in command
|
||||
// +1 because that defines is size, not ind.
|
||||
*rx_data_size = hmodbus->pMessagePtr->ByteCnt + 2;
|
||||
}
|
||||
|
||||
|
||||
if(hmodbus->pMessagePtr->Func_Code == MB_R_DEVICE_INFO)
|
||||
{
|
||||
*rx_data_size = 0;
|
||||
}
|
||||
|
||||
hmodbus->RS_Message_Size = RX_FIRST_PART_SIZE + *rx_data_size; // size of whole message
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------FOR USER------------------------------
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
||||
void MB_DevoceInentificationInit(void)
|
||||
{
|
||||
MB_INFO.VendorName.name = MODBUS_VENDOR_NAME;
|
||||
MB_INFO.ProductCode.name = MODBUS_PRODUCT_CODE;
|
||||
MB_INFO.Revision.name = MODBUS_REVISION;
|
||||
MB_INFO.VendorUrl.name = MODBUS_VENDOR_URL;
|
||||
MB_INFO.ProductName.name = MODBUS_PRODUCT_NAME;
|
||||
MB_INFO.ModelName.name = MODBUS_MODEL_NAME;
|
||||
MB_INFO.UserApplicationName.name = MODBUS_USER_APPLICATION_NAME;
|
||||
|
||||
|
||||
MB_INFO.VendorName.length = sizeof(MODBUS_VENDOR_NAME);
|
||||
MB_INFO.ProductCode.length = sizeof(MODBUS_PRODUCT_CODE);
|
||||
MB_INFO.Revision.length = sizeof(MODBUS_REVISION);
|
||||
MB_INFO.VendorUrl.length = sizeof(MODBUS_VENDOR_URL);
|
||||
MB_INFO.ProductName.length = sizeof(MODBUS_PRODUCT_NAME);
|
||||
MB_INFO.ModelName.length = sizeof(MODBUS_MODEL_NAME);
|
||||
MB_INFO.UserApplicationName.length = sizeof(MODBUS_USER_APPLICATION_NAME);
|
||||
}
|
||||
|
||||
|
||||
|
372
Modbus/modbus.h
Normal file
372
Modbus/modbus.h
Normal file
@ -0,0 +1,372 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file modbus.h
|
||||
* @brief Заголовочный файл модуля MODBUS.
|
||||
* @details Данный файл необходимо подключить в rs_message.h. После подключать
|
||||
* rs_message.h к основному проекту.
|
||||
*
|
||||
* @defgroup MODBUS
|
||||
* @brief Modbus stuff
|
||||
*
|
||||
*************************************************************************/
|
||||
#ifndef __MODBUS_H_
|
||||
#define __MODBUS_H_
|
||||
|
||||
#include "modbus_config.h"
|
||||
#include "modbus_data.h"
|
||||
//#include "settings.h" // for modbus settings
|
||||
|
||||
/**
|
||||
* @addtogroup MODBUS_SETTINGS
|
||||
* @ingroup MODBUS
|
||||
* @brief Some defines for modbus
|
||||
@{
|
||||
*/
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////---SETTINGS---/////////////////////////////
|
||||
// USER SETTINGS FOR MODBUS IN interface_config.h
|
||||
//////////////////////////---SETTINGS---/////////////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////---USER MESSAGE DEFINES---//////////////////////
|
||||
//-------------DEFINES FOR STRUCTURE----------------
|
||||
/* defines for structure of modbus message */
|
||||
#define MbAddr_SIZE 1 ///< size of (MbAddr)
|
||||
#define Func_Code_SIZE 1 ///< size of (Func_Code)
|
||||
#define Addr_SIZE 2 ///< size of (Addr)
|
||||
#define Qnt_SIZE 2 ///< size of (Qnt)
|
||||
#define ByteCnt_SIZE 1 ///< size of (ByteCnt)
|
||||
#define DATA_SIZE 125 ///< maximum number of data: DWORD (NOT MESSAGE SIZE)
|
||||
#define CRC_SIZE 2 ///< size of (MB_CRC) in bytes
|
||||
|
||||
/** @brief Size of whole message */
|
||||
#define INFO_SIZE_MAX (MbAddr_SIZE+Func_Code_SIZE+Addr_SIZE+Qnt_SIZE+ByteCnt_SIZE)
|
||||
|
||||
/** @brief Size of first part of message that will be received
|
||||
first receive info part of message, than defines size of rest message*/
|
||||
#define RX_FIRST_PART_SIZE INFO_SIZE_MAX
|
||||
|
||||
/** @brief Size of buffer: max size of whole message */
|
||||
#define MSG_SIZE_MAX (INFO_SIZE_MAX + DATA_SIZE*2 + CRC_SIZE) // max possible size of message
|
||||
|
||||
/** @brief Structure for modbus exception codes */
|
||||
typedef enum //MB_ExceptionTypeDef
|
||||
{
|
||||
// reading
|
||||
NO_ERRORS = 0x00, ///< no errors
|
||||
ILLEGAL_FUNCTION = 0x01, ///< Принятый код функции не может быть обработан
|
||||
ILLEGAL_DATA_ADDRESS = 0x02, ///< Адрес данных, указанный в запросе, недоступен
|
||||
ILLEGAL_DATA_VALUE = 0x03, ///< Значение, содержащееся в поле данных запроса, является недопустимой величиной
|
||||
SLAVE_DEVICE_FAILURE = 0x04, ///< Невосстанавливаемая ошибка имела место, пока ведомое устройство пыталось выполнить затребованное действие
|
||||
// ACKNOWLEDGE = 0x05, ///< idk
|
||||
// SLAVE_DEVICE_BUSY = 0x06, ///< idk
|
||||
// MEMORY_PARITY_ERROR = 0x08, ///< idk
|
||||
}MB_ExceptionTypeDef;
|
||||
|
||||
#define ERR_VALUES_START 0x80U ///< from this value starts error func codes
|
||||
/** @brief Structure for modbus func codes */
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
/* COMMANDS */
|
||||
// reading
|
||||
MB_R_COILS = 0x01, ///< Чтение битовых ячеек
|
||||
MB_R_DISC_IN = 0x02, ///< Чтение дискретных входов
|
||||
#ifndef MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
||||
MB_R_HOLD_REGS = 0x03, ///< Чтение входных регистров
|
||||
MB_R_IN_REGS = 0x04, ///< Чтение регистров хранения
|
||||
#else
|
||||
MB_R_HOLD_REGS = 0x04, ///< Чтение входных регистров
|
||||
MB_R_IN_REGS = 0x03, ///< Чтение регистров хранения
|
||||
#endif
|
||||
|
||||
// writting
|
||||
MB_W_COIL = 0x05, ///< Запись битовой ячейки
|
||||
MB_W_HOLD_REG = 0x06, ///< Запись одиночного регистра
|
||||
MB_W_COILS = 0x0F, ///< Запись нескольких битовых ячеек
|
||||
MB_W_HOLD_REGS = 0x10, ///< Запись нескольких регистров
|
||||
|
||||
MB_R_DEVICE_INFO = 0x2B, ///< Чтения информации об устройстве
|
||||
|
||||
/* ERRORS */
|
||||
// error reading
|
||||
MB_ERR_R_COILS = MB_R_COILS + ERR_VALUES_START, ///< Ошибка чтения битовых ячеек
|
||||
MB_ERR_R_DISC_IN = MB_R_DISC_IN + ERR_VALUES_START, ///< Ошибка чтения дискретных входов
|
||||
MB_ERR_R_IN_REGS = MB_R_IN_REGS + ERR_VALUES_START, ///< Ошибка чтения регистров хранения
|
||||
MB_ERR_R_HOLD_REGS = MB_R_HOLD_REGS + ERR_VALUES_START, ///< Ошибка чтения входных регистров
|
||||
|
||||
// error writting
|
||||
MB_ERR_W_COIL = MB_W_COIL + ERR_VALUES_START, ///< Ошибка записи битовой ячейки
|
||||
MB_ERR_W_HOLD_REG = MB_W_HOLD_REG + ERR_VALUES_START, ///< Ошибка записи одиночного регистра
|
||||
MB_ERR_W_COILS = MB_W_COILS + ERR_VALUES_START, ///< Ошибка записи нескольких битовых ячеек
|
||||
MB_ERR_W_HOLD_REGS = MB_W_HOLD_REGS + ERR_VALUES_START, ///< Ошибка записи нескольких регистров
|
||||
}MB_FunctonTypeDef;
|
||||
|
||||
/** @brief Structure for MEI func codes */
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MEI_DEVICE_IDENTIFICATION = 0x0E,
|
||||
}MB_MEITypeDef;
|
||||
|
||||
/** @brief Structure for MEI func codes */
|
||||
typedef enum //MB_FunctonTypeDef
|
||||
{
|
||||
MB_BASIC_IDENTIFICATION = 0x01,
|
||||
MB_REGULAR_IDENTIFICATION = 0x02,
|
||||
|
||||
|
||||
/* ERRORS */
|
||||
MB_ERR_BASIC_IDENTIFICATION = MB_BASIC_IDENTIFICATION + ERR_VALUES_START,
|
||||
MB_ERR_REGULAR_IDENTIFICATION = MB_REGULAR_IDENTIFICATION + ERR_VALUES_START,
|
||||
}MB_ConformityTypeDef;
|
||||
|
||||
/** @brief Structure for decive identification message type */
|
||||
typedef struct
|
||||
{
|
||||
MB_MEITypeDef MEI_Type; ///< MEI Type assigned number for Device Identification Interface
|
||||
MB_ConformityTypeDef ReadDevId;
|
||||
MB_ConformityTypeDef Conformity;
|
||||
uint8_t MoreFollows; ///< in this library always a zero
|
||||
uint8_t NextObjId;
|
||||
uint8_t NumbOfObj;
|
||||
}MB_DevIdMsgTypeDef;
|
||||
|
||||
/** @brief Structure for modbus messsage */
|
||||
typedef struct // RS_MsgTypeDef
|
||||
{
|
||||
uint8_t MbAddr; ///< Modbus Slave Address
|
||||
MB_FunctonTypeDef Func_Code; ///< Modbus Function Code
|
||||
MB_DevIdMsgTypeDef DevId; ///< Read Device Identification Header struct
|
||||
uint16_t Addr; ///< Modbus Address of data
|
||||
uint16_t Qnt; ///< Quantity of modbus data
|
||||
uint8_t ByteCnt; ///< Quantity of bytes of data in message to transmit/receive
|
||||
|
||||
uint16_t DATA[DATA_SIZE]; ///< Modbus Data
|
||||
MB_ExceptionTypeDef Except_Code; ///< Exception Code for the command
|
||||
|
||||
uint16_t MB_CRC; ///< Modbus CRC
|
||||
}RS_MsgTypeDef;
|
||||
//--------------------------------------------------
|
||||
extern RS_MsgTypeDef MODBUS_MSG;
|
||||
/////////////////////---MODBUS USER SETTINGS---//////////////////////
|
||||
|
||||
/** MODBUS_SETTINGS
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
||||
/**
|
||||
* @addtogroup MODBUS_MESSAGE_DEFINES
|
||||
* @ingroup MODBUS
|
||||
* @brief Some defines for modbus
|
||||
@{
|
||||
*/
|
||||
/** @brief Structure for coils operation */
|
||||
typedef enum
|
||||
{
|
||||
SET_COIL,
|
||||
RESET_COIL,
|
||||
TOOGLE_COIL,
|
||||
}MB_CoilsOpTypeDef;
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Macros to set pointer to 16-bit array
|
||||
* @param _arr_ - массив регистров (16-бит).
|
||||
*/
|
||||
#define MB_Set_Arr16_Ptr(_arr_) ((uint16_t*)(&(_arr_)))
|
||||
/**
|
||||
* @brief Macros to set pointer to register
|
||||
* @param _parr_ - массив регистров.
|
||||
* @param _addr_ - Номер регистра (его индекс) от начала массива _arr_.
|
||||
*/
|
||||
#define MB_Set_Register_Ptr(_parr_, _addr_) ((uint16_t *)(_parr_)+(_addr_))
|
||||
|
||||
/**
|
||||
* @brief Macros to set pointer to a certain register that contains certain coil
|
||||
* @param _parr_ - массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
* @note Используется вместе с @ref MB_Set_Coil_Mask
|
||||
@verbatim Пояснение выражений
|
||||
(_coil_/16) - get index (address shift) of register that contain certain coil
|
||||
Visual explanation: 30th coil in coils registers array
|
||||
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|
||||
|register[0]----| |register[1]----|
|
||||
|skip this------| |get this-------|
|
||||
|shift to 14 bit|
|
||||
@endverbatim
|
||||
*/
|
||||
#define MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ((uint16_t *)(_parr_)+((_coil_)/16))
|
||||
/**
|
||||
* @brief Macros to set mask to a certain bit in coils register
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
* @note Используется вместе с @ref MB_Set_Coil_Reg_Ptr
|
||||
@verbatim Пояснение выражений
|
||||
(16*(_coil_/16) - how many coils we need to skip. e.g. (16*30/16) - skip 16 coils from first register
|
||||
_coil_-(16*(_coil_/16)) - shift to certain coil in certain register
|
||||
e.g. Coil(30) gets in register[1] (30/16 = 1) coil №14 (30 - (16*30/16) = 30 - 16 = 14)
|
||||
|
||||
Visual explanation: 30th coil in coils registers array
|
||||
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxCx
|
||||
|register[0]----| |register[1]----|
|
||||
|skip this------| |get this-------|
|
||||
|shift to 14 bit|
|
||||
@endverbatim
|
||||
*/
|
||||
#define MB_Set_Coil_Mask(_coil_) (1 << ( _coil_ - (16*((_coil_)/16)) ))
|
||||
|
||||
/**
|
||||
* @brief Read Coil at its local address.
|
||||
* @param _parr_ - массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
* @return uint16_t - Возвращает запрошенный коил на 0м бите.
|
||||
*
|
||||
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
|
||||
*/
|
||||
#define MB_Read_Coil_Local(_parr_, _coil_) (( *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) & MB_Set_Coil_Mask(_coil_) ) >> (_coil_))
|
||||
/**
|
||||
* @brief Set Coil at its local address.
|
||||
* @param _parr_ - указатель на массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
*
|
||||
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
|
||||
*/
|
||||
#define MB_Set_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) |= MB_Set_Coil_Mask(_coil_)
|
||||
/**
|
||||
* @brief Reset Coil at its local address.
|
||||
* @param _parr_ - указатель на массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
*
|
||||
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
|
||||
*/
|
||||
#define MB_Reset_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) &= ~(MB_Set_Coil_Mask(_coil_))
|
||||
/**
|
||||
* @brief Set Coil at its local address.
|
||||
* @param _parr_ - указатель на массив коилов.
|
||||
* @param _coil_ - Номер коила от начала массива _arr_.
|
||||
*
|
||||
* @details Позволяет обратиться к коилу по адресу относительно _arr_.
|
||||
*/
|
||||
#define MB_Toogle_Coil_Local(_parr_, _coil_) *MB_Set_Coil_Reg_Ptr(_parr_, _coil_) ^= MB_Set_Coil_Mask(_coil_)
|
||||
//--------------------------------------------------
|
||||
|
||||
|
||||
//------------------OTHER DEFINES-------------------
|
||||
#define RegisterType_Holding 0
|
||||
#define RegisterType_Input 1
|
||||
#define RegisterType_Discrete 2
|
||||
// create hadnles and settings for uart, tim, rs with _modbus_ name
|
||||
//--------------------------------------------------
|
||||
|
||||
#ifndef Divide_Up
|
||||
/**
|
||||
* @brief Calc dividing including remainder
|
||||
* @param _val_ - делимое.
|
||||
* @param _div_ - делитель.
|
||||
* @details Если результат деления без остатка: он возвращается как есть
|
||||
Если с остатком - округляется вверх
|
||||
*/
|
||||
//#define Divide_Up(_val_, _div_) (((_val_)%(_div_))? (_val_)/(_div_)+1 : (_val_)/_div_) /* через тернарный оператор */
|
||||
#define Divide_Up(_val_, _div_) ((_val_ - 1) / _div_) + 1 /* через мат выражение */
|
||||
#endif
|
||||
|
||||
#ifndef ByteSwap16
|
||||
/**
|
||||
* @brief Swap between Little Endian and Big Endian
|
||||
* @param v - Переменная для свапа.
|
||||
* @return v (new) - Свапнутая переменная.
|
||||
* @details Переключения между двумя типами хранения слова: HI-LO байты и LO-HI байты.
|
||||
*/
|
||||
#define ByteSwap16(v) (((v&0xFF00) >> (8)) | ((v&0x00FF) << (8)))
|
||||
#endif
|
||||
/** GENERAL_MODBUS_STUFF
|
||||
* @}
|
||||
*/
|
||||
////////////////////---MODBUS MESSAGE DEFINES---/////////////////////
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
/**
|
||||
* @addtogroup MODBUS_FUNCTIONS
|
||||
* @ingroup MODBUS
|
||||
* @brief Function for controling modbus communication
|
||||
*/
|
||||
|
||||
//----------------FUNCTIONS FOR USER----------------
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_ACCESS_FUNCTIONS
|
||||
* @ingroup MODBUS_FUNCTIONS
|
||||
* @brief Function for user use
|
||||
@{
|
||||
*/
|
||||
/* First set up of MODBUS */
|
||||
void MODBUS_FirstInit(void);
|
||||
/* Set or Reset Coil at its global address */
|
||||
MB_ExceptionTypeDef MB_Write_Coil_Global(uint16_t Addr, MB_CoilsOpTypeDef WriteVal);
|
||||
/* Read Coil at its global address */
|
||||
uint16_t MB_Read_Coil_Global(uint16_t Addr, MB_ExceptionTypeDef *Exception);
|
||||
|
||||
/** MODBUS_DATA_ACCESS_FUNCTIONS
|
||||
* @}
|
||||
*/
|
||||
|
||||
//---------PROCESS MODBUS COMMAND FUNCTIONS---------
|
||||
/**
|
||||
* @addtogroup MODBUS_CMD_PROCESS_FUNCTIONS
|
||||
* @ingroup MODBUS_FUNCTIONS
|
||||
* @brief Function process commands
|
||||
@{
|
||||
*/
|
||||
/* Check is address valid for certain array */
|
||||
MB_ExceptionTypeDef MB_Check_Address_For_Arr(uint16_t Addr, uint16_t Qnt, uint16_t R_ARR_ADDR, uint16_t R_ARR_NUMB);
|
||||
/* Define Address Origin for Input/Holding Registers */
|
||||
MB_ExceptionTypeDef MB_DefineRegistersAddress(uint16_t **pRegs, uint16_t Addr, uint16_t Qnt, uint8_t RegisterType);
|
||||
/* Define Address Origin for coils */
|
||||
MB_ExceptionTypeDef MB_DefineCoilsAddress(uint16_t **pCoils, uint16_t Addr, uint16_t Qnt, uint16_t *start_shift, uint8_t WriteFlag);
|
||||
/* Proccess command Read Coils (01 - 0x01) */
|
||||
uint8_t MB_Read_Coils(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Read Holding Registers (03 - 0x03) */
|
||||
uint8_t MB_Read_Hold_Regs(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Read Input Registers (04 - 0x04) */
|
||||
uint8_t MB_Read_Input_Regs(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Write Single Coils (05 - 0x05) */
|
||||
uint8_t MB_Write_Single_Coil(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Write Multiple Coils (15 - 0x0F) */
|
||||
uint8_t MB_Write_Miltuple_Coils(RS_MsgTypeDef *modbus_msg);
|
||||
/* Proccess command Write Multiple Register (16 - 0x10) */
|
||||
uint8_t MB_Write_Miltuple_Regs(RS_MsgTypeDef *modbus_msg);
|
||||
|
||||
/** MODBUS_DATA_ACCESS_FUNCTIONS
|
||||
* @}
|
||||
*/
|
||||
/////////////////////////---FUNCTIONS---/////////////////////////////
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////---CALC DEFINES---//////////////////////////
|
||||
|
||||
|
||||
// TRACES DEFINES
|
||||
#ifndef Trace_MB_UART_Enter
|
||||
#define Trace_MB_UART_Enter()
|
||||
#endif //Trace_MB_UART_Enter
|
||||
|
||||
#ifndef Trace_MB_UART_Exit
|
||||
#define Trace_MB_UART_Exit()
|
||||
#endif //Trace_MB_UART_Exit
|
||||
|
||||
#ifndef Trace_MB_TIM_Enter
|
||||
#define Trace_MB_TIM_Enter()
|
||||
#endif //Trace_MB_TIM_Enter
|
||||
|
||||
#ifndef Trace_MB_TIM_Exit
|
||||
#define Trace_MB_TIM_Exit()
|
||||
#endif //Trace_MB_TIM_Exit
|
||||
|
||||
#endif //__MODBUS_H_
|
44
Modbus/modbus_config.h
Normal file
44
Modbus/modbus_config.h
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file interface_config.h
|
||||
* @brief Конфигурация для модбаса
|
||||
*************************************************************************/
|
||||
#ifndef _MODBUS_CONFIG_H_
|
||||
#define _MODBUS_CONFIG_H_
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
// MODBUS PARAMS
|
||||
#define MODBUS_DEVICE_ID 1 ///< девайс текущего устройства
|
||||
#define MODBUS_TIMEOUT 5000 ///< максимальнйы тайтаут MB в тиках таймера
|
||||
|
||||
// STRING OBJECTS MODBUS
|
||||
#define MODBUS_VENDOR_NAME "NIO-12"
|
||||
#define MODBUS_PRODUCT_CODE ""
|
||||
#define MODBUS_REVISION "Ver. 1.0"
|
||||
#define MODBUS_VENDOR_URL ""
|
||||
#define MODBUS_PRODUCT_NAME ""
|
||||
#define MODBUS_MODEL_NAME "STM32F103"
|
||||
#define MODBUS_USER_APPLICATION_NAME ""
|
||||
|
||||
// PERIPH FUNCTIONS AND HANDLERS
|
||||
#define RS_UART_Init MX_USART1_UART_Init
|
||||
#define RS_UART_DeInit HAL_UART_MspDeInit
|
||||
#define RS_TIM_Init MX_TIM3_Init
|
||||
#define RS_TIM_DeInit HAL_TIM_Base_MspDeInit
|
||||
#define rs_huart huart1
|
||||
#define rs_htim htim3
|
||||
|
||||
|
||||
/**
|
||||
* @brief Поменять комманды 0x03 и 0x04 местами (для LabView терминалки от двигателей)
|
||||
* @details Терминалка от двигателей использует для чтения регистров комманду R_HOLD_REGS вместо R_IN_REGS
|
||||
* Поэтому чтобы считывать Input Regs - надо поменять их местами.
|
||||
*/
|
||||
//#define MODBUS_SWITCH_COMMAND_R_IN_REGS_AND_R_HOLD_REGS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////---CALC DEFINES---//////////////////////////
|
||||
|
||||
|
||||
|
||||
#endif //_MODBUS_CONFIG_H_
|
173
Modbus/modbus_data.h
Normal file
173
Modbus/modbus_data.h
Normal file
@ -0,0 +1,173 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file modbus_data.h
|
||||
* @brief Заголовочный файл с описанием даты MODBUS.
|
||||
* @details Данный файл необходимо подключается в rs_message.h. После rs_message.h
|
||||
* подключается к основному проекту.
|
||||
*
|
||||
* @defgroup MODBUS_DATA
|
||||
* @ingroup MODBUS
|
||||
* @brief Modbus data description
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#ifndef _MODBUS_DATA_H_
|
||||
#define _MODBUS_DATA_H_
|
||||
|
||||
#include "stdint.h"
|
||||
//--------------DEFINES FOR REGISTERS---------------
|
||||
// DEFINES FOR ARRAYS
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_RERISTERS_DEFINES
|
||||
* @ingroup MODBUS_DATA
|
||||
* @brief Defines for registers
|
||||
Структура дефайна адресов
|
||||
@verbatim
|
||||
Для массивов регистров:
|
||||
R_<NAME_ARRAY>_ADDR - модбас адресс первого регистра в массиве
|
||||
R_<NAME_ARRAY>_QNT - количество регистров в массиве
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Регистры хранения
|
||||
*/
|
||||
typedef struct //MB_DataInRegsTypeDef
|
||||
{
|
||||
uint16_t ForwardVoltage;
|
||||
uint16_t ReversePeakVoltage;
|
||||
}MB_DataInRegsTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Входные регистры
|
||||
*/
|
||||
typedef struct //MB_DataInRegsTypeDef
|
||||
{
|
||||
uint16_t TimeForForward;
|
||||
uint16_t TimeForReverse;
|
||||
uint16_t TimeBeforeTest;
|
||||
uint16_t TimeDeadtime;
|
||||
uint16_t TimeBeforePeak;
|
||||
|
||||
uint16_t Adc_PulseWidth;
|
||||
uint16_t Adc_PulseSign;
|
||||
uint16_t Adc_CalibrValue;
|
||||
uint16_t Adc_ZeroValue;
|
||||
uint16_t Adc_U_Calibr;
|
||||
}MB_DataHoldRegsTypeDef;
|
||||
|
||||
|
||||
// DEFINES FOR INPUT REGISTERS ARRAYS
|
||||
#define R_MEASURED_ADDR 0
|
||||
#define R_MEASURED_QNT 2
|
||||
|
||||
// DEFINES FOR HOLDING REGISTERS ARRAYS
|
||||
#define R_SETTINGS_ADDR 0
|
||||
#define R_SETTINGS_QNT 10
|
||||
|
||||
|
||||
// DEFINES FOR REGISTERS LOCAL ADDRESSES
|
||||
//#define R_SET_ERROR(_te_num_) 0
|
||||
|
||||
|
||||
/** MODBUS_DATA_RERISTERS_DEFINES
|
||||
* @}
|
||||
*/
|
||||
|
||||
//----------------DEFINES FOR COILS-----------------
|
||||
/**
|
||||
* @addtogroup MODBUS_DATA_COILS_DEFINES
|
||||
* @ingroup MODBUS_DATA
|
||||
* @brief Defines for coils
|
||||
@verbatim
|
||||
Структура дефайна
|
||||
Для массивов коилов:
|
||||
C_<NAME_ARRAY>_ADDR - модбас адресс первого коила в массиве
|
||||
C_<NAME_ARRAY>_QNT - количество коилов в массиве (минимум 16)
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Коилы
|
||||
*/
|
||||
typedef struct //MB_DataCoilsTypeDef
|
||||
{
|
||||
/* reg 1 - control */
|
||||
unsigned ForwardTest:1;
|
||||
unsigned ReverseTest:1;
|
||||
unsigned StartTest:1;
|
||||
unsigned KeyForwardHiTest:1;
|
||||
unsigned KeyForwardLoTest:1;
|
||||
unsigned KeyReverseHiTest:1;
|
||||
unsigned KeyReverseLoTest:1;
|
||||
|
||||
unsigned reserved:9;
|
||||
|
||||
/* reg 2 - settings */
|
||||
unsigned msTimeForForward_enable:1;
|
||||
unsigned msTimeForReverse_enable:1;
|
||||
unsigned msTimeBeforeTest_enable:1;
|
||||
unsigned msTimeDeadtime_enable:1;
|
||||
unsigned msTimeBeforePeak_enable:1;
|
||||
unsigned reserved2:11;
|
||||
}MB_DataCoilsTypeDef;
|
||||
|
||||
// DEFINES FOR COIL ARRAYS
|
||||
#define C_CONTROL_ADDR 0
|
||||
#define C_CONTROL_QNT 7
|
||||
|
||||
#define C_SETTINGS_ADDR 16
|
||||
#define C_SETTINGS_QNT 5
|
||||
|
||||
/** MODBUS_DATA_COILS_DEFINES
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
//-----------MODBUS DEVICE DATA SETTING-------------
|
||||
// MODBUS DATA STRUCTTURE
|
||||
/**
|
||||
* @brief Структура со всеми регистрами и коилами модбас
|
||||
* @ingroup MODBUS_DATA
|
||||
*/
|
||||
typedef struct // tester modbus data
|
||||
{
|
||||
MB_DataInRegsTypeDef InRegs; ///< Modbus input registers @ref MB_DataInRegsTypeDef
|
||||
|
||||
MB_DataCoilsTypeDef Coils; ///< Modbus coils @ref MB_DataCoilsTypeDef
|
||||
|
||||
MB_DataHoldRegsTypeDef HoldRegs; ///< Modbus holding registers @ref MB_DataHoldRegsTypeDef
|
||||
}MB_DataStructureTypeDef;
|
||||
extern MB_DataStructureTypeDef MB_DATA;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned length;
|
||||
char *name;
|
||||
}MB_DeviceObjectTypeDef;
|
||||
typedef struct
|
||||
{
|
||||
MB_DeviceObjectTypeDef VendorName;
|
||||
MB_DeviceObjectTypeDef ProductCode;
|
||||
MB_DeviceObjectTypeDef Revision;
|
||||
MB_DeviceObjectTypeDef VendorUrl;
|
||||
MB_DeviceObjectTypeDef ProductName;
|
||||
MB_DeviceObjectTypeDef ModelName;
|
||||
MB_DeviceObjectTypeDef UserApplicationName;
|
||||
}MB_DeviceIdentificationTypeDef;
|
||||
void MB_DevoceInentificationInit(void);
|
||||
|
||||
|
||||
#endif //_MODBUS_DATA_H_
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
///////////////////////TEMP/OUTDATE/OTHER////////////////////
|
550
Modbus/rs_message.c
Normal file
550
Modbus/rs_message.c
Normal file
@ -0,0 +1,550 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file rs_message.c
|
||||
* @brief Модуль для реализации протоколов по RS/UART.
|
||||
**************************************************************************\
|
||||
* @details
|
||||
* Данный модуль реализует основные функции для приема и передачи сообщений
|
||||
* по протоколу RS через UART в режиме прерываний. Реализована обработка
|
||||
* приема и передачи данных, управление состояниями RS, а также функции для
|
||||
* инициализации и управления периферией.
|
||||
*
|
||||
* Реализованы следующие функции:
|
||||
* - RS_Receive_IT() — запуск приема данных в прерывании по UART.
|
||||
* - RS_Transmit_IT() — запуск передачи данных в прерывании по UART.
|
||||
* - RS_Init() — инициализация структуры RS и привязка периферии.
|
||||
* - RS_ReInit_UART() — переинициализация UART и перезапуск приема данных.
|
||||
* - RS_Abort() — остановка работы RS/UART с очисткой флагов и структур.
|
||||
* - RS_Handle_Receive_Start() — обработка старта приема данных по RS.
|
||||
*
|
||||
* В модуле также определен буфер RS_Buffer[] для хранения принимаемых/передаваемых данных.
|
||||
*
|
||||
* @note
|
||||
* Для корректной работы модуля предполагается использование соответствующих
|
||||
* обработчиков прерываний UART и таймера (RS_UART_Handler(), RS_TIM_Handler()),
|
||||
* которые надо вызывать с обработчиках используемой периферии
|
||||
|
||||
@verbatim
|
||||
//-------------------Функции-------------------//
|
||||
Functions: users
|
||||
- RS_Parse_Message/RS_Collect_Message Заполнение структуры сообщения и буфера
|
||||
- RS_Response Ответ на сообщение
|
||||
- RS_Define_Size_of_RX_Message Определение размера принимаемых данных
|
||||
|
||||
Functions: general
|
||||
- RS_Receive_IT Ожидание комманды и ответ на неё
|
||||
- RS_Transmit_IT Отправление комманды и ожидание ответа
|
||||
- RS_Init Инициализация переферии и структуры для RS
|
||||
- RS_ReInit_UART Реинициализация UART для RS
|
||||
- RS_Abort Отмена приема/передачи по ЮАРТ
|
||||
- RS_Init Инициализация периферии и modbus handler
|
||||
|
||||
Functions: callback/handler
|
||||
- RS_Handle_Receive_Start Функция для запуска приема или остановки RS
|
||||
- RS_Handle_Transmit_Start Функция для запуска передачи или остановки RS
|
||||
|
||||
- RS_UART_RxCpltCallback Коллбек при окончании приема или передачи
|
||||
RS_UART_TxCpltCallback
|
||||
|
||||
- RS_UART_Handler Обработчик прерывания для UART
|
||||
- RS_TIM_Handler Обработчик прерывания для TIM
|
||||
|
||||
@endverbatim
|
||||
*************************************************************************/
|
||||
#include "rs_message.h"
|
||||
|
||||
uint8_t RS_Buffer[MSG_SIZE_MAX]; // uart buffer
|
||||
|
||||
extern void RS_UART_Init(void);
|
||||
extern void RS_UART_DeInit(UART_HandleTypeDef *huart);
|
||||
extern void RS_TIM_Init(void);
|
||||
extern void RS_TIM_DeInit(TIM_HandleTypeDef *htim);
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//-------------------------GENERAL FUNCTIONS-------------------------
|
||||
/**
|
||||
* @brief Start receive IT.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации приема.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
|
||||
//-------------CHECK RS LINE----------------
|
||||
// check that receive isnt busy
|
||||
if( RS_Is_RX_Busy(hRS) ) // if tx busy - return busy status
|
||||
return RS_BUSY;
|
||||
|
||||
//-----------INITIALIZE RECEIVE-------------
|
||||
// if all OK: start receiving
|
||||
RS_EnableReceive();
|
||||
RS_Set_Busy(hRS); // set RS busy
|
||||
RS_Set_RX_Flags(hRS); // initialize flags for receive
|
||||
hRS->pMessagePtr = RS_msg; // set pointer to message structire for filling it from UARTHandler fucntions
|
||||
|
||||
// start receiving
|
||||
uart_res = HAL_UART_Receive_IT(hRS->huart, hRS->pBufferPtr, RX_FIRST_PART_SIZE); // receive until ByteCnt+1 byte,
|
||||
// then in Callback restart receive for rest bytes
|
||||
|
||||
// if receive isnt started - abort RS
|
||||
if(uart_res != HAL_OK)
|
||||
{
|
||||
RS_RES = RS_Abort(hRS, ABORT_RS);
|
||||
printf_rs_err("\n%d: Error RS: Failed to start RS receiving...", uwTick);
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_RES = RS_OK;
|
||||
printf_rs("\n%d: RS: Start Receiving...", uwTick);
|
||||
}
|
||||
|
||||
hRS->RS_STATUS = RS_RES;
|
||||
return RS_RES; // returns result of receive init
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start transmit IT.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации передачи.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
|
||||
//-------------CHECK RS LINE----------------
|
||||
// check that transmit isnt busy
|
||||
if( RS_Is_TX_Busy(hRS) ) // if tx busy - return busy status
|
||||
return RS_BUSY;
|
||||
// check receive line
|
||||
|
||||
|
||||
//------------COLLECT MESSAGE---------------
|
||||
RS_RES = RS_Collect_Message(hRS, RS_msg, hRS->pBufferPtr);
|
||||
if (RS_RES != RS_OK) // if message isnt collect - stop RS and return error in RS_RES
|
||||
{// need collect message status, so doesnt write abort to RS_RES
|
||||
RS_Abort(hRS, ABORT_RS);
|
||||
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr); // restart receive
|
||||
}
|
||||
else // if collect successful
|
||||
{
|
||||
|
||||
//----------INITIALIZE TRANSMIT-------------
|
||||
RS_EnableTransmit();
|
||||
// for(int i = 0; i < hRS->sRS_Timeout; i++);
|
||||
|
||||
RS_Set_Busy(hRS); // set RS busy
|
||||
RS_Set_TX_Flags(hRS); // initialize flags for transmit IT
|
||||
hRS->pMessagePtr = RS_msg; // set pointer for filling given structure from UARTHandler fucntion
|
||||
|
||||
// if all OK: start transmitting
|
||||
uart_res = HAL_UART_Transmit_IT(hRS->huart, hRS->pBufferPtr, hRS->RS_Message_Size);
|
||||
// if transmit isnt started - abort RS
|
||||
if(uart_res != HAL_OK)
|
||||
{
|
||||
RS_RES = RS_Abort(hRS, ABORT_RS);
|
||||
printf_rs_err("\n%d: Error RS: Failed to start RS transmitting...", uwTick);
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_RES = RS_OK;
|
||||
printf_rs("\n%d: RS: Start Transmitting...", uwTick);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hRS->RS_STATUS = RS_RES;
|
||||
return RS_RES; // returns result of transmit init
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize UART and handle RS stucture.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param suart - указатель на структуру с настройками UART.
|
||||
* @param stim - указатель на структуру с настройками таймера.
|
||||
* @param pRS_BufferPtr - указатель на буффер для приема-передачи по UART. Если он NULL, то поставиться библиотечный буфер.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации.
|
||||
* @note Инициализация перефирии и структуры для приема-передачи по RS.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr)
|
||||
{
|
||||
// check that hRS is defined
|
||||
if (hRS == NULL)
|
||||
return RS_ERR;
|
||||
// check that huart is defined
|
||||
if (huart == NULL)
|
||||
return RS_ERR;
|
||||
// init uart
|
||||
|
||||
// RS_UART_Init();
|
||||
hRS->huart = huart;
|
||||
|
||||
// RS_TIM_Init();
|
||||
hRS->htim = htim;
|
||||
|
||||
if (hRS->sRS_RX_Size_Mode == NULL)
|
||||
return RS_ERR;
|
||||
|
||||
// check that buffer is defined
|
||||
if (hRS->pBufferPtr == NULL)
|
||||
{
|
||||
hRS->pBufferPtr = RS_Buffer; // if no - set default
|
||||
}
|
||||
else
|
||||
hRS->pBufferPtr = pRS_BufferPtr; // if yes - set by user
|
||||
|
||||
return RS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief ReInitialize UART and RS receive.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param suart - указатель на структуру с настройками UART.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации.
|
||||
* @note Реинициализация UART и приема по RS.
|
||||
*/
|
||||
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart)
|
||||
{
|
||||
HAL_StatusTypeDef RS_RES;
|
||||
hRS->f.ReInit_UART = 0;
|
||||
|
||||
// // check is settings are valid
|
||||
// if(Check_UART_Init_Struct(suart) != HAL_OK)
|
||||
// return HAL_ERROR;
|
||||
|
||||
RS_Abort(hRS, ABORT_RS);
|
||||
|
||||
RS_UART_DeInit(huart);
|
||||
|
||||
RS_UART_Init();
|
||||
|
||||
|
||||
RS_Receive_IT(hRS, hRS->pMessagePtr);
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Abort RS/UART.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param AbortMode - выбор, что надо отменить.
|
||||
- ABORT_TX: Отмена передачи по ЮАРТ, с очищением флагов TX,
|
||||
- ABORT_RX: Отмена приема по ЮАРТ, с очищением флагов RX,
|
||||
- ABORT_RX_TX: Отмена приема и передачи по ЮАРТ,
|
||||
- ABORT_RS: Отмена приема-передачи RS, с очищением всей структуры.
|
||||
* @return RS_RES - статус о состоянии RS после аборта.
|
||||
* @note Отмена работы UART в целом или отмена приема/передачи RS.
|
||||
Также очищается хендл hRS.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode)
|
||||
{
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
hRS->htim->Instance->CNT = 0;
|
||||
__HAL_TIM_CLEAR_IT(hRS->htim, TIM_IT_UPDATE);
|
||||
|
||||
if(hRS->sRS_Timeout) // if timeout setted
|
||||
HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout
|
||||
|
||||
if((AbortMode&ABORT_RS) == 0x00)
|
||||
{
|
||||
if((AbortMode&ABORT_RX) == ABORT_RX)
|
||||
{
|
||||
uart_res = HAL_UART_AbortReceive(hRS->huart); // abort receive
|
||||
RS_Reset_RX_Flags(hRS);
|
||||
}
|
||||
|
||||
if((AbortMode&ABORT_TX) == ABORT_TX)
|
||||
{
|
||||
uart_res = HAL_UART_AbortTransmit(hRS->huart); // abort transmit
|
||||
RS_Reset_TX_Flags(hRS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uart_res = HAL_UART_Abort(hRS->huart);
|
||||
RS_Clear_All(hRS);
|
||||
}
|
||||
hRS->RS_STATUS = RS_ABORTED;
|
||||
return RS_ABORTED;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------GENERAL FUNCTIONS-------------------------
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
|
||||
/**
|
||||
* @brief Handle for starting receive.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации приема или окончания общения.
|
||||
* @note Определяет начинать прием команды/ответа или нет.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
|
||||
switch(hRS->sRS_Mode)
|
||||
{
|
||||
case SLAVE_ALWAYS_WAIT: // in slave mode with permanent waiting
|
||||
RS_RES = RS_Receive_IT(hRS, RS_msg); break; // start receiving again
|
||||
case SLAVE_TIMEOUT_WAIT: // in slave mode with timeout waiting (start receiving cmd by request)
|
||||
RS_Set_Free(hRS); RS_RES = RS_OK; break; // end RS communication (set RS unbusy)
|
||||
}
|
||||
|
||||
if(RS_RES != RS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
return RS_RES;
|
||||
}
|
||||
/**
|
||||
* @brief Handle for starting transmit.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о состоянии RS после инициализации передачи.
|
||||
* @note Определяет отвечать ли на команду или нет.
|
||||
*/
|
||||
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
|
||||
switch(hRS->sRS_Mode)
|
||||
{
|
||||
case SLAVE_ALWAYS_WAIT: // in slave mode always response
|
||||
case SLAVE_TIMEOUT_WAIT: // transmit response
|
||||
RS_RES = RS_Transmit_IT(hRS, RS_msg); break;
|
||||
}
|
||||
if(RS_RES != RS_OK)
|
||||
{
|
||||
}
|
||||
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief UART RX Callback: define behaviour after receiving parts of message.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @return RS_RES - статус о состоянии RS после обработки приема.
|
||||
* @note Контролирует прием сообщения: определяет размер принимаемой посылки и обрабатывает его.
|
||||
*/
|
||||
RS_StatusTypeDef RS_UART_RxCpltCallback(RS_HandleTypeDef *hRS)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = 0;
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
|
||||
// if we had received bytes before ByteCnt
|
||||
if((hRS->sRS_RX_Size_Mode == RS_RX_Size_NotConst) && (hRS->f.RX_Half == 0)) // if data size isnt constant and its first half, and
|
||||
{ // First receive part of message, then define size of rest of message, and start receive it
|
||||
hRS->f.RX_Half = 1;
|
||||
//---------------FIND DATA SIZE-----------------
|
||||
uint32_t NuRS_of_Rest_Bytes = 0xFFFF;
|
||||
RS_RES = RS_Define_Size_of_RX_Message(hRS, &NuRS_of_Rest_Bytes);
|
||||
|
||||
|
||||
// if we need to skip this message - restart receive
|
||||
if(RS_RES == RS_SKIP || NuRS_of_Rest_Bytes == 0xFFFF)
|
||||
{
|
||||
RS_Abort(hRS, ABORT_RX);
|
||||
RS_RES = RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
// if there is no bytes to receive
|
||||
if(NuRS_of_Rest_Bytes == 0)
|
||||
{
|
||||
hRS->f.RX_Half = 0;
|
||||
|
||||
//---------PROCESS DATA & ENDING RECEIVING--------
|
||||
RS_Set_RX_End(hRS);
|
||||
|
||||
if(hRS->sRS_Timeout) // if timeout setted
|
||||
HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout
|
||||
|
||||
// parse received data
|
||||
RS_RES = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr); // parse message
|
||||
|
||||
// RESPONSE
|
||||
RS_RES = RS_Response(hRS, hRS->pMessagePtr);
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
|
||||
//-------------START UART RECEIVE---------------
|
||||
uart_res = HAL_UART_Receive_IT(hRS->huart, (hRS->pBufferPtr + RX_FIRST_PART_SIZE), NuRS_of_Rest_Bytes);
|
||||
|
||||
if(uart_res != HAL_OK)
|
||||
{// need uart status, so doesnt write abort to RS_RES
|
||||
RS_RES = RS_Abort(hRS, ABORT_RS);
|
||||
}
|
||||
else
|
||||
RS_RES = RS_OK;
|
||||
}
|
||||
else // if we had received whole message
|
||||
{
|
||||
hRS->f.RX_Half = 0;
|
||||
|
||||
//---------PROCESS DATA & ENDING RECEIVING--------
|
||||
RS_Set_RX_End(hRS);
|
||||
|
||||
if(hRS->sRS_Timeout) // if timeout setted
|
||||
HAL_TIM_Base_Stop_IT(hRS->htim); // stop timeout
|
||||
|
||||
// parse received data
|
||||
RS_RES = RS_Parse_Message(hRS, hRS->pMessagePtr, hRS->pBufferPtr); // parse message
|
||||
|
||||
// RESPONSE
|
||||
RS_RES = RS_Response(hRS, hRS->pMessagePtr);
|
||||
}
|
||||
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief UART TX Callback: define behaviour after transmiting message.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @return RS_RES - статус о состоянии RS после обработки приема.
|
||||
* @note Определяет поведение RS после передачи сообщения.
|
||||
*/
|
||||
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS)
|
||||
{
|
||||
RS_StatusTypeDef RS_RES = RS_OK;
|
||||
HAL_StatusTypeDef uart_res = 0;
|
||||
|
||||
//--------------ENDING TRANSMITTING-------------
|
||||
RS_Set_TX_End(hRS);
|
||||
RS_EnableReceive();
|
||||
// for(int i = 0; i < hRS->sRS_Timeout; i++);
|
||||
|
||||
//-----------START RECEIVING or END RS----------
|
||||
RS_RES = RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||
|
||||
return RS_RES;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handler for UART.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @note Обрабатывает ошибки если есть и вызывает RS Коллбеки.
|
||||
* Добавить вызов этой функции в UARTx_IRQHandler() после HAL_UART_IRQHandler().
|
||||
*/
|
||||
void RS_UART_Handler(RS_HandleTypeDef *hRS)
|
||||
{
|
||||
//-------------CALL RS CALLBACKS------------
|
||||
/* IF NO ERROR OCCURS */
|
||||
if(hRS->huart->ErrorCode == 0)
|
||||
{
|
||||
hRS->htim->Instance->CNT = 0; // reset cnt;
|
||||
/* Start timeout */
|
||||
if(hRS->sRS_Timeout) // if timeout setted
|
||||
if((hRS->huart->RxXferCount+1 == hRS->huart->RxXferSize) && RS_Is_RX_Busy(hRS)) // if first byte is received and receive is active
|
||||
{
|
||||
hRS->htim->Instance->ARR = hRS->sRS_Timeout; // reset cnt;
|
||||
HAL_TIM_Base_Start_IT(hRS->htim);
|
||||
RS_Set_RX_Active_Flags(hRS);
|
||||
}
|
||||
|
||||
/* RX Callback */
|
||||
if (( hRS->huart->RxXferCount == 0U) && RS_Is_RX_Busy(hRS) && // if all bytes are received and receive is active
|
||||
hRS->huart->RxState != HAL_UART_STATE_BUSY_RX) // also check that receive "REALLY" isnt busy
|
||||
RS_UART_RxCpltCallback(hRS);
|
||||
|
||||
/* TX Callback */
|
||||
if (( hRS->huart->TxXferCount == 0U) && RS_Is_TX_Busy(hRS) && // if all bytes are transmited and transmit is active
|
||||
hRS->huart->gState != HAL_UART_STATE_BUSY_TX) // also check that receive "REALLY" isnt busy
|
||||
RS_UART_TxCpltCallback(hRS);
|
||||
}
|
||||
//----------------ERRORS HANDLER----------------
|
||||
else
|
||||
{
|
||||
/* de-init uart transfer */
|
||||
RS_Abort(hRS, ABORT_RS);
|
||||
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||
// later, maybe, will be added specific handlers for err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handler for TIM.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @note Попадание сюда = таймаут и перезапуск RS приема
|
||||
* Добавить вызов этой функции в TIMx_IRQHandler() после HAL_TIM_IRQHandler().
|
||||
*/
|
||||
void RS_TIM_Handler(RS_HandleTypeDef *hRS)
|
||||
{
|
||||
HAL_TIM_Base_Stop_IT(hRS->htim);
|
||||
RS_Abort(hRS, ABORT_RS);
|
||||
|
||||
RS_Handle_Receive_Start(hRS, hRS->pMessagePtr);
|
||||
}
|
||||
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
|
||||
//-------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//--------------WEAK PROTOTYPES FOR PROCESSING MESSAGE---------------
|
||||
/**
|
||||
* @brief Respond accord to received message.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @return RS_RES - статус о результате ответа на комманду.
|
||||
* @note Обработка принятой комманды и ответ на неё.
|
||||
*/
|
||||
__weak RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg)
|
||||
{
|
||||
/* Redefine function for user purposes */
|
||||
return RS_ERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Collect message in buffer to transmit it.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @param msg_uart_buff - указатель на буффер UART.
|
||||
* @return RS_RES - статус о результате заполнения буфера.
|
||||
* @note Заполнение буффера UART из структуры сообщения.
|
||||
*/
|
||||
__weak RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
|
||||
{
|
||||
/* Redefine function for user purposes */
|
||||
return RS_ERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse message from buffer to process it.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param RS_msg - указатель на структуру сообщения.
|
||||
* @param msg_uart_buff - указатель на буффер UART.
|
||||
* @return RS_RES - статус о результате заполнения структуры.
|
||||
* @note Заполнение структуры сообщения из буффера UART.
|
||||
*/
|
||||
__weak RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff)
|
||||
{
|
||||
/* Redefine function for user purposes */
|
||||
return RS_ERR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Define size of RX Message that need to be received.
|
||||
* @param hRS - указатель на хендлер RS.
|
||||
* @param rx_data_size - указатель на переменную для записи кол-ва байт для принятия.
|
||||
* @return RS_RES - статус о корректности рассчета кол-ва байт для принятия.
|
||||
* @note Определение сколько байтов надо принять по протоколу.
|
||||
*/
|
||||
__weak RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hRS, uint32_t *rx_data_size)
|
||||
{
|
||||
/* Redefine function for user purposes */
|
||||
return RS_ERR;
|
||||
}
|
||||
//--------------WEAK PROTOTYPES FOR PROCESSING MESSAGE---------------
|
||||
//-------------------------------------------------------------------
|
257
Modbus/rs_message.h
Normal file
257
Modbus/rs_message.h
Normal file
@ -0,0 +1,257 @@
|
||||
/**
|
||||
**************************************************************************
|
||||
* @file rs_message.h
|
||||
* @brief Заголовочный файл для модуля реализации протоколов по RS/UART.
|
||||
**************************************************************************
|
||||
* @defgroup RS_TOOLS
|
||||
* @brief Всякое для работы по UART/RS
|
||||
**************************************************************************
|
||||
@details
|
||||
**************************************************************************
|
||||
Для настройки RS/UART под нужный протокол, необходимо:
|
||||
- Определить структуру сообщения RS_MsgTypeDef и
|
||||
дефайны RX_FIRST_PART_SIZE и MSG_SIZE_MAX.
|
||||
- Подключить этот файл в раздел rs_message.h.
|
||||
- Определить функции для обработки сообщения: RS_Parse_Message(),
|
||||
RS_Collect_Message(), RS_Response(), RS_Define_Size_of_RX_Message()
|
||||
- Добавить UART/TIM Handler в Хендлер используемых UART/TIM.
|
||||
|
||||
Так же данный модуль использует счетчики
|
||||
**************************************************************************
|
||||
@verbatim
|
||||
Визуальное описание. Форматирование сохраняется как в коде.
|
||||
@endverbatim
|
||||
*************************************************************************/
|
||||
#ifndef __RS_LIB_H_
|
||||
#define __RS_LIB_H_
|
||||
|
||||
#include "modbus.h"
|
||||
|
||||
#include "crc_algs.h"
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////---DEFINES---////////////////////////////
|
||||
/* Check that all defines required by RS are defined */
|
||||
#ifndef MSG_SIZE_MAX
|
||||
#error Define MSG_SIZE_MAX (Maximum size of message). This is necessary to create buffer for UART.
|
||||
#endif
|
||||
|
||||
#ifndef RX_FIRST_PART_SIZE
|
||||
#error Define RX_FIRST_PART_SIZE (Size of first part of message). This is necessary to receive the first part of the message, from which determine the size of the remaining part of the message.
|
||||
#endif
|
||||
|
||||
|
||||
/* Clear message-uart buffer */
|
||||
#define RS_Clear_Buff(_buff_) for(int i=0; i<MSG_SIZE_MAX;i++) _buff_[i] = NULL
|
||||
|
||||
/* Set/Reset flags */
|
||||
#define RS_Set_Free(_hRS_) _hRS_->f.RS_Busy = 0
|
||||
#define RS_Set_Busy(_hRS_) _hRS_->f.RS_Busy = 1
|
||||
|
||||
#define RS_Set_RX_Flags(_hRS_) _hRS_->f.RX_Busy = 1; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
|
||||
#define RS_Set_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 1
|
||||
|
||||
|
||||
#define RS_Set_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 1; _hRS_->f.TX_Done = 0
|
||||
|
||||
#define RS_Reset_RX_Active_Flags(_hRS_) _hRS_->f.RX_Ongoing = 0
|
||||
#define RS_Reset_RX_Flags(_hRS_) RS_Reset_RX_Active_Flags(_hRS_); _hRS_->f.RX_Busy = 0; _hRS_->f.RX_Done = 0; _hRS_->f.RX_Half = 0
|
||||
#define RS_Reset_TX_Flags(_hRS_) _hRS_->f.TX_Busy = 0; _hRS_->f.TX_Done = 0
|
||||
|
||||
#define RS_Set_RX_End_Flag(_hRS_) _hRS_->f.RX_Done = 1;
|
||||
#define RS_Set_TX_End_Flag(_hRS_) _hRS_->f.TX_Done = 1
|
||||
|
||||
#define RS_Set_RX_End(_hRS_) RS_Reset_RX_Flags(_hRS_); RS_Set_RX_End_Flag(_hRS_)
|
||||
#define RS_Set_TX_End(_hRS_) RS_Reset_TX_Flags(_hRS_); RS_Set_TX_End_Flag(_hRS_)
|
||||
|
||||
/* Clear all RS stuff */
|
||||
#define RS_Clear_All(_hRS_) RS_Clear_Buff(_hRS_->pBufferPtr); RS_Reset_RX_Flags(_hRS_); RS_Reset_TX_Flags(_hRS_);
|
||||
|
||||
//#define MB_Is_RX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_RX)
|
||||
//#define MB_Is_TX_Busy(_hRS_) ((_hRS_->huart->gState&HAL_USART_STATE_BUSY_RX) == HAL_USART_STATE_BUSY_TX)
|
||||
#define RS_Is_RX_Busy(_hRS_) (_hRS_->f.RX_Busy == 1)
|
||||
#define RS_Is_TX_Busy(_hRS_) (_hRS_->f.TX_Busy == 1)
|
||||
|
||||
|
||||
#ifndef RS_EnableReceive
|
||||
#define RS_EnableReceive()
|
||||
#endif
|
||||
#ifndef RS_EnableTransmit
|
||||
#define RS_EnableTransmit()
|
||||
#endif
|
||||
////////////////////////////---DEFINES---////////////////////////////
|
||||
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
|
||||
//------------------ENUMERATIONS--------------------
|
||||
/** @brief Enums for respond CMD about RS status */
|
||||
typedef enum // RS_StatusTypeDef
|
||||
{
|
||||
/* IN-CODE STATUS (start from 0x01, and goes up)*/
|
||||
/*0x01*/ RS_OK = 0x01,
|
||||
/*0x02*/ RS_ERR,
|
||||
/*0x03*/ RS_ABORTED,
|
||||
/*0x04*/ RS_BUSY,
|
||||
/*0x05*/ RS_SKIP,
|
||||
|
||||
/*0x06*/ RS_COLLECT_MSG_ERR,
|
||||
/*0x07*/ RS_PARSE_MSG_ERR,
|
||||
|
||||
// reserved values
|
||||
// /*0x00*/ RS_UNKNOWN_ERR = 0x00, ///< reserved for case, if no one error founded (nothing changed response from zero)
|
||||
}RS_StatusTypeDef;
|
||||
|
||||
|
||||
/** @brief Enums for RS Modes */
|
||||
typedef enum // RS_ModeTypeDef
|
||||
{
|
||||
SLAVE_ALWAYS_WAIT = 0x01, ///< Slave mode with infinity waiting
|
||||
SLAVE_TIMEOUT_WAIT = 0x02, ///< Slave mode with waiting with timeout
|
||||
// MASTER = 0x03, ///< Master mode
|
||||
}RS_ModeTypeDef;
|
||||
|
||||
/** @brief Enums for RS UART Modes */
|
||||
typedef enum // RS_ITModeTypeDef
|
||||
{
|
||||
BLCK_MODE = 0x00, ///< Blocking mode
|
||||
IT_MODE = 0x01, ///< Interrupt mode
|
||||
}RS_ITModeTypeDef;
|
||||
|
||||
/** @brief Enums for Abort modes */
|
||||
typedef enum // RS_AbortTypeDef
|
||||
{
|
||||
ABORT_TX = 0x01, ///< Abort transmit
|
||||
ABORT_RX = 0x02, ///< Abort receive
|
||||
ABORT_RX_TX = 0x03, ///< Abort receive and transmit
|
||||
ABORT_RS = 0x04, ///< Abort uart and reset RS structure
|
||||
}RS_AbortTypeDef;
|
||||
|
||||
/** @brief Enums for RX Size modes */
|
||||
typedef enum // RS_RXSizeTypeDef
|
||||
{
|
||||
RS_RX_Size_Const = 0x01, ///< size of receiving message is constant
|
||||
RS_RX_Size_NotConst = 0x02, ///< size of receiving message isnt constant
|
||||
}RS_RXSizeTypeDef;
|
||||
|
||||
|
||||
//-----------STRUCTURE FOR HANDLE RS------------
|
||||
/** @brief Struct for flags RS */
|
||||
typedef struct
|
||||
{
|
||||
unsigned RX_Half:1; ///< flag: 0 - receiving msg before ByteCnt, 0 - receiving msg after ByteCnt
|
||||
|
||||
unsigned RS_Busy:1; ///< flag: 1 - RS is busy, 0 - RS isnt busy
|
||||
unsigned RX_Ongoing:1; ///< flag: 1 - receiving data right now, 0 - waiting for receiving data
|
||||
|
||||
unsigned RX_Busy:1; ///< flag: 1 - receiving is active, 0 - receiving isnt active
|
||||
unsigned TX_Busy:1; ///< flag: 1 - transmiting is active, 0 - transmiting isnt active
|
||||
|
||||
unsigned RX_Done:1; ///< flag: 1 - receiving is done, 0 - receiving isnt done
|
||||
unsigned TX_Done:1; ///< flag: 1 - transmiting is done, 0 - transmiting isnt done
|
||||
|
||||
// setted by user
|
||||
unsigned MessageHandled:1; ///< flag: 1 - RS command is handled, 0 - RS command isnt handled yet
|
||||
unsigned EchoResponse:1; ///< flag: 1 - response with received msg, 0 - response with own msg
|
||||
unsigned DeferredResponse:1; ///< flag: 1 - response not in interrupt, 0 - response in interrupt
|
||||
unsigned ReInit_UART:1; ///< flag: 1 - need to reinitialize uart, 0 - nothing
|
||||
}RS_FlagsTypeDef;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Handle for RS communication.
|
||||
* @note Prefixes: h - handle, s - settings, f - flag
|
||||
*/
|
||||
typedef struct // RS_HandleTypeDef
|
||||
{
|
||||
/* MESSAGE */
|
||||
uint8_t ID; ///< ID of RS "channel"
|
||||
RS_MsgTypeDef *pMessagePtr; ///< pointer to message struct
|
||||
uint8_t *pBufferPtr; ///< pointer to message buffer
|
||||
uint32_t RS_Message_Size; ///< size of whole message, not only data
|
||||
|
||||
/* HANDLERS and SETTINGS */
|
||||
UART_HandleTypeDef *huart; ///< handler for used uart
|
||||
TIM_HandleTypeDef *htim; ///< handler for used tim
|
||||
RS_ModeTypeDef sRS_Mode; ///< setting: slave or master @ref RS_ModeTypeDef
|
||||
RS_ITModeTypeDef sRS_IT_Mode; ///< setting: 1 - IT mode, 0 - Blocking mode
|
||||
uint16_t sRS_Timeout; ///< setting: timeout in ms
|
||||
RS_RXSizeTypeDef sRS_RX_Size_Mode; ///< setting: 1 - not const, 0 - const
|
||||
|
||||
/* FLAGS */
|
||||
RS_FlagsTypeDef f; ///< These flags for controling receive/transmit
|
||||
|
||||
/* RS STATUS */
|
||||
RS_StatusTypeDef RS_STATUS; ///< RS status
|
||||
}RS_HandleTypeDef;
|
||||
extern RS_HandleTypeDef hmodbus1;
|
||||
|
||||
|
||||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////---FUNCTIONS---///////////////////////////
|
||||
//----------------FUNCTIONS FOR PROCESSING MESSAGE-------------------
|
||||
/*--------------------Defined by users purposes--------------------*/
|
||||
/* Respond accord to received message */
|
||||
RS_StatusTypeDef RS_Response(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
|
||||
/* Collect message in buffer to transmit it */
|
||||
RS_StatusTypeDef RS_Collect_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
|
||||
|
||||
/* Parse message from buffer to process it */
|
||||
RS_StatusTypeDef RS_Parse_Message(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg, uint8_t *msg_uart_buff);
|
||||
|
||||
/* Define size of RX Message that need to be received */
|
||||
RS_StatusTypeDef RS_Define_Size_of_RX_Message(RS_HandleTypeDef *hRS, uint32_t *rx_data_size);
|
||||
|
||||
|
||||
//-------------------------GENERAL FUNCTIONS-------------------------
|
||||
/*-----------------Should be called from main code-----------------*/
|
||||
/* Start receive IT */
|
||||
RS_StatusTypeDef RS_Receive_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
|
||||
/* Start transmit IT */
|
||||
RS_StatusTypeDef RS_Transmit_IT(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
|
||||
/* Initialize UART and handle RS stucture */
|
||||
RS_StatusTypeDef RS_Init(RS_HandleTypeDef *hRS, UART_HandleTypeDef *huart, TIM_HandleTypeDef *htim, uint8_t *pRS_BufferPtr);
|
||||
|
||||
/* ReInitialize UART and RS receive */
|
||||
HAL_StatusTypeDef RS_ReInit_UART(RS_HandleTypeDef *hRS, UART_HandleTypeDef *suart);
|
||||
|
||||
/* Abort RS/UART */
|
||||
RS_StatusTypeDef RS_Abort(RS_HandleTypeDef *hRS, RS_AbortTypeDef AbortMode);
|
||||
//-------------------------GENERAL FUNCTIONS-------------------------
|
||||
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
|
||||
/* Handle for starting receive */
|
||||
RS_StatusTypeDef RS_Handle_Receive_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
/* Handle for starting transmit */
|
||||
RS_StatusTypeDef RS_Handle_Transmit_Start(RS_HandleTypeDef *hRS, RS_MsgTypeDef *RS_msg);
|
||||
/* UART RX Callback: define behaviour after receiving parts of message */
|
||||
RS_StatusTypeDef RS_UART_RxCpltCallback(RS_HandleTypeDef *hRS);
|
||||
/* UART TX Callback: define behaviour after transmiting message */
|
||||
RS_StatusTypeDef RS_UART_TxCpltCallback(RS_HandleTypeDef *hRS);
|
||||
/* Handler for UART */
|
||||
void RS_UART_Handler(RS_HandleTypeDef *hRS);
|
||||
/* Handler for TIM */
|
||||
void RS_TIM_Handler(RS_HandleTypeDef *hRS);
|
||||
//--------------------CALLBACK/HANDLER FUNCTIONS---------------------
|
||||
///////////////////////////---FUNCTIONS---///////////////////////////
|
||||
|
||||
|
||||
#ifndef printf_rs_err
|
||||
#define printf_rs_err(...)
|
||||
#endif
|
||||
|
||||
#ifndef printf_rs
|
||||
#define printf_rs(...)
|
||||
#endif
|
||||
#endif // __RS_LIB_H_
|
36
STM32F103_Example/.mxproject
Normal file
36
STM32F103_Example/.mxproject
Normal file
@ -0,0 +1,36 @@
|
||||
[PreviousLibFiles]
|
||||
LibFiles=Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_tim_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_tim.h;Drivers\STM32F1xx_HAL_Driver\Inc\Legacy\stm32_hal_legacy.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_def.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_rcc_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_bus.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_rcc.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_system.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_utils.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_gpio_ex.h;Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_gpio.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_dma.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_cortex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_pwr.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_flash_ex.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_exti.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_hal_uart.h;Drivers\STM32F1xx_HAL_Driver\Inc\stm32f1xx_ll_usart.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f103xb.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Include\system_stm32f1xx.h;Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;Drivers\CMSIS\Include\cmsis_armcc.h;Drivers\CMSIS\Include\cmsis_armclang.h;Drivers\CMSIS\Include\cmsis_compiler.h;Drivers\CMSIS\Include\cmsis_gcc.h;Drivers\CMSIS\Include\cmsis_iccarm.h;Drivers\CMSIS\Include\cmsis_version.h;Drivers\CMSIS\Include\core_armv8mbl.h;Drivers\CMSIS\Include\core_armv8mml.h;Drivers\CMSIS\Include\core_cm0.h;Drivers\CMSIS\Include\core_cm0plus.h;Drivers\CMSIS\Include\core_cm1.h;Drivers\CMSIS\Include\core_cm23.h;Drivers\CMSIS\Include\core_cm3.h;Drivers\CMSIS\Include\core_cm33.h;Drivers\CMSIS\Include\core_cm4.h;Drivers\CMSIS\Include\core_cm7.h;Drivers\CMSIS\Include\core_sc000.h;Drivers\CMSIS\Include\core_sc300.h;Drivers\CMSIS\Include\mpu_armv7.h;Drivers\CMSIS\Include\mpu_armv8.h;Drivers\CMSIS\Include\tz_context.h;
|
||||
|
||||
[PreviousUsedIarFiles]
|
||||
SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\usart.c;..\Core\Src\stm32f1xx_it.c;..\Core\Src\stm32f1xx_hal_msp.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\Core\Src\system_stm32f1xx.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\Core\Src\system_stm32f1xx.c;;;
|
||||
HeaderPath=..\Drivers\STM32F1xx_HAL_Driver\Inc;..\Drivers\STM32F1xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F1xx\Include;..\Drivers\CMSIS\Include;..\Core\Inc;
|
||||
CDefines=USE_HAL_DRIVER;STM32F103xB;USE_HAL_DRIVER;USE_HAL_DRIVER;
|
||||
|
||||
[PreviousUsedKeilFiles]
|
||||
SourceFiles=..\Core\Src\main.c;..\Core\Src\gpio.c;..\Core\Src\tim.c;..\Core\Src\usart.c;..\Core\Src\stm32f1xx_it.c;..\Core\Src\stm32f1xx_hal_msp.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\Core\Src\system_stm32f1xx.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_tim_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_rcc_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_gpio.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_dma.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_cortex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_pwr.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_flash_ex.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_exti.c;..\Drivers\STM32F1xx_HAL_Driver\Src\stm32f1xx_hal_uart.c;..\Drivers\CMSIS\Device\ST\STM32F1xx\Source\Templates\system_stm32f1xx.c;..\Core\Src\system_stm32f1xx.c;;;
|
||||
HeaderPath=..\Drivers\STM32F1xx_HAL_Driver\Inc;..\Drivers\STM32F1xx_HAL_Driver\Inc\Legacy;..\Drivers\CMSIS\Device\ST\STM32F1xx\Include;..\Drivers\CMSIS\Include;..\Core\Inc;
|
||||
CDefines=USE_HAL_DRIVER;STM32F103xB;USE_HAL_DRIVER;USE_HAL_DRIVER;
|
||||
|
||||
[PreviousGenFiles]
|
||||
AdvancedFolderStructure=true
|
||||
HeaderFileListSize=6
|
||||
HeaderFiles#0=..\Core\Inc\gpio.h
|
||||
HeaderFiles#1=..\Core\Inc\tim.h
|
||||
HeaderFiles#2=..\Core\Inc\usart.h
|
||||
HeaderFiles#3=..\Core\Inc\stm32f1xx_it.h
|
||||
HeaderFiles#4=..\Core\Inc\stm32f1xx_hal_conf.h
|
||||
HeaderFiles#5=..\Core\Inc\main.h
|
||||
HeaderFolderListSize=1
|
||||
HeaderPath#0=..\Core\Inc
|
||||
HeaderFiles=;
|
||||
SourceFileListSize=6
|
||||
SourceFiles#0=..\Core\Src\gpio.c
|
||||
SourceFiles#1=..\Core\Src\tim.c
|
||||
SourceFiles#2=..\Core\Src\usart.c
|
||||
SourceFiles#3=..\Core\Src\stm32f1xx_it.c
|
||||
SourceFiles#4=..\Core\Src\stm32f1xx_hal_msp.c
|
||||
SourceFiles#5=..\Core\Src\main.c
|
||||
SourceFolderListSize=1
|
||||
SourcePath#0=..\Core\Src
|
||||
SourceFiles=;
|
||||
|
49
STM32F103_Example/Core/Inc/gpio.h
Normal file
49
STM32F103_Example/Core/Inc/gpio.h
Normal file
@ -0,0 +1,49 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file gpio.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the gpio.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __GPIO_H__
|
||||
#define __GPIO_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_GPIO_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*__ GPIO_H__ */
|
||||
|
69
STM32F103_Example/Core/Inc/main.h
Normal file
69
STM32F103_Example/Core/Inc/main.h
Normal file
@ -0,0 +1,69 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.h
|
||||
* @brief : Header for main.c file.
|
||||
* This file contains the common defines of the application.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __MAIN_H
|
||||
#define __MAIN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f1xx_hal.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void Error_Handler(void);
|
||||
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
/* Private defines -----------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __MAIN_H */
|
391
STM32F103_Example/Core/Inc/stm32f1xx_hal_conf.h
Normal file
391
STM32F103_Example/Core/Inc/stm32f1xx_hal_conf.h
Normal file
@ -0,0 +1,391 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_conf.h
|
||||
* @brief HAL configuration file.
|
||||
******************************************************************************
|
||||
* @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.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F1xx_HAL_CONF_H
|
||||
#define __STM32F1xx_HAL_CONF_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
|
||||
/* ########################## Module Selection ############################## */
|
||||
/**
|
||||
* @brief This is the list of modules to be used in the HAL driver
|
||||
*/
|
||||
|
||||
#define HAL_MODULE_ENABLED
|
||||
/*#define HAL_ADC_MODULE_ENABLED */
|
||||
/*#define HAL_CRYP_MODULE_ENABLED */
|
||||
/*#define HAL_CAN_MODULE_ENABLED */
|
||||
/*#define HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
/*#define HAL_CEC_MODULE_ENABLED */
|
||||
/*#define HAL_CORTEX_MODULE_ENABLED */
|
||||
/*#define HAL_CRC_MODULE_ENABLED */
|
||||
/*#define HAL_DAC_MODULE_ENABLED */
|
||||
/*#define HAL_DMA_MODULE_ENABLED */
|
||||
/*#define HAL_ETH_MODULE_ENABLED */
|
||||
/*#define HAL_FLASH_MODULE_ENABLED */
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
/*#define HAL_I2C_MODULE_ENABLED */
|
||||
/*#define HAL_I2S_MODULE_ENABLED */
|
||||
/*#define HAL_IRDA_MODULE_ENABLED */
|
||||
/*#define HAL_IWDG_MODULE_ENABLED */
|
||||
/*#define HAL_NOR_MODULE_ENABLED */
|
||||
/*#define HAL_NAND_MODULE_ENABLED */
|
||||
/*#define HAL_PCCARD_MODULE_ENABLED */
|
||||
/*#define HAL_PCD_MODULE_ENABLED */
|
||||
/*#define HAL_HCD_MODULE_ENABLED */
|
||||
/*#define HAL_PWR_MODULE_ENABLED */
|
||||
/*#define HAL_RCC_MODULE_ENABLED */
|
||||
/*#define HAL_RTC_MODULE_ENABLED */
|
||||
/*#define HAL_SD_MODULE_ENABLED */
|
||||
/*#define HAL_MMC_MODULE_ENABLED */
|
||||
/*#define HAL_SDRAM_MODULE_ENABLED */
|
||||
/*#define HAL_SMARTCARD_MODULE_ENABLED */
|
||||
/*#define HAL_SPI_MODULE_ENABLED */
|
||||
/*#define HAL_SRAM_MODULE_ENABLED */
|
||||
#define HAL_TIM_MODULE_ENABLED
|
||||
#define HAL_UART_MODULE_ENABLED
|
||||
/*#define HAL_USART_MODULE_ENABLED */
|
||||
/*#define HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#define HAL_CORTEX_MODULE_ENABLED
|
||||
#define HAL_DMA_MODULE_ENABLED
|
||||
#define HAL_FLASH_MODULE_ENABLED
|
||||
#define HAL_EXTI_MODULE_ENABLED
|
||||
#define HAL_GPIO_MODULE_ENABLED
|
||||
#define HAL_PWR_MODULE_ENABLED
|
||||
#define HAL_RCC_MODULE_ENABLED
|
||||
|
||||
/* ########################## Oscillator Values adaptation ####################*/
|
||||
/**
|
||||
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSE is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSE_STARTUP_TIMEOUT)
|
||||
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
|
||||
#endif /* HSE_STARTUP_TIMEOUT */
|
||||
|
||||
/**
|
||||
* @brief Internal High Speed oscillator (HSI) value.
|
||||
* This value is used by the RCC HAL module to compute the system frequency
|
||||
* (when HSI is used as system clock source, directly or through the PLL).
|
||||
*/
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz*/
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/**
|
||||
* @brief Internal Low Speed oscillator (LSI) value.
|
||||
*/
|
||||
#if !defined (LSI_VALUE)
|
||||
#define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */
|
||||
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
|
||||
The real value may vary depending on the variations
|
||||
in voltage and temperature. */
|
||||
|
||||
/**
|
||||
* @brief External Low Speed oscillator (LSE) value.
|
||||
* This value is used by the UART, RTC HAL module to compute the system frequency
|
||||
*/
|
||||
#if !defined (LSE_VALUE)
|
||||
#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/
|
||||
#endif /* LSE_VALUE */
|
||||
|
||||
#if !defined (LSE_STARTUP_TIMEOUT)
|
||||
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
|
||||
#endif /* LSE_STARTUP_TIMEOUT */
|
||||
|
||||
/* Tip: To avoid modifying this file each time you need to use different HSE,
|
||||
=== you can define the HSE value in your toolchain compiler preprocessor. */
|
||||
|
||||
/* ########################### System Configuration ######################### */
|
||||
/**
|
||||
* @brief This is the HAL system configuration section
|
||||
*/
|
||||
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
|
||||
#define TICK_INT_PRIORITY 15U /*!< tick interrupt priority (lowest by default) */
|
||||
#define USE_RTOS 0U
|
||||
#define PREFETCH_ENABLE 1U
|
||||
|
||||
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
|
||||
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
|
||||
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
|
||||
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
|
||||
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
|
||||
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
|
||||
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
|
||||
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
|
||||
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
|
||||
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
|
||||
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
|
||||
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
|
||||
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
|
||||
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
|
||||
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
|
||||
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
|
||||
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
|
||||
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
|
||||
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
|
||||
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
|
||||
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
|
||||
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
|
||||
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
|
||||
|
||||
/* ########################## Assert Selection ############################## */
|
||||
/**
|
||||
* @brief Uncomment the line below to expanse the "assert_param" macro in the
|
||||
* HAL drivers code
|
||||
*/
|
||||
/* #define USE_FULL_ASSERT 1U */
|
||||
|
||||
/* ################## Ethernet peripheral configuration ##################### */
|
||||
|
||||
/* Section 1 : Ethernet peripheral configuration */
|
||||
|
||||
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
|
||||
#define MAC_ADDR0 2U
|
||||
#define MAC_ADDR1 0U
|
||||
#define MAC_ADDR2 0U
|
||||
#define MAC_ADDR3 0U
|
||||
#define MAC_ADDR4 0U
|
||||
#define MAC_ADDR5 0U
|
||||
|
||||
/* Definition of the Ethernet driver buffers size and count */
|
||||
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
|
||||
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
|
||||
#define ETH_RXBUFNB 8U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
|
||||
#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
|
||||
|
||||
/* Section 2: PHY configuration section */
|
||||
|
||||
/* DP83848_PHY_ADDRESS Address*/
|
||||
#define DP83848_PHY_ADDRESS 0x01U
|
||||
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
|
||||
#define PHY_RESET_DELAY 0x000000FFU
|
||||
/* PHY Configuration delay */
|
||||
#define PHY_CONFIG_DELAY 0x00000FFFU
|
||||
|
||||
#define PHY_READ_TO 0x0000FFFFU
|
||||
#define PHY_WRITE_TO 0x0000FFFFU
|
||||
|
||||
/* Section 3: Common PHY Registers */
|
||||
|
||||
#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
|
||||
#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
|
||||
|
||||
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
|
||||
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
|
||||
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
|
||||
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
|
||||
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
|
||||
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
|
||||
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
|
||||
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
|
||||
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
|
||||
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
|
||||
|
||||
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
|
||||
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
|
||||
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
|
||||
|
||||
/* Section 4: Extended PHY Registers */
|
||||
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
|
||||
|
||||
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
|
||||
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
|
||||
|
||||
/* ################## SPI peripheral configuration ########################## */
|
||||
|
||||
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
|
||||
* Activated: CRC code is present inside driver
|
||||
* Deactivated: CRC code cleaned from driver
|
||||
*/
|
||||
|
||||
#define USE_SPI_CRC 0U
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
/**
|
||||
* @brief Include module's header file
|
||||
*/
|
||||
|
||||
#ifdef HAL_RCC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_rcc.h"
|
||||
#endif /* HAL_RCC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_GPIO_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_gpio.h"
|
||||
#endif /* HAL_GPIO_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_EXTI_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_exti.h"
|
||||
#endif /* HAL_EXTI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DMA_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_dma.h"
|
||||
#endif /* HAL_DMA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ETH_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_eth.h"
|
||||
#endif /* HAL_ETH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_can.h"
|
||||
#endif /* HAL_CAN_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
|
||||
#include "Legacy/stm32f1xx_hal_can_legacy.h"
|
||||
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CEC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_cec.h"
|
||||
#endif /* HAL_CEC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CORTEX_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_cortex.h"
|
||||
#endif /* HAL_CORTEX_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_ADC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_adc.h"
|
||||
#endif /* HAL_ADC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_crc.h"
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_DAC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_dac.h"
|
||||
#endif /* HAL_DAC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_FLASH_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_flash.h"
|
||||
#endif /* HAL_FLASH_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SRAM_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_sram.h"
|
||||
#endif /* HAL_SRAM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NOR_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_nor.h"
|
||||
#endif /* HAL_NOR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2C_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_i2c.h"
|
||||
#endif /* HAL_I2C_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_I2S_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_i2s.h"
|
||||
#endif /* HAL_I2S_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IWDG_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_iwdg.h"
|
||||
#endif /* HAL_IWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PWR_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_pwr.h"
|
||||
#endif /* HAL_PWR_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_RTC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_rtc.h"
|
||||
#endif /* HAL_RTC_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCCARD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_pccard.h"
|
||||
#endif /* HAL_PCCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_sd.h"
|
||||
#endif /* HAL_SD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_NAND_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_nand.h"
|
||||
#endif /* HAL_NAND_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SPI_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_spi.h"
|
||||
#endif /* HAL_SPI_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_TIM_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_tim.h"
|
||||
#endif /* HAL_TIM_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_UART_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_uart.h"
|
||||
#endif /* HAL_UART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_USART_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_usart.h"
|
||||
#endif /* HAL_USART_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_IRDA_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_irda.h"
|
||||
#endif /* HAL_IRDA_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_SMARTCARD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_smartcard.h"
|
||||
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_WWDG_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_wwdg.h"
|
||||
#endif /* HAL_WWDG_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_PCD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_pcd.h"
|
||||
#endif /* HAL_PCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_HCD_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_hcd.h"
|
||||
#endif /* HAL_HCD_MODULE_ENABLED */
|
||||
|
||||
#ifdef HAL_MMC_MODULE_ENABLED
|
||||
#include "stm32f1xx_hal_mmc.h"
|
||||
#endif /* HAL_MMC_MODULE_ENABLED */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
#ifdef USE_FULL_ASSERT
|
||||
/**
|
||||
* @brief The assert_param macro is used for function's parameters check.
|
||||
* @param expr If expr is false, it calls assert_failed function
|
||||
* which reports the name of the source file and the source
|
||||
* line number of the call that failed.
|
||||
* If expr is true, it returns no value.
|
||||
* @retval None
|
||||
*/
|
||||
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
|
||||
/* Exported functions ------------------------------------------------------- */
|
||||
void assert_failed(uint8_t* file, uint32_t line);
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F1xx_HAL_CONF_H */
|
||||
|
66
STM32F103_Example/Core/Inc/stm32f1xx_it.h
Normal file
66
STM32F103_Example/Core/Inc/stm32f1xx_it.h
Normal file
@ -0,0 +1,66 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_it.h
|
||||
* @brief This file contains the headers of the interrupt handlers.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 */
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __STM32F1xx_IT_H
|
||||
#define __STM32F1xx_IT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN ET */
|
||||
|
||||
/* USER CODE END ET */
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EC */
|
||||
|
||||
/* USER CODE END EC */
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN EM */
|
||||
|
||||
/* USER CODE END EM */
|
||||
|
||||
/* Exported functions prototypes ---------------------------------------------*/
|
||||
void NMI_Handler(void);
|
||||
void HardFault_Handler(void);
|
||||
void MemManage_Handler(void);
|
||||
void BusFault_Handler(void);
|
||||
void UsageFault_Handler(void);
|
||||
void SVC_Handler(void);
|
||||
void DebugMon_Handler(void);
|
||||
void PendSV_Handler(void);
|
||||
void SysTick_Handler(void);
|
||||
/* USER CODE BEGIN EFP */
|
||||
|
||||
/* USER CODE END EFP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STM32F1xx_IT_H */
|
52
STM32F103_Example/Core/Inc/tim.h
Normal file
52
STM32F103_Example/Core/Inc/tim.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tim.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the tim.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __TIM_H__
|
||||
#define __TIM_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern TIM_HandleTypeDef htim3;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_TIM3_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __TIM_H__ */
|
||||
|
52
STM32F103_Example/Core/Inc/usart.h
Normal file
52
STM32F103_Example/Core/Inc/usart.h
Normal file
@ -0,0 +1,52 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usart.h
|
||||
* @brief This file contains all the function prototypes for
|
||||
* the usart.c file
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 */
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __USART_H__
|
||||
#define __USART_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern UART_HandleTypeDef huart1;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_USART1_UART_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __USART_H__ */
|
||||
|
47
STM32F103_Example/Core/Src/gpio.c
Normal file
47
STM32F103_Example/Core/Src/gpio.c
Normal file
@ -0,0 +1,47 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file gpio.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of all used GPIO pins.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 "gpio.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* Configure GPIO */
|
||||
/*----------------------------------------------------------------------------*/
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/** Pinout Configuration
|
||||
*/
|
||||
void MX_GPIO_Init(void)
|
||||
{
|
||||
|
||||
/* GPIO Ports Clock Enable */
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
/* USER CODE END 2 */
|
179
STM32F103_Example/Core/Src/main.c
Normal file
179
STM32F103_Example/Core/Src/main.c
Normal file
@ -0,0 +1,179 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : main.c
|
||||
* @brief : Main program body
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 "tim.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
|
||||
/* Private includes ----------------------------------------------------------*/
|
||||
/* USER CODE BEGIN Includes */
|
||||
#include "rs_message.h"
|
||||
/* 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 ---------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN PV */
|
||||
|
||||
/* USER CODE END PV */
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
void SystemClock_Config(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_USART1_UART_Init();
|
||||
MX_TIM3_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
MODBUS_FirstInit();
|
||||
RS_Receive_IT(&hmodbus1, &MODBUS_MSG);
|
||||
/* 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};
|
||||
|
||||
/** 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();
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 */
|
87
STM32F103_Example/Core/Src/stm32f1xx_hal_msp.c
Normal file
87
STM32F103_Example/Core/Src/stm32f1xx_hal_msp.c
Normal file
@ -0,0 +1,87 @@
|
||||
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_hal_msp.c
|
||||
* @brief This file provides code for the MSP Initialization
|
||||
* and de-Initialization codes.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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_AFIO_CLK_ENABLE();
|
||||
__HAL_RCC_PWR_CLK_ENABLE();
|
||||
|
||||
/* System interrupt init*/
|
||||
|
||||
/** DISABLE: JTAG-DP Disabled and SW-DP Disabled
|
||||
*/
|
||||
__HAL_AFIO_REMAP_SWJ_DISABLE();
|
||||
|
||||
/* USER CODE BEGIN MspInit 1 */
|
||||
|
||||
/* USER CODE END MspInit 1 */
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
203
STM32F103_Example/Core/Src/stm32f1xx_it.c
Normal file
203
STM32F103_Example/Core/Src/stm32f1xx_it.c
Normal file
@ -0,0 +1,203 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f1xx_it.c
|
||||
* @brief Interrupt Service Routines.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 "stm32f1xx_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 --------------------------------------------------------*/
|
||||
|
||||
/* USER CODE BEGIN EV */
|
||||
|
||||
/* USER CODE END EV */
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M3 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 Prefetch 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 */
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* STM32F1xx 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_stm32f1xx.s). */
|
||||
/******************************************************************************/
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
406
STM32F103_Example/Core/Src/system_stm32f1xx.c
Normal file
406
STM32F103_Example/Core/Src/system_stm32f1xx.c
Normal file
@ -0,0 +1,406 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file system_stm32f1xx.c
|
||||
* @author MCD Application Team
|
||||
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
|
||||
*
|
||||
* 1. This file provides two functions and one global variable to be called from
|
||||
* user application:
|
||||
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
|
||||
* factors, AHB/APBx prescalers and Flash settings).
|
||||
* This function is called at startup just after reset and
|
||||
* before branch to main program. This call is made inside
|
||||
* the "startup_stm32f1xx_xx.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.
|
||||
*
|
||||
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
|
||||
* Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
|
||||
* configure the system clock before to branch to main program.
|
||||
*
|
||||
* 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
|
||||
* the product used), refer to "HSE_VALUE".
|
||||
* When HSE is used as system clock source, directly or through PLL, and you
|
||||
* are using different crystal you have to adapt the HSE value to your own
|
||||
* configuration.
|
||||
*
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2017-2021 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 stm32f1xx_system
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Includes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "stm32f1xx.h"
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Defines
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if !defined (HSE_VALUE)
|
||||
#define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSE_VALUE */
|
||||
|
||||
#if !defined (HSI_VALUE)
|
||||
#define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
|
||||
This value can be provided and adapted by the user application. */
|
||||
#endif /* HSI_VALUE */
|
||||
|
||||
/*!< Uncomment the following line if you need to use external SRAM */
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/* #define DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/* 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 STM32F1xx_System_Private_Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_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 = 8000000;
|
||||
const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
|
||||
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
static void SystemInit_ExtMemCtl(void);
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup STM32F1xx_System_Private_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Setup the microcontroller system
|
||||
* Initialize the Embedded Flash Interface, the PLL and update the
|
||||
* SystemCoreClock variable.
|
||||
* @note This function should be used only after reset.
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit (void)
|
||||
{
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
SystemInit_ExtMemCtl();
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif
|
||||
|
||||
/* 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 by the PLL factors.
|
||||
*
|
||||
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz) but the real value may vary depending on the variations
|
||||
* in voltage and temperature.
|
||||
*
|
||||
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
|
||||
* 8 MHz or 25 MHz, depending on the product used), 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 = 0U, pllmull = 0U, pllsource = 0U;
|
||||
|
||||
#if defined(STM32F105xC) || defined(STM32F107xC)
|
||||
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
|
||||
#endif /* STM32F105xC */
|
||||
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
uint32_t prediv1factor = 0U;
|
||||
#endif /* STM32F100xB or STM32F100xE */
|
||||
|
||||
/* Get SYSCLK source -------------------------------------------------------*/
|
||||
tmp = RCC->CFGR & RCC_CFGR_SWS;
|
||||
|
||||
switch (tmp)
|
||||
{
|
||||
case 0x00U: /* HSI used as system clock */
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
case 0x04U: /* HSE used as system clock */
|
||||
SystemCoreClock = HSE_VALUE;
|
||||
break;
|
||||
case 0x08U: /* PLL used as system clock */
|
||||
|
||||
/* Get PLL clock source and multiplication factor ----------------------*/
|
||||
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
|
||||
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
|
||||
|
||||
#if !defined(STM32F105xC) && !defined(STM32F107xC)
|
||||
pllmull = ( pllmull >> 18U) + 2U;
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(STM32F100xB) || defined(STM32F100xE)
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
#else
|
||||
/* HSE selected as PLL clock entry */
|
||||
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
|
||||
{/* HSE oscillator clock divided by 2 */
|
||||
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemCoreClock = HSE_VALUE * pllmull;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
pllmull = pllmull >> 18U;
|
||||
|
||||
if (pllmull != 0x0DU)
|
||||
{
|
||||
pllmull += 2U;
|
||||
}
|
||||
else
|
||||
{ /* PLL multiplication factor = PLL input clock * 6.5 */
|
||||
pllmull = 13U / 2U;
|
||||
}
|
||||
|
||||
if (pllsource == 0x00U)
|
||||
{
|
||||
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
|
||||
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PREDIV1 selected as PLL clock entry */
|
||||
|
||||
/* Get PREDIV1 clock source and division factor */
|
||||
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
|
||||
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
|
||||
|
||||
if (prediv1source == 0U)
|
||||
{
|
||||
/* HSE oscillator clock selected as PREDIV1 clock entry */
|
||||
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
|
||||
}
|
||||
else
|
||||
{/* PLL2 clock selected as PREDIV1 clock entry */
|
||||
|
||||
/* Get PREDIV2 division factor and PLL2 multiplication factor */
|
||||
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
|
||||
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
|
||||
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
|
||||
}
|
||||
}
|
||||
#endif /* STM32F105xC */
|
||||
break;
|
||||
|
||||
default:
|
||||
SystemCoreClock = HSI_VALUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Compute HCLK clock frequency ----------------*/
|
||||
/* Get HCLK prescaler */
|
||||
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
|
||||
/* HCLK clock frequency */
|
||||
SystemCoreClock >>= tmp;
|
||||
}
|
||||
|
||||
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
|
||||
/**
|
||||
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
|
||||
* before jump to __main
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
#ifdef DATA_IN_ExtSRAM
|
||||
/**
|
||||
* @brief Setup the external memory controller.
|
||||
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
|
||||
* This function configures the external SRAM mounted on STM3210E-EVAL
|
||||
* board (STM32 High density devices). This SRAM will be used as program
|
||||
* data memory (including heap and stack).
|
||||
* @param None
|
||||
* @retval None
|
||||
*/
|
||||
void SystemInit_ExtMemCtl(void)
|
||||
{
|
||||
__IO uint32_t tmpreg;
|
||||
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
|
||||
required, then adjust the Register Addresses */
|
||||
|
||||
/* Enable FSMC clock */
|
||||
RCC->AHBENR = 0x00000114U;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
|
||||
|
||||
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
|
||||
RCC->APB2ENR = 0x000001E0U;
|
||||
|
||||
/* Delay after an RCC peripheral clock enabling */
|
||||
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
|
||||
|
||||
(void)(tmpreg);
|
||||
|
||||
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
|
||||
/*---------------- SRAM Address lines configuration -------------------------*/
|
||||
/*---------------- NOE and NWE configuration --------------------------------*/
|
||||
/*---------------- NE3 configuration ----------------------------------------*/
|
||||
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
|
||||
|
||||
GPIOD->CRL = 0x44BB44BBU;
|
||||
GPIOD->CRH = 0xBBBBBBBBU;
|
||||
|
||||
GPIOE->CRL = 0xB44444BBU;
|
||||
GPIOE->CRH = 0xBBBBBBBBU;
|
||||
|
||||
GPIOF->CRL = 0x44BBBBBBU;
|
||||
GPIOF->CRH = 0xBBBB4444U;
|
||||
|
||||
GPIOG->CRL = 0x44BBBBBBU;
|
||||
GPIOG->CRH = 0x444B4B44U;
|
||||
|
||||
/*---------------- FSMC Configuration ---------------------------------------*/
|
||||
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
|
||||
|
||||
FSMC_Bank1->BTCR[4U] = 0x00001091U;
|
||||
FSMC_Bank1->BTCR[5U] = 0x00110212U;
|
||||
}
|
||||
#endif /* DATA_IN_ExtSRAM */
|
||||
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
104
STM32F103_Example/Core/Src/tim.c
Normal file
104
STM32F103_Example/Core/Src/tim.c
Normal file
@ -0,0 +1,104 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file tim.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the TIM instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 "tim.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
TIM_HandleTypeDef htim3;
|
||||
|
||||
/* TIM3 init function */
|
||||
void MX_TIM3_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN TIM3_Init 0 */
|
||||
|
||||
/* USER CODE END TIM3_Init 0 */
|
||||
|
||||
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
|
||||
TIM_MasterConfigTypeDef sMasterConfig = {0};
|
||||
|
||||
/* USER CODE BEGIN TIM3_Init 1 */
|
||||
|
||||
/* USER CODE END TIM3_Init 1 */
|
||||
htim3.Instance = TIM3;
|
||||
htim3.Init.Prescaler = 8-1;
|
||||
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim3.Init.Period = 65535;
|
||||
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
|
||||
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
|
||||
if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
|
||||
if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
|
||||
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
|
||||
if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN TIM3_Init 2 */
|
||||
|
||||
/* USER CODE END TIM3_Init 2 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||
{
|
||||
|
||||
if(tim_baseHandle->Instance==TIM3)
|
||||
{
|
||||
/* USER CODE BEGIN TIM3_MspInit 0 */
|
||||
|
||||
/* USER CODE END TIM3_MspInit 0 */
|
||||
/* TIM3 clock enable */
|
||||
__HAL_RCC_TIM3_CLK_ENABLE();
|
||||
/* USER CODE BEGIN TIM3_MspInit 1 */
|
||||
|
||||
/* USER CODE END TIM3_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
|
||||
{
|
||||
|
||||
if(tim_baseHandle->Instance==TIM3)
|
||||
{
|
||||
/* USER CODE BEGIN TIM3_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END TIM3_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_TIM3_CLK_DISABLE();
|
||||
/* USER CODE BEGIN TIM3_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END TIM3_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
117
STM32F103_Example/Core/Src/usart.c
Normal file
117
STM32F103_Example/Core/Src/usart.c
Normal file
@ -0,0 +1,117 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file usart.c
|
||||
* @brief This file provides code for the configuration
|
||||
* of the USART instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2025 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 "usart.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
UART_HandleTypeDef huart1;
|
||||
|
||||
/* USART1 init function */
|
||||
|
||||
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 */
|
||||
|
||||
}
|
||||
|
||||
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(uartHandle->Instance==USART1)
|
||||
{
|
||||
/* USER CODE BEGIN USART1_MspInit 0 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 0 */
|
||||
/* USART1 clock enable */
|
||||
__HAL_RCC_USART1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
/**USART1 GPIO Configuration
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
||||
{
|
||||
|
||||
if(uartHandle->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
|
||||
PA9 ------> USART1_TX
|
||||
PA10 ------> USART1_RX
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
|
||||
|
||||
/* USER CODE BEGIN USART1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END USART1_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
865
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_armcc.h
Normal file
865
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_armcc.h
Normal file
@ -0,0 +1,865 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_armcc.h
|
||||
* @brief CMSIS compiler ARMCC (Arm Compiler 5) header file
|
||||
* @version V5.0.4
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_ARMCC_H
|
||||
#define __CMSIS_ARMCC_H
|
||||
|
||||
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
|
||||
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler control architecture macros */
|
||||
#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \
|
||||
(defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) )
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#endif
|
||||
|
||||
#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1))
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#endif
|
||||
|
||||
#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1))
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#endif
|
||||
|
||||
/* __ARM_ARCH_8M_BASE__ not applicable */
|
||||
/* __ARM_ARCH_8M_MAIN__ not applicable */
|
||||
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE static __forceinline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION __packed union
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Enable IRQ Interrupts
|
||||
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
/* intrinsic void __enable_irq(); */
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable IRQ Interrupts
|
||||
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
/* intrinsic void __disable_irq(); */
|
||||
|
||||
/**
|
||||
\brief Get Control Register
|
||||
\details Returns the content of the Control Register.
|
||||
\return Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CONTROL(void)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
return(__regControl);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Control Register
|
||||
\details Writes the given value to the Control Register.
|
||||
\param [in] control Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CONTROL(uint32_t control)
|
||||
{
|
||||
register uint32_t __regControl __ASM("control");
|
||||
__regControl = control;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get IPSR Register
|
||||
\details Returns the content of the IPSR Register.
|
||||
\return IPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_IPSR(void)
|
||||
{
|
||||
register uint32_t __regIPSR __ASM("ipsr");
|
||||
return(__regIPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get APSR Register
|
||||
\details Returns the content of the APSR Register.
|
||||
\return APSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
register uint32_t __regAPSR __ASM("apsr");
|
||||
return(__regAPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get xPSR Register
|
||||
\details Returns the content of the xPSR Register.
|
||||
\return xPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_xPSR(void)
|
||||
{
|
||||
register uint32_t __regXPSR __ASM("xpsr");
|
||||
return(__regXPSR);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Process Stack Pointer
|
||||
\details Returns the current value of the Process Stack Pointer (PSP).
|
||||
\return PSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PSP(void)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
return(__regProcessStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Process Stack Pointer
|
||||
\details Assigns the given value to the Process Stack Pointer (PSP).
|
||||
\param [in] topOfProcStack Process Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
{
|
||||
register uint32_t __regProcessStackPointer __ASM("psp");
|
||||
__regProcessStackPointer = topOfProcStack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Main Stack Pointer
|
||||
\details Returns the current value of the Main Stack Pointer (MSP).
|
||||
\return MSP Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MSP(void)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
return(__regMainStackPointer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Main Stack Pointer
|
||||
\details Assigns the given value to the Main Stack Pointer (MSP).
|
||||
\param [in] topOfMainStack Main Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
|
||||
{
|
||||
register uint32_t __regMainStackPointer __ASM("msp");
|
||||
__regMainStackPointer = topOfMainStack;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Priority Mask
|
||||
\details Returns the current state of the priority mask bit from the Priority Mask Register.
|
||||
\return Priority Mask value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_PRIMASK(void)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
return(__regPriMask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Priority Mask
|
||||
\details Assigns the given value to the Priority Mask Register.
|
||||
\param [in] priMask Priority Mask
|
||||
*/
|
||||
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
|
||||
{
|
||||
register uint32_t __regPriMask __ASM("primask");
|
||||
__regPriMask = (priMask);
|
||||
}
|
||||
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
/**
|
||||
\brief Enable FIQ
|
||||
\details Enables FIQ interrupts by clearing the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable FIQ
|
||||
\details Disables FIQ interrupts by setting the F-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Base Priority
|
||||
\details Returns the current value of the Base Priority register.
|
||||
\return Base Priority register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_BASEPRI(void)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
return(__regBasePri);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Base Priority
|
||||
\details Assigns the given value to the Base Priority register.
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePri __ASM("basepri");
|
||||
__regBasePri = (basePri & 0xFFU);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Base Priority with condition
|
||||
\details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
|
||||
or the new value increases the BASEPRI priority level.
|
||||
\param [in] basePri Base Priority value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
|
||||
{
|
||||
register uint32_t __regBasePriMax __ASM("basepri_max");
|
||||
__regBasePriMax = (basePri & 0xFFU);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Fault Mask
|
||||
\details Returns the current value of the Fault Mask register.
|
||||
\return Fault Mask register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
return(__regFaultMask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Fault Mask
|
||||
\details Assigns the given value to the Fault Mask register.
|
||||
\param [in] faultMask Fault Mask value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
|
||||
{
|
||||
register uint32_t __regFaultMask __ASM("faultmask");
|
||||
__regFaultMask = (faultMask & (uint32_t)1U);
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\details Returns the current value of the Floating Point Status/Control register.
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\details Assigns the given value to the Floating Point Status/Control register.
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_RegAccFunctions */
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief No Operation
|
||||
\details No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
\details Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
\details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or memory,
|
||||
after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
\details Acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
\details Ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\details Causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\details Reverses the bit order of the given value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
#define __RBIT __rbit
|
||||
#else
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value != 0U; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\details Counts the number of leading zeros of a data value.
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/**
|
||||
\brief Rotate Right with Extend (32 bit)
|
||||
\details Moves each bit of a bitstring right by one bit.
|
||||
The carry input is shifted in at the left end of the bitstring.
|
||||
\param [in] value Value to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
rrx r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (8 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (16 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief LDRT Unprivileged (32 bit)
|
||||
\details Executes a Unprivileged LDRT instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (8 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (16 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/**
|
||||
\brief STRT Unprivileged (32 bit)
|
||||
\details Executes a Unprivileged STRT instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRT(value, ptr) __strt(value, ptr)
|
||||
|
||||
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if ((sat >= 1U) && (sat <= 32U))
|
||||
{
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (val < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if (sat <= 31U)
|
||||
{
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (val < 0)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
|
||||
/* ################### Compiler specific Intrinsics ########################### */
|
||||
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||
Access to dedicated SIMD instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) )
|
||||
|
||||
#define __SADD8 __sadd8
|
||||
#define __QADD8 __qadd8
|
||||
#define __SHADD8 __shadd8
|
||||
#define __UADD8 __uadd8
|
||||
#define __UQADD8 __uqadd8
|
||||
#define __UHADD8 __uhadd8
|
||||
#define __SSUB8 __ssub8
|
||||
#define __QSUB8 __qsub8
|
||||
#define __SHSUB8 __shsub8
|
||||
#define __USUB8 __usub8
|
||||
#define __UQSUB8 __uqsub8
|
||||
#define __UHSUB8 __uhsub8
|
||||
#define __SADD16 __sadd16
|
||||
#define __QADD16 __qadd16
|
||||
#define __SHADD16 __shadd16
|
||||
#define __UADD16 __uadd16
|
||||
#define __UQADD16 __uqadd16
|
||||
#define __UHADD16 __uhadd16
|
||||
#define __SSUB16 __ssub16
|
||||
#define __QSUB16 __qsub16
|
||||
#define __SHSUB16 __shsub16
|
||||
#define __USUB16 __usub16
|
||||
#define __UQSUB16 __uqsub16
|
||||
#define __UHSUB16 __uhsub16
|
||||
#define __SASX __sasx
|
||||
#define __QASX __qasx
|
||||
#define __SHASX __shasx
|
||||
#define __UASX __uasx
|
||||
#define __UQASX __uqasx
|
||||
#define __UHASX __uhasx
|
||||
#define __SSAX __ssax
|
||||
#define __QSAX __qsax
|
||||
#define __SHSAX __shsax
|
||||
#define __USAX __usax
|
||||
#define __UQSAX __uqsax
|
||||
#define __UHSAX __uhsax
|
||||
#define __USAD8 __usad8
|
||||
#define __USADA8 __usada8
|
||||
#define __SSAT16 __ssat16
|
||||
#define __USAT16 __usat16
|
||||
#define __UXTB16 __uxtb16
|
||||
#define __UXTAB16 __uxtab16
|
||||
#define __SXTB16 __sxtb16
|
||||
#define __SXTAB16 __sxtab16
|
||||
#define __SMUAD __smuad
|
||||
#define __SMUADX __smuadx
|
||||
#define __SMLAD __smlad
|
||||
#define __SMLADX __smladx
|
||||
#define __SMLALD __smlald
|
||||
#define __SMLALDX __smlaldx
|
||||
#define __SMUSD __smusd
|
||||
#define __SMUSDX __smusdx
|
||||
#define __SMLSD __smlsd
|
||||
#define __SMLSDX __smlsdx
|
||||
#define __SMLSLD __smlsld
|
||||
#define __SMLSLDX __smlsldx
|
||||
#define __SEL __sel
|
||||
#define __QADD __qadd
|
||||
#define __QSUB __qsub
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||
|
||||
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||
((int64_t)(ARG3) << 32U) ) >> 32U))
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
1869
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_armclang.h
Normal file
1869
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_armclang.h
Normal file
File diff suppressed because it is too large
Load Diff
266
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_compiler.h
Normal file
266
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_compiler.h
Normal file
@ -0,0 +1,266 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_compiler.h
|
||||
* @brief CMSIS compiler generic header file
|
||||
* @version V5.0.4
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_COMPILER_H
|
||||
#define __CMSIS_COMPILER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Arm Compiler 4/5
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#include "cmsis_armcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* Arm Compiler 6 (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#include "cmsis_armclang.h"
|
||||
|
||||
|
||||
/*
|
||||
* GNU Compiler
|
||||
*/
|
||||
#elif defined ( __GNUC__ )
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
#include <cmsis_iccarm.h>
|
||||
|
||||
|
||||
/*
|
||||
* TI Arm Compiler
|
||||
*/
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TASKING Compiler
|
||||
*/
|
||||
#elif defined ( __TASKING__ )
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed__
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __packed__
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __packed__
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __packed__ T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __align(x)
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* COSMIC Compiler
|
||||
*/
|
||||
#elif defined ( __CSMC__ )
|
||||
#include <cmsis_csm.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM _asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
// NO RETURN is automatically detected hence no warning here
|
||||
#define __NO_RETURN
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#warning No compiler specific solution for __USED. __USED is ignored.
|
||||
#define __USED
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED @packed
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT @packed struct
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION @packed union
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
@packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
|
2085
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_gcc.h
Normal file
2085
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_gcc.h
Normal file
File diff suppressed because it is too large
Load Diff
935
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_iccarm.h
Normal file
935
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_iccarm.h
Normal file
@ -0,0 +1,935 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_iccarm.h
|
||||
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
|
||||
* @version V5.0.7
|
||||
* @date 19. June 2018
|
||||
******************************************************************************/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017-2018 IAR Systems
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License")
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __CMSIS_ICCARM_H__
|
||||
#define __CMSIS_ICCARM_H__
|
||||
|
||||
#ifndef __ICCARM__
|
||||
#error This file should only be compiled by ICCARM
|
||||
#endif
|
||||
|
||||
#pragma system_include
|
||||
|
||||
#define __IAR_FT _Pragma("inline=forced") __intrinsic
|
||||
|
||||
#if (__VER__ >= 8000000)
|
||||
#define __ICCARM_V8 1
|
||||
#else
|
||||
#define __ICCARM_V8 0
|
||||
#endif
|
||||
|
||||
#ifndef __ALIGNED
|
||||
#if __ICCARM_V8
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#elif (__VER__ >= 7080000)
|
||||
/* Needs IAR language extensions */
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#else
|
||||
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler macros for CPU architecture, used in CMSIS 5.
|
||||
*/
|
||||
#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__
|
||||
/* Macros already defined */
|
||||
#else
|
||||
#if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#elif defined(__ARM8M_BASELINE__)
|
||||
#define __ARM_ARCH_8M_BASE__ 1
|
||||
#elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
|
||||
#if __ARM_ARCH == 6
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#elif __ARM_ARCH == 7
|
||||
#if __ARM_FEATURE_DSP
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#else
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#endif
|
||||
#endif /* __ARM_ARCH */
|
||||
#endif /* __ARM_ARCH_PROFILE == 'M' */
|
||||
#endif
|
||||
|
||||
/* Alternativ core deduction for older ICCARM's */
|
||||
#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \
|
||||
!defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__)
|
||||
#if defined(__ARM6M__) && (__CORE__ == __ARM6M__)
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#elif defined(__ARM7M__) && (__CORE__ == __ARM7M__)
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__)
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__)
|
||||
#define __ARM_ARCH_8M_BASE__ 1
|
||||
#elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#else
|
||||
#error "Unknown target."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1
|
||||
#define __IAR_M0_FAMILY 1
|
||||
#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1
|
||||
#define __IAR_M0_FAMILY 1
|
||||
#else
|
||||
#define __IAR_M0_FAMILY 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#if __ICCARM_V8
|
||||
#define __NO_RETURN __attribute__((__noreturn__))
|
||||
#else
|
||||
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_STRUCT
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_UNION
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED_UNION __packed union
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE _Pragma("inline=forced")
|
||||
#endif
|
||||
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint16_t __iar_uint16_read(void const *ptr)
|
||||
{
|
||||
return *(__packed uint16_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val)
|
||||
{
|
||||
*(__packed uint16_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint32_t __iar_uint32_read(void const *ptr)
|
||||
{
|
||||
return *(__packed uint32_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val)
|
||||
{
|
||||
*(__packed uint32_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__packed struct __iar_u32 { uint32_t v; };
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
|
||||
#endif
|
||||
|
||||
#ifndef __USED
|
||||
#if __ICCARM_V8
|
||||
#define __USED __attribute__((used))
|
||||
#else
|
||||
#define __USED _Pragma("__root")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __WEAK
|
||||
#if __ICCARM_V8
|
||||
#define __WEAK __attribute__((weak))
|
||||
#else
|
||||
#define __WEAK _Pragma("__weak")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ICCARM_INTRINSICS_VERSION__
|
||||
#define __ICCARM_INTRINSICS_VERSION__ 0
|
||||
#endif
|
||||
|
||||
#if __ICCARM_INTRINSICS_VERSION__ == 2
|
||||
|
||||
#if defined(__CLZ)
|
||||
#undef __CLZ
|
||||
#endif
|
||||
#if defined(__REVSH)
|
||||
#undef __REVSH
|
||||
#endif
|
||||
#if defined(__RBIT)
|
||||
#undef __RBIT
|
||||
#endif
|
||||
#if defined(__SSAT)
|
||||
#undef __SSAT
|
||||
#endif
|
||||
#if defined(__USAT)
|
||||
#undef __USAT
|
||||
#endif
|
||||
|
||||
#include "iccarm_builtin.h"
|
||||
|
||||
#define __disable_fault_irq __iar_builtin_disable_fiq
|
||||
#define __disable_irq __iar_builtin_disable_interrupt
|
||||
#define __enable_fault_irq __iar_builtin_enable_fiq
|
||||
#define __enable_irq __iar_builtin_enable_interrupt
|
||||
#define __arm_rsr __iar_builtin_rsr
|
||||
#define __arm_wsr __iar_builtin_wsr
|
||||
|
||||
|
||||
#define __get_APSR() (__arm_rsr("APSR"))
|
||||
#define __get_BASEPRI() (__arm_rsr("BASEPRI"))
|
||||
#define __get_CONTROL() (__arm_rsr("CONTROL"))
|
||||
#define __get_FAULTMASK() (__arm_rsr("FAULTMASK"))
|
||||
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#define __get_FPSCR() (__arm_rsr("FPSCR"))
|
||||
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE)))
|
||||
#else
|
||||
#define __get_FPSCR() ( 0 )
|
||||
#define __set_FPSCR(VALUE) ((void)VALUE)
|
||||
#endif
|
||||
|
||||
#define __get_IPSR() (__arm_rsr("IPSR"))
|
||||
#define __get_MSP() (__arm_rsr("MSP"))
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||
#define __get_MSPLIM() (0U)
|
||||
#else
|
||||
#define __get_MSPLIM() (__arm_rsr("MSPLIM"))
|
||||
#endif
|
||||
#define __get_PRIMASK() (__arm_rsr("PRIMASK"))
|
||||
#define __get_PSP() (__arm_rsr("PSP"))
|
||||
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
#define __get_PSPLIM() (0U)
|
||||
#else
|
||||
#define __get_PSPLIM() (__arm_rsr("PSPLIM"))
|
||||
#endif
|
||||
|
||||
#define __get_xPSR() (__arm_rsr("xPSR"))
|
||||
|
||||
#define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE)))
|
||||
#define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE)))
|
||||
#define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE)))
|
||||
#define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE)))
|
||||
#define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE)))
|
||||
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||
#define __set_MSPLIM(VALUE) ((void)(VALUE))
|
||||
#else
|
||||
#define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE)))
|
||||
#endif
|
||||
#define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE)))
|
||||
#define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE)))
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
#define __set_PSPLIM(VALUE) ((void)(VALUE))
|
||||
#else
|
||||
#define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE)))
|
||||
#endif
|
||||
|
||||
#define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS"))
|
||||
#define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE)))
|
||||
#define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS"))
|
||||
#define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE)))
|
||||
#define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS"))
|
||||
#define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE)))
|
||||
#define __TZ_get_SP_NS() (__arm_rsr("SP_NS"))
|
||||
#define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE)))
|
||||
#define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS"))
|
||||
#define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE)))
|
||||
#define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS"))
|
||||
#define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE)))
|
||||
#define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS"))
|
||||
#define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE)))
|
||||
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
#define __TZ_get_PSPLIM_NS() (0U)
|
||||
#define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE))
|
||||
#else
|
||||
#define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS"))
|
||||
#define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE)))
|
||||
#endif
|
||||
|
||||
#define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS"))
|
||||
#define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE)))
|
||||
|
||||
#define __NOP __iar_builtin_no_operation
|
||||
|
||||
#define __CLZ __iar_builtin_CLZ
|
||||
#define __CLREX __iar_builtin_CLREX
|
||||
|
||||
#define __DMB __iar_builtin_DMB
|
||||
#define __DSB __iar_builtin_DSB
|
||||
#define __ISB __iar_builtin_ISB
|
||||
|
||||
#define __LDREXB __iar_builtin_LDREXB
|
||||
#define __LDREXH __iar_builtin_LDREXH
|
||||
#define __LDREXW __iar_builtin_LDREX
|
||||
|
||||
#define __RBIT __iar_builtin_RBIT
|
||||
#define __REV __iar_builtin_REV
|
||||
#define __REV16 __iar_builtin_REV16
|
||||
|
||||
__IAR_FT int16_t __REVSH(int16_t val)
|
||||
{
|
||||
return (int16_t) __iar_builtin_REVSH(val);
|
||||
}
|
||||
|
||||
#define __ROR __iar_builtin_ROR
|
||||
#define __RRX __iar_builtin_RRX
|
||||
|
||||
#define __SEV __iar_builtin_SEV
|
||||
|
||||
#if !__IAR_M0_FAMILY
|
||||
#define __SSAT __iar_builtin_SSAT
|
||||
#endif
|
||||
|
||||
#define __STREXB __iar_builtin_STREXB
|
||||
#define __STREXH __iar_builtin_STREXH
|
||||
#define __STREXW __iar_builtin_STREX
|
||||
|
||||
#if !__IAR_M0_FAMILY
|
||||
#define __USAT __iar_builtin_USAT
|
||||
#endif
|
||||
|
||||
#define __WFE __iar_builtin_WFE
|
||||
#define __WFI __iar_builtin_WFI
|
||||
|
||||
#if __ARM_MEDIA__
|
||||
#define __SADD8 __iar_builtin_SADD8
|
||||
#define __QADD8 __iar_builtin_QADD8
|
||||
#define __SHADD8 __iar_builtin_SHADD8
|
||||
#define __UADD8 __iar_builtin_UADD8
|
||||
#define __UQADD8 __iar_builtin_UQADD8
|
||||
#define __UHADD8 __iar_builtin_UHADD8
|
||||
#define __SSUB8 __iar_builtin_SSUB8
|
||||
#define __QSUB8 __iar_builtin_QSUB8
|
||||
#define __SHSUB8 __iar_builtin_SHSUB8
|
||||
#define __USUB8 __iar_builtin_USUB8
|
||||
#define __UQSUB8 __iar_builtin_UQSUB8
|
||||
#define __UHSUB8 __iar_builtin_UHSUB8
|
||||
#define __SADD16 __iar_builtin_SADD16
|
||||
#define __QADD16 __iar_builtin_QADD16
|
||||
#define __SHADD16 __iar_builtin_SHADD16
|
||||
#define __UADD16 __iar_builtin_UADD16
|
||||
#define __UQADD16 __iar_builtin_UQADD16
|
||||
#define __UHADD16 __iar_builtin_UHADD16
|
||||
#define __SSUB16 __iar_builtin_SSUB16
|
||||
#define __QSUB16 __iar_builtin_QSUB16
|
||||
#define __SHSUB16 __iar_builtin_SHSUB16
|
||||
#define __USUB16 __iar_builtin_USUB16
|
||||
#define __UQSUB16 __iar_builtin_UQSUB16
|
||||
#define __UHSUB16 __iar_builtin_UHSUB16
|
||||
#define __SASX __iar_builtin_SASX
|
||||
#define __QASX __iar_builtin_QASX
|
||||
#define __SHASX __iar_builtin_SHASX
|
||||
#define __UASX __iar_builtin_UASX
|
||||
#define __UQASX __iar_builtin_UQASX
|
||||
#define __UHASX __iar_builtin_UHASX
|
||||
#define __SSAX __iar_builtin_SSAX
|
||||
#define __QSAX __iar_builtin_QSAX
|
||||
#define __SHSAX __iar_builtin_SHSAX
|
||||
#define __USAX __iar_builtin_USAX
|
||||
#define __UQSAX __iar_builtin_UQSAX
|
||||
#define __UHSAX __iar_builtin_UHSAX
|
||||
#define __USAD8 __iar_builtin_USAD8
|
||||
#define __USADA8 __iar_builtin_USADA8
|
||||
#define __SSAT16 __iar_builtin_SSAT16
|
||||
#define __USAT16 __iar_builtin_USAT16
|
||||
#define __UXTB16 __iar_builtin_UXTB16
|
||||
#define __UXTAB16 __iar_builtin_UXTAB16
|
||||
#define __SXTB16 __iar_builtin_SXTB16
|
||||
#define __SXTAB16 __iar_builtin_SXTAB16
|
||||
#define __SMUAD __iar_builtin_SMUAD
|
||||
#define __SMUADX __iar_builtin_SMUADX
|
||||
#define __SMMLA __iar_builtin_SMMLA
|
||||
#define __SMLAD __iar_builtin_SMLAD
|
||||
#define __SMLADX __iar_builtin_SMLADX
|
||||
#define __SMLALD __iar_builtin_SMLALD
|
||||
#define __SMLALDX __iar_builtin_SMLALDX
|
||||
#define __SMUSD __iar_builtin_SMUSD
|
||||
#define __SMUSDX __iar_builtin_SMUSDX
|
||||
#define __SMLSD __iar_builtin_SMLSD
|
||||
#define __SMLSDX __iar_builtin_SMLSDX
|
||||
#define __SMLSLD __iar_builtin_SMLSLD
|
||||
#define __SMLSLDX __iar_builtin_SMLSLDX
|
||||
#define __SEL __iar_builtin_SEL
|
||||
#define __QADD __iar_builtin_QADD
|
||||
#define __QSUB __iar_builtin_QSUB
|
||||
#define __PKHBT __iar_builtin_PKHBT
|
||||
#define __PKHTB __iar_builtin_PKHTB
|
||||
#endif
|
||||
|
||||
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
|
||||
#define __CLZ __cmsis_iar_clz_not_active
|
||||
#define __SSAT __cmsis_iar_ssat_not_active
|
||||
#define __USAT __cmsis_iar_usat_not_active
|
||||
#define __RBIT __cmsis_iar_rbit_not_active
|
||||
#define __get_APSR __cmsis_iar_get_APSR_not_active
|
||||
#endif
|
||||
|
||||
|
||||
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
|
||||
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
|
||||
#define __set_FPSCR __cmsis_iar_set_FPSR_not_active
|
||||
#endif
|
||||
|
||||
#ifdef __INTRINSICS_INCLUDED
|
||||
#error intrinsics.h is already included previously!
|
||||
#endif
|
||||
|
||||
#include <intrinsics.h>
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
|
||||
#undef __CLZ
|
||||
#undef __SSAT
|
||||
#undef __USAT
|
||||
#undef __RBIT
|
||||
#undef __get_APSR
|
||||
|
||||
__STATIC_INLINE uint8_t __CLZ(uint32_t data)
|
||||
{
|
||||
if (data == 0U) { return 32U; }
|
||||
|
||||
uint32_t count = 0U;
|
||||
uint32_t mask = 0x80000000U;
|
||||
|
||||
while ((data & mask) == 0U)
|
||||
{
|
||||
count += 1U;
|
||||
mask = mask >> 1U;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __RBIT(uint32_t v)
|
||||
{
|
||||
uint8_t sc = 31U;
|
||||
uint32_t r = v;
|
||||
for (v >>= 1U; v; v >>= 1U)
|
||||
{
|
||||
r <<= 1U;
|
||||
r |= v & 1U;
|
||||
sc--;
|
||||
}
|
||||
return (r << sc);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __get_APSR(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm("MRS %0,APSR" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
|
||||
#undef __get_FPSCR
|
||||
#undef __set_FPSCR
|
||||
#define __get_FPSCR() (0)
|
||||
#define __set_FPSCR(VALUE) ((void)VALUE)
|
||||
#endif
|
||||
|
||||
#pragma diag_suppress=Pe940
|
||||
#pragma diag_suppress=Pe177
|
||||
|
||||
#define __enable_irq __enable_interrupt
|
||||
#define __disable_irq __disable_interrupt
|
||||
#define __NOP __no_operation
|
||||
|
||||
#define __get_xPSR __get_PSR
|
||||
|
||||
#if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0)
|
||||
|
||||
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr)
|
||||
{
|
||||
return __LDREX((unsigned long *)ptr);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr)
|
||||
{
|
||||
return __STREX(value, (unsigned long *)ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
__IAR_FT uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
|
||||
return(result);
|
||||
}
|
||||
|
||||
__IAR_FT void __set_BASEPRI_MAX(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR BASEPRI_MAX,%0"::"r" (value));
|
||||
}
|
||||
|
||||
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
|
||||
}
|
||||
|
||||
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||
|
||||
__IAR_FT uint32_t __get_MSPLIM(void)
|
||||
{
|
||||
uint32_t res;
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||
res = 0U;
|
||||
#else
|
||||
__asm volatile("MRS %0,MSPLIM" : "=r" (res));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __set_MSPLIM(uint32_t value)
|
||||
{
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure MSPLIM is RAZ/WI
|
||||
(void)value;
|
||||
#else
|
||||
__asm volatile("MSR MSPLIM,%0" :: "r" (value));
|
||||
#endif
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __get_PSPLIM(void)
|
||||
{
|
||||
uint32_t res;
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
res = 0U;
|
||||
#else
|
||||
__asm volatile("MRS %0,PSPLIM" : "=r" (res));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __set_PSPLIM(uint32_t value)
|
||||
{
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
(void)value;
|
||||
#else
|
||||
__asm volatile("MSR PSPLIM,%0" :: "r" (value));
|
||||
#endif
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_CONTROL_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,CONTROL_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_CONTROL_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR CONTROL_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PSP_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,PSP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_PSP_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR PSP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_MSP_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,MSP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_MSP_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR MSP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_SP_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,SP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
__IAR_FT void __TZ_set_SP_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR SP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PRIMASK_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,PRIMASK_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR PRIMASK_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_BASEPRI_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,BASEPRI_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR BASEPRI_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PSPLIM_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
res = 0U;
|
||||
#else
|
||||
__asm volatile("MRS %0,PSPLIM_NS" : "=r" (res));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value)
|
||||
{
|
||||
#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \
|
||||
(!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3)))
|
||||
// without main extensions, the non-secure PSPLIM is RAZ/WI
|
||||
(void)value;
|
||||
#else
|
||||
__asm volatile("MSR PSPLIM_NS,%0" :: "r" (value));
|
||||
#endif
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_MSPLIM_NS(void)
|
||||
{
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,MSPLIM_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value)
|
||||
{
|
||||
__asm volatile("MSR MSPLIM_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
|
||||
|
||||
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
__STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if ((sat >= 1U) && (sat <= 32U))
|
||||
{
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (val < min)
|
||||
{
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if (sat <= 31U)
|
||||
{
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max)
|
||||
{
|
||||
return max;
|
||||
}
|
||||
else if (val < 0)
|
||||
{
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
|
||||
|
||||
__IAR_FT uint8_t __LDRBT(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDRHT(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDRT(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
__ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
__ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
__ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||
|
||||
|
||||
__IAR_FT uint8_t __LDAB(volatile uint8_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDAH(volatile uint16_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDA(volatile uint32_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr)
|
||||
{
|
||||
__ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr)
|
||||
{
|
||||
__ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr)
|
||||
{
|
||||
__ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr)
|
||||
{
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
|
||||
|
||||
#undef __IAR_FT
|
||||
#undef __IAR_M0_FAMILY
|
||||
#undef __ICCARM_V8
|
||||
|
||||
#pragma diag_default=Pe940
|
||||
#pragma diag_default=Pe177
|
||||
|
||||
#endif /* __CMSIS_ICCARM_H__ */
|
39
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_version.h
Normal file
39
STM32F103_Example/Drivers/CMSIS/Core/Include/cmsis_version.h
Normal file
@ -0,0 +1,39 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_version.h
|
||||
* @brief CMSIS Core(M) Version definitions
|
||||
* @version V5.0.2
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CMSIS_VERSION_H
|
||||
#define __CMSIS_VERSION_H
|
||||
|
||||
/* CMSIS Version definitions */
|
||||
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
|
||||
#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */
|
||||
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
|
||||
#endif
|
1918
STM32F103_Example/Drivers/CMSIS/Core/Include/core_armv8mbl.h
Normal file
1918
STM32F103_Example/Drivers/CMSIS/Core/Include/core_armv8mbl.h
Normal file
File diff suppressed because it is too large
Load Diff
2927
STM32F103_Example/Drivers/CMSIS/Core/Include/core_armv8mml.h
Normal file
2927
STM32F103_Example/Drivers/CMSIS/Core/Include/core_armv8mml.h
Normal file
File diff suppressed because it is too large
Load Diff
949
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm0.h
Normal file
949
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm0.h
Normal file
@ -0,0 +1,949 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cm0.h
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.5
|
||||
* @date 28. May 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM0_H_GENERIC
|
||||
#define __CORE_CM0_H_GENERIC
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\ingroup Cortex_M0
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM0 definitions */
|
||||
#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0U) /*!< Cortex-M Core */
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not.
|
||||
This core does not support an FPU at all
|
||||
*/
|
||||
#define __FPU_USED 0U
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#if defined __ARM_PCS_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __CSMC__ )
|
||||
#if ( __CSMC__ & 0x400U)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM0_H_DEPENDANT
|
||||
#define __CORE_CM0_H_DEPENDANT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM0_REV
|
||||
#define __CM0_REV 0x0000U
|
||||
#warning "__CM0_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2U
|
||||
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 0U
|
||||
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
|
||||
/*@} end of group Cortex_M0 */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
Core Register contain:
|
||||
- Core Register
|
||||
- Core NVIC Register
|
||||
- Core SCB Register
|
||||
- Core SysTick Register
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
/* APSR Register Definitions */
|
||||
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||
|
||||
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||
|
||||
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||
|
||||
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} IPSR_Type;
|
||||
|
||||
/* IPSR Register Definitions */
|
||||
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} xPSR_Type;
|
||||
|
||||
/* xPSR Register Definitions */
|
||||
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||
|
||||
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||
|
||||
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||
|
||||
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||
|
||||
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||
|
||||
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Control Registers (CONTROL).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
|
||||
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CONTROL_Type;
|
||||
|
||||
/* CONTROL Register Definitions */
|
||||
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||
\brief Type definitions for the NVIC Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31U];
|
||||
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RSERVED1[31U];
|
||||
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31U];
|
||||
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31U];
|
||||
uint32_t RESERVED4[64U];
|
||||
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||
} NVIC_Type;
|
||||
|
||||
/*@} end of group CMSIS_NVIC */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||
\brief Type definitions for the System Control Block Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Control Block (SCB).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||
uint32_t RESERVED0;
|
||||
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||
uint32_t RESERVED1;
|
||||
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||
} SCB_Type;
|
||||
|
||||
/* SCB CPUID Register Definitions */
|
||||
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||
|
||||
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||
|
||||
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||
|
||||
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||
|
||||
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||
|
||||
/* SCB Interrupt Control State Register Definitions */
|
||||
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
|
||||
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||
|
||||
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||
|
||||
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||
|
||||
/* SCB System Control Register Definitions */
|
||||
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||
|
||||
/* SCB Configuration Control Register Definitions */
|
||||
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
|
||||
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||
|
||||
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||
|
||||
/* SCB System Handler Control and State Register Definitions */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCB */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||
\brief Type definitions for the System Timer Registers.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Timer (SysTick).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||
} SysTick_Type;
|
||||
|
||||
/* SysTick Control / Status Register Definitions */
|
||||
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||
|
||||
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||
|
||||
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||
|
||||
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||
|
||||
/* SysTick Reload Register Definitions */
|
||||
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||
|
||||
/* SysTick Current Register Definitions */
|
||||
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||
|
||||
/* SysTick Calibration Register Definitions */
|
||||
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||
|
||||
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||
|
||||
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||
|
||||
/*@} end of group CMSIS_SysTick */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||
\brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||
Therefore they are not covered by the Cortex-M0 header file.
|
||||
@{
|
||||
*/
|
||||
/*@} end of group CMSIS_CoreDebug */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Mask and shift a bit field value for use in a register bit range.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted value.
|
||||
*/
|
||||
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
|
||||
|
||||
/**
|
||||
\brief Mask and shift a register value to extract a bit filed value.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted bit field value.
|
||||
*/
|
||||
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
|
||||
|
||||
/*@} end of group CMSIS_core_bitfield */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_base Core Definitions
|
||||
\brief Definitions for base addresses, unions, and structures.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Memory mapping of Core Hardware */
|
||||
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||
|
||||
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||
|
||||
|
||||
/*@} */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
Core Function Interface contains:
|
||||
- Core NVIC Functions
|
||||
- Core SysTick Functions
|
||||
- Core Register Access Functions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ########################## NVIC functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifdef CMSIS_NVIC_VIRTUAL
|
||||
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
|
||||
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
|
||||
#define NVIC_EnableIRQ __NVIC_EnableIRQ
|
||||
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
|
||||
#define NVIC_DisableIRQ __NVIC_DisableIRQ
|
||||
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
|
||||
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
|
||||
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
|
||||
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0 */
|
||||
#define NVIC_SetPriority __NVIC_SetPriority
|
||||
#define NVIC_GetPriority __NVIC_GetPriority
|
||||
#define NVIC_SystemReset __NVIC_SystemReset
|
||||
#endif /* CMSIS_NVIC_VIRTUAL */
|
||||
|
||||
#ifdef CMSIS_VECTAB_VIRTUAL
|
||||
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetVector __NVIC_SetVector
|
||||
#define NVIC_GetVector __NVIC_GetVector
|
||||
#endif /* (CMSIS_VECTAB_VIRTUAL) */
|
||||
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
|
||||
/* The following EXC_RETURN values are saved the LR on exception entry */
|
||||
#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */
|
||||
|
||||
|
||||
/* Interrupt Priorities are WORD accessible only under Armv6-M */
|
||||
/* The following MACROS handle generation of the register offset and byte masks */
|
||||
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||
|
||||
#define __NVIC_SetPriorityGrouping(X) (void)(X)
|
||||
#define __NVIC_GetPriorityGrouping() (0U)
|
||||
|
||||
/**
|
||||
\brief Enable Interrupt
|
||||
\details Enables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Enable status
|
||||
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt is not enabled.
|
||||
\return 1 Interrupt is enabled.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable Interrupt
|
||||
\details Disables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Pending Interrupt
|
||||
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt status is not pending.
|
||||
\return 1 Interrupt status is pending.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Pending Interrupt
|
||||
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Clear Pending Interrupt
|
||||
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Priority
|
||||
\details Sets the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\param [in] priority Priority to set.
|
||||
\note The priority cannot be set for every processor exception.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Priority
|
||||
\details Reads the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Interrupt Priority.
|
||||
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Encode Priority
|
||||
\details Encodes the priority for an interrupt with the given priority group,
|
||||
preemptive priority value, and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [in] PreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [in] SubPriority Subpriority value (starting from 0).
|
||||
\return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
|
||||
*/
|
||||
__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
return (
|
||||
((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
|
||||
((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Decode Priority
|
||||
\details Decodes an interrupt priority value with a given priority group to
|
||||
preemptive priority value and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
|
||||
\param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [out] pPreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [out] pSubPriority Subpriority value (starting from 0).
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
*pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
|
||||
*pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Vector
|
||||
\details Sets an interrupt vector in SRAM based interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
Address 0 must be mapped to SRAM.
|
||||
\param [in] IRQn Interrupt number
|
||||
\param [in] vector Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Vector
|
||||
\details Reads an interrupt vector from interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief System Reset
|
||||
\details Initiates a system reset request to reset the MCU.
|
||||
*/
|
||||
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
|
||||
{
|
||||
__DSB(); /* Ensure all outstanding memory accesses included
|
||||
buffered write are completed before reset */
|
||||
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
|
||||
for(;;) /* wait until reset */
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_FpuFunctions FPU Functions
|
||||
\brief Function that provides FPU type.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief get FPU type
|
||||
\details returns the FPU type
|
||||
\returns
|
||||
- \b 0: No FPU
|
||||
- \b 1: Single precision FPU
|
||||
- \b 2: Double + Single precision FPU
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
|
||||
{
|
||||
return 0U; /* No FPU */
|
||||
}
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_FpuFunctions */
|
||||
|
||||
|
||||
|
||||
/* ################################## SysTick function ############################################ */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||
\brief Functions that configure the System.
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
|
||||
|
||||
/**
|
||||
\brief System Tick Configuration
|
||||
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
Counter is in free running mode to generate periodic interrupts.
|
||||
\param [in] ticks Number of ticks between two interrupts.
|
||||
\return 0 Function succeeded.
|
||||
\return 1 Function failed.
|
||||
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
must contain a vendor-specific implementation of this function.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
{
|
||||
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||
{
|
||||
return (1UL); /* Reload value impossible */
|
||||
}
|
||||
|
||||
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||
return (0UL); /* Function successful */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM0_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
1083
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm0plus.h
Normal file
1083
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm0plus.h
Normal file
File diff suppressed because it is too large
Load Diff
976
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm1.h
Normal file
976
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm1.h
Normal file
@ -0,0 +1,976 @@
|
||||
/**************************************************************************//**
|
||||
* @file core_cm1.h
|
||||
* @brief CMSIS Cortex-M1 Core Peripheral Access Layer Header File
|
||||
* @version V1.0.0
|
||||
* @date 23. July 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM1_H_GENERIC
|
||||
#define __CORE_CM1_H_GENERIC
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
\page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\ingroup Cortex_M1
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM1 definitions */
|
||||
#define __CM1_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM1_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM1_CMSIS_VERSION ((__CM1_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM1_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (1U) /*!< Cortex-M Core */
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not.
|
||||
This core does not support an FPU at all
|
||||
*/
|
||||
#define __FPU_USED 0U
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#if defined __ARM_PCS_VFP
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#elif defined ( __CSMC__ )
|
||||
#if ( __CSMC__ & 0x400U)
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "cmsis_compiler.h" /* CMSIS compiler specific defines */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM1_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CM1_H_DEPENDANT
|
||||
#define __CORE_CM1_H_DEPENDANT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CM1_REV
|
||||
#define __CM1_REV 0x0100U
|
||||
#warning "__CM1_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __NVIC_PRIO_BITS
|
||||
#define __NVIC_PRIO_BITS 2U
|
||||
#warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 0U
|
||||
#warning "__Vendor_SysTickConfig not defined in device header file; using default!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/* following defines should be used for structure members */
|
||||
#define __IM volatile const /*! Defines 'read only' structure member permissions */
|
||||
#define __OM volatile /*! Defines 'write only' structure member permissions */
|
||||
#define __IOM volatile /*! Defines 'read / write' structure member permissions */
|
||||
|
||||
/*@} end of group Cortex_M1 */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
Core Register contain:
|
||||
- Core Register
|
||||
- Core NVIC Register
|
||||
- Core SCB Register
|
||||
- Core SysTick Register
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-M processor based devices.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
/* APSR Register Definitions */
|
||||
#define APSR_N_Pos 31U /*!< APSR: N Position */
|
||||
#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
|
||||
|
||||
#define APSR_Z_Pos 30U /*!< APSR: Z Position */
|
||||
#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
|
||||
|
||||
#define APSR_C_Pos 29U /*!< APSR: C Position */
|
||||
#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
|
||||
|
||||
#define APSR_V_Pos 28U /*!< APSR: V Position */
|
||||
#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Interrupt Program Status Register (IPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} IPSR_Type;
|
||||
|
||||
/* IPSR Register Definitions */
|
||||
#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
|
||||
#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Special-Purpose Program Status Registers (xPSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
|
||||
uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
|
||||
uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
|
||||
uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} xPSR_Type;
|
||||
|
||||
/* xPSR Register Definitions */
|
||||
#define xPSR_N_Pos 31U /*!< xPSR: N Position */
|
||||
#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
|
||||
|
||||
#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
|
||||
#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
|
||||
|
||||
#define xPSR_C_Pos 29U /*!< xPSR: C Position */
|
||||
#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
|
||||
|
||||
#define xPSR_V_Pos 28U /*!< xPSR: V Position */
|
||||
#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
|
||||
|
||||
#define xPSR_T_Pos 24U /*!< xPSR: T Position */
|
||||
#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
|
||||
|
||||
#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
|
||||
#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
|
||||
|
||||
|
||||
/**
|
||||
\brief Union type to access the Control Registers (CONTROL).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:1; /*!< bit: 0 Reserved */
|
||||
uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
|
||||
uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} CONTROL_Type;
|
||||
|
||||
/* CONTROL Register Definitions */
|
||||
#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
|
||||
#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
|
||||
\brief Type definitions for the NVIC Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
|
||||
uint32_t RESERVED0[31U];
|
||||
__IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
|
||||
uint32_t RSERVED1[31U];
|
||||
__IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
|
||||
uint32_t RESERVED2[31U];
|
||||
__IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
|
||||
uint32_t RESERVED3[31U];
|
||||
uint32_t RESERVED4[64U];
|
||||
__IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
|
||||
} NVIC_Type;
|
||||
|
||||
/*@} end of group CMSIS_NVIC */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCB System Control Block (SCB)
|
||||
\brief Type definitions for the System Control Block Registers
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Control Block (SCB).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
|
||||
__IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
|
||||
uint32_t RESERVED0;
|
||||
__IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
|
||||
__IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
|
||||
__IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
|
||||
uint32_t RESERVED1;
|
||||
__IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
|
||||
__IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
|
||||
} SCB_Type;
|
||||
|
||||
/* SCB CPUID Register Definitions */
|
||||
#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
|
||||
#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
|
||||
|
||||
#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
|
||||
#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
|
||||
|
||||
#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
|
||||
#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
|
||||
|
||||
#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
|
||||
#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
|
||||
|
||||
#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
|
||||
#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
|
||||
|
||||
/* SCB Interrupt Control State Register Definitions */
|
||||
#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
|
||||
#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
|
||||
#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
|
||||
#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
|
||||
#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
|
||||
|
||||
#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
|
||||
#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
|
||||
#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
|
||||
|
||||
#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
|
||||
#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
|
||||
#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
|
||||
|
||||
#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
|
||||
#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
|
||||
|
||||
/* SCB Application Interrupt and Reset Control Register Definitions */
|
||||
#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
|
||||
#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
|
||||
#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
|
||||
|
||||
#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
|
||||
#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
|
||||
|
||||
#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
|
||||
#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
|
||||
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
|
||||
#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
|
||||
|
||||
/* SCB System Control Register Definitions */
|
||||
#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
|
||||
#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
|
||||
#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
|
||||
|
||||
#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
|
||||
#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
|
||||
|
||||
/* SCB Configuration Control Register Definitions */
|
||||
#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
|
||||
#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
|
||||
|
||||
#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
|
||||
#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
|
||||
|
||||
/* SCB System Handler Control and State Register Definitions */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
|
||||
#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCB */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
|
||||
\brief Type definitions for the System Control and ID Register not in the SCB
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Control and ID Register not in the SCB.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t RESERVED0[2U];
|
||||
__IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
|
||||
} SCnSCB_Type;
|
||||
|
||||
/* Auxiliary Control Register Definitions */
|
||||
#define SCnSCB_ACTLR_ITCMUAEN_Pos 4U /*!< ACTLR: Instruction TCM Upper Alias Enable Position */
|
||||
#define SCnSCB_ACTLR_ITCMUAEN_Msk (1UL << SCnSCB_ACTLR_ITCMUAEN_Pos) /*!< ACTLR: Instruction TCM Upper Alias Enable Mask */
|
||||
|
||||
#define SCnSCB_ACTLR_ITCMLAEN_Pos 3U /*!< ACTLR: Instruction TCM Lower Alias Enable Position */
|
||||
#define SCnSCB_ACTLR_ITCMLAEN_Msk (1UL << SCnSCB_ACTLR_ITCMLAEN_Pos) /*!< ACTLR: Instruction TCM Lower Alias Enable Mask */
|
||||
|
||||
/*@} end of group CMSIS_SCnotSCB */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_SysTick System Tick Timer (SysTick)
|
||||
\brief Type definitions for the System Timer Registers.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Structure type to access the System Timer (SysTick).
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
|
||||
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
|
||||
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
|
||||
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
|
||||
} SysTick_Type;
|
||||
|
||||
/* SysTick Control / Status Register Definitions */
|
||||
#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
|
||||
#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
|
||||
|
||||
#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
|
||||
#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
|
||||
|
||||
#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
|
||||
#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
|
||||
|
||||
#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
|
||||
#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
|
||||
|
||||
/* SysTick Reload Register Definitions */
|
||||
#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
|
||||
#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
|
||||
|
||||
/* SysTick Current Register Definitions */
|
||||
#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
|
||||
#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
|
||||
|
||||
/* SysTick Calibration Register Definitions */
|
||||
#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
|
||||
#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
|
||||
|
||||
#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
|
||||
#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
|
||||
|
||||
#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
|
||||
#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
|
||||
|
||||
/*@} end of group CMSIS_SysTick */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
|
||||
\brief Cortex-M1 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
|
||||
Therefore they are not covered by the Cortex-M1 header file.
|
||||
@{
|
||||
*/
|
||||
/*@} end of group CMSIS_CoreDebug */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_bitfield Core register bit field macros
|
||||
\brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief Mask and shift a bit field value for use in a register bit range.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted value.
|
||||
*/
|
||||
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
|
||||
|
||||
/**
|
||||
\brief Mask and shift a register value to extract a bit filed value.
|
||||
\param[in] field Name of the register bit field.
|
||||
\param[in] value Value of register. This parameter is interpreted as an uint32_t type.
|
||||
\return Masked and shifted bit field value.
|
||||
*/
|
||||
#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos)
|
||||
|
||||
/*@} end of group CMSIS_core_bitfield */
|
||||
|
||||
|
||||
/**
|
||||
\ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_core_base Core Definitions
|
||||
\brief Definitions for base addresses, unions, and structures.
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Memory mapping of Core Hardware */
|
||||
#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
|
||||
#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
|
||||
#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
|
||||
#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
|
||||
|
||||
#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
|
||||
#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
|
||||
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
|
||||
#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
|
||||
|
||||
|
||||
/*@} */
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
Core Function Interface contains:
|
||||
- Core NVIC Functions
|
||||
- Core SysTick Functions
|
||||
- Core Register Access Functions
|
||||
******************************************************************************/
|
||||
/**
|
||||
\defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* ########################## NVIC functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_NVICFunctions NVIC Functions
|
||||
\brief Functions that manage interrupts and exceptions via the NVIC.
|
||||
@{
|
||||
*/
|
||||
|
||||
#ifdef CMSIS_NVIC_VIRTUAL
|
||||
#ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_NVIC_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping
|
||||
#define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping
|
||||
#define NVIC_EnableIRQ __NVIC_EnableIRQ
|
||||
#define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ
|
||||
#define NVIC_DisableIRQ __NVIC_DisableIRQ
|
||||
#define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ
|
||||
#define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ
|
||||
#define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ
|
||||
/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M1 */
|
||||
#define NVIC_SetPriority __NVIC_SetPriority
|
||||
#define NVIC_GetPriority __NVIC_GetPriority
|
||||
#define NVIC_SystemReset __NVIC_SystemReset
|
||||
#endif /* CMSIS_NVIC_VIRTUAL */
|
||||
|
||||
#ifdef CMSIS_VECTAB_VIRTUAL
|
||||
#ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h"
|
||||
#endif
|
||||
#include CMSIS_VECTAB_VIRTUAL_HEADER_FILE
|
||||
#else
|
||||
#define NVIC_SetVector __NVIC_SetVector
|
||||
#define NVIC_GetVector __NVIC_GetVector
|
||||
#endif /* (CMSIS_VECTAB_VIRTUAL) */
|
||||
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
|
||||
/* The following EXC_RETURN values are saved the LR on exception entry */
|
||||
#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */
|
||||
#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */
|
||||
|
||||
|
||||
/* Interrupt Priorities are WORD accessible only under Armv6-M */
|
||||
/* The following MACROS handle generation of the register offset and byte masks */
|
||||
#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
|
||||
#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
|
||||
#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
|
||||
|
||||
#define __NVIC_SetPriorityGrouping(X) (void)(X)
|
||||
#define __NVIC_GetPriorityGrouping() (0U)
|
||||
|
||||
/**
|
||||
\brief Enable Interrupt
|
||||
\details Enables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Enable status
|
||||
\details Returns a device specific interrupt enable status from the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt is not enabled.
|
||||
\return 1 Interrupt is enabled.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Disable Interrupt
|
||||
\details Disables a device specific interrupt in the NVIC interrupt controller.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
__DSB();
|
||||
__ISB();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Pending Interrupt
|
||||
\details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\return 0 Interrupt status is not pending.
|
||||
\return 1 Interrupt status is pending.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Pending Interrupt
|
||||
\details Sets the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Clear Pending Interrupt
|
||||
\details Clears the pending bit of a device specific interrupt in the NVIC pending register.
|
||||
\param [in] IRQn Device specific interrupt number.
|
||||
\note IRQn must not be negative.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Priority
|
||||
\details Sets the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\param [in] priority Priority to set.
|
||||
\note The priority cannot be set for every processor exception.
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
|
||||
{
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
else
|
||||
{
|
||||
SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
|
||||
(((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Priority
|
||||
\details Reads the priority of a device specific interrupt or a processor exception.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Interrupt Priority.
|
||||
Value is aligned automatically to the implemented priority bits of the microcontroller.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetPriority(IRQn_Type IRQn)
|
||||
{
|
||||
|
||||
if ((int32_t)(IRQn) >= 0)
|
||||
{
|
||||
return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
else
|
||||
{
|
||||
return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Encode Priority
|
||||
\details Encodes the priority for an interrupt with the given priority group,
|
||||
preemptive priority value, and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [in] PreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [in] SubPriority Subpriority value (starting from 0).
|
||||
\return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
|
||||
*/
|
||||
__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
return (
|
||||
((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
|
||||
((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Decode Priority
|
||||
\details Decodes an interrupt priority value with a given priority group to
|
||||
preemptive priority value and subpriority value.
|
||||
In case of a conflict between priority grouping and available
|
||||
priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
|
||||
\param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
|
||||
\param [in] PriorityGroup Used priority group.
|
||||
\param [out] pPreemptPriority Preemptive priority value (starting from 0).
|
||||
\param [out] pSubPriority Subpriority value (starting from 0).
|
||||
*/
|
||||
__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
|
||||
{
|
||||
uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
|
||||
uint32_t PreemptPriorityBits;
|
||||
uint32_t SubPriorityBits;
|
||||
|
||||
PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
|
||||
SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
|
||||
|
||||
*pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
|
||||
*pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
\brief Set Interrupt Vector
|
||||
\details Sets an interrupt vector in SRAM based interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
Address 0 must be mapped to SRAM.
|
||||
\param [in] IRQn Interrupt number
|
||||
\param [in] vector Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Get Interrupt Vector
|
||||
\details Reads an interrupt vector from interrupt vector table.
|
||||
The interrupt number can be positive to specify a device specific interrupt,
|
||||
or negative to specify a processor exception.
|
||||
\param [in] IRQn Interrupt number.
|
||||
\return Address of interrupt handler function
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
uint32_t *vectors = (uint32_t *)0x0U;
|
||||
return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief System Reset
|
||||
\details Initiates a system reset request to reset the MCU.
|
||||
*/
|
||||
__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void)
|
||||
{
|
||||
__DSB(); /* Ensure all outstanding memory accesses included
|
||||
buffered write are completed before reset */
|
||||
SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
|
||||
SCB_AIRCR_SYSRESETREQ_Msk);
|
||||
__DSB(); /* Ensure completion of memory access */
|
||||
|
||||
for(;;) /* wait until reset */
|
||||
{
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_FpuFunctions FPU Functions
|
||||
\brief Function that provides FPU type.
|
||||
@{
|
||||
*/
|
||||
|
||||
/**
|
||||
\brief get FPU type
|
||||
\details returns the FPU type
|
||||
\returns
|
||||
- \b 0: No FPU
|
||||
- \b 1: Single precision FPU
|
||||
- \b 2: Double + Single precision FPU
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SCB_GetFPUType(void)
|
||||
{
|
||||
return 0U; /* No FPU */
|
||||
}
|
||||
|
||||
|
||||
/*@} end of CMSIS_Core_FpuFunctions */
|
||||
|
||||
|
||||
|
||||
/* ################################## SysTick function ############################################ */
|
||||
/**
|
||||
\ingroup CMSIS_Core_FunctionInterface
|
||||
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
|
||||
\brief Functions that configure the System.
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
|
||||
|
||||
/**
|
||||
\brief System Tick Configuration
|
||||
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
|
||||
Counter is in free running mode to generate periodic interrupts.
|
||||
\param [in] ticks Number of ticks between two interrupts.
|
||||
\return 0 Function succeeded.
|
||||
\return 1 Function failed.
|
||||
\note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
|
||||
function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
|
||||
must contain a vendor-specific implementation of this function.
|
||||
*/
|
||||
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
|
||||
{
|
||||
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
|
||||
{
|
||||
return (1UL); /* Reload value impossible */
|
||||
}
|
||||
|
||||
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
|
||||
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
|
||||
SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
|
||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
|
||||
return (0UL); /* Function successful */
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of CMSIS_Core_SysTickFunctions */
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CORE_CM1_H_DEPENDANT */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
1993
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm23.h
Normal file
1993
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm23.h
Normal file
File diff suppressed because it is too large
Load Diff
1941
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm3.h
Normal file
1941
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm3.h
Normal file
File diff suppressed because it is too large
Load Diff
3002
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm33.h
Normal file
3002
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm33.h
Normal file
File diff suppressed because it is too large
Load Diff
2129
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm4.h
Normal file
2129
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm4.h
Normal file
File diff suppressed because it is too large
Load Diff
2671
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm7.h
Normal file
2671
STM32F103_Example/Drivers/CMSIS/Core/Include/core_cm7.h
Normal file
File diff suppressed because it is too large
Load Diff
1022
STM32F103_Example/Drivers/CMSIS/Core/Include/core_sc000.h
Normal file
1022
STM32F103_Example/Drivers/CMSIS/Core/Include/core_sc000.h
Normal file
File diff suppressed because it is too large
Load Diff
1915
STM32F103_Example/Drivers/CMSIS/Core/Include/core_sc300.h
Normal file
1915
STM32F103_Example/Drivers/CMSIS/Core/Include/core_sc300.h
Normal file
File diff suppressed because it is too large
Load Diff
270
STM32F103_Example/Drivers/CMSIS/Core/Include/mpu_armv7.h
Normal file
270
STM32F103_Example/Drivers/CMSIS/Core/Include/mpu_armv7.h
Normal file
@ -0,0 +1,270 @@
|
||||
/******************************************************************************
|
||||
* @file mpu_armv7.h
|
||||
* @brief CMSIS MPU API for Armv7-M MPU
|
||||
* @version V5.0.4
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef ARM_MPU_ARMV7_H
|
||||
#define ARM_MPU_ARMV7_H
|
||||
|
||||
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes
|
||||
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte
|
||||
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes
|
||||
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte
|
||||
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes
|
||||
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte
|
||||
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes
|
||||
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes
|
||||
|
||||
#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access
|
||||
#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only
|
||||
#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only
|
||||
#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access
|
||||
#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only
|
||||
#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access
|
||||
|
||||
/** MPU Region Base Address Register Value
|
||||
*
|
||||
* \param Region The region to be configured, number 0 to 15.
|
||||
* \param BaseAddress The base address for the region.
|
||||
*/
|
||||
#define ARM_MPU_RBAR(Region, BaseAddress) \
|
||||
(((BaseAddress) & MPU_RBAR_ADDR_Msk) | \
|
||||
((Region) & MPU_RBAR_REGION_Msk) | \
|
||||
(MPU_RBAR_VALID_Msk))
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attributes
|
||||
*
|
||||
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
|
||||
* \param IsShareable Region is shareable between multiple bus masters.
|
||||
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
|
||||
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
|
||||
*/
|
||||
#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \
|
||||
((((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
|
||||
(((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
|
||||
(((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
|
||||
(((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk))
|
||||
|
||||
/**
|
||||
* MPU Region Attribute and Size Register Value
|
||||
*
|
||||
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
|
||||
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
|
||||
* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_.
|
||||
* \param SubRegionDisable Sub-region disable field.
|
||||
* \param Size Region size of the region to be configured, for example 4K, 8K.
|
||||
*/
|
||||
#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \
|
||||
((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
|
||||
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
|
||||
(((AccessAttributes) ) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk)))
|
||||
|
||||
/**
|
||||
* MPU Region Attribute and Size Register Value
|
||||
*
|
||||
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
|
||||
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
|
||||
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
|
||||
* \param IsShareable Region is shareable between multiple bus masters.
|
||||
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
|
||||
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
|
||||
* \param SubRegionDisable Sub-region disable field.
|
||||
* \param Size Region size of the region to be configured, for example 4K, 8K.
|
||||
*/
|
||||
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
|
||||
ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size)
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute for strongly ordered memory.
|
||||
* - TEX: 000b
|
||||
* - Shareable
|
||||
* - Non-cacheable
|
||||
* - Non-bufferable
|
||||
*/
|
||||
#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U)
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute for device memory.
|
||||
* - TEX: 000b (if non-shareable) or 010b (if shareable)
|
||||
* - Shareable or non-shareable
|
||||
* - Non-cacheable
|
||||
* - Bufferable (if shareable) or non-bufferable (if non-shareable)
|
||||
*
|
||||
* \param IsShareable Configures the device memory as shareable or non-shareable.
|
||||
*/
|
||||
#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U))
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute for normal memory.
|
||||
* - TEX: 1BBb (reflecting outer cacheability rules)
|
||||
* - Shareable or non-shareable
|
||||
* - Cacheable or non-cacheable (reflecting inner cacheability rules)
|
||||
* - Bufferable or non-bufferable (reflecting inner cacheability rules)
|
||||
*
|
||||
* \param OuterCp Configures the outer cache policy.
|
||||
* \param InnerCp Configures the inner cache policy.
|
||||
* \param IsShareable Configures the memory as shareable or non-shareable.
|
||||
*/
|
||||
#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U))
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute non-cacheable policy.
|
||||
*/
|
||||
#define ARM_MPU_CACHEP_NOCACHE 0U
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute write-back, write and read allocate policy.
|
||||
*/
|
||||
#define ARM_MPU_CACHEP_WB_WRA 1U
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute write-through, no write allocate policy.
|
||||
*/
|
||||
#define ARM_MPU_CACHEP_WT_NWA 2U
|
||||
|
||||
/**
|
||||
* MPU Memory Access Attribute write-back, no write allocate policy.
|
||||
*/
|
||||
#define ARM_MPU_CACHEP_WB_NWA 3U
|
||||
|
||||
|
||||
/**
|
||||
* Struct for a single MPU Region
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t RBAR; //!< The region base address register value (RBAR)
|
||||
uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
|
||||
} ARM_MPU_Region_t;
|
||||
|
||||
/** Enable the MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Disable the MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable(void)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
/** Clear and disable the given MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
MPU->RASR = 0U;
|
||||
}
|
||||
|
||||
/** Configure an MPU region.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rsar Value for RSAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
|
||||
{
|
||||
MPU->RBAR = rbar;
|
||||
MPU->RASR = rasr;
|
||||
}
|
||||
|
||||
/** Configure the given MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rsar Value for RSAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
MPU->RBAR = rbar;
|
||||
MPU->RASR = rasr;
|
||||
}
|
||||
|
||||
/** Memcopy with strictly ordered memory access, e.g. for register targets.
|
||||
* \param dst Destination data is copied to.
|
||||
* \param src Source data is copied from.
|
||||
* \param len Amount of data words to be copied.
|
||||
*/
|
||||
__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0U; i < len; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
|
||||
while (cnt > MPU_TYPE_RALIASES) {
|
||||
orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
|
||||
table += MPU_TYPE_RALIASES;
|
||||
cnt -= MPU_TYPE_RALIASES;
|
||||
}
|
||||
orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
|
||||
#endif
|
333
STM32F103_Example/Drivers/CMSIS/Core/Include/mpu_armv8.h
Normal file
333
STM32F103_Example/Drivers/CMSIS/Core/Include/mpu_armv8.h
Normal file
@ -0,0 +1,333 @@
|
||||
/******************************************************************************
|
||||
* @file mpu_armv8.h
|
||||
* @brief CMSIS MPU API for Armv8-M MPU
|
||||
* @version V5.0.4
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef ARM_MPU_ARMV8_H
|
||||
#define ARM_MPU_ARMV8_H
|
||||
|
||||
/** \brief Attribute for device memory (outer only) */
|
||||
#define ARM_MPU_ATTR_DEVICE ( 0U )
|
||||
|
||||
/** \brief Attribute for non-cacheable, normal memory */
|
||||
#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U )
|
||||
|
||||
/** \brief Attribute for normal memory (outer and inner)
|
||||
* \param NT Non-Transient: Set to 1 for non-transient data.
|
||||
* \param WB Write-Back: Set to 1 to use write-back update policy.
|
||||
* \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
|
||||
* \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
|
||||
*/
|
||||
#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
|
||||
(((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U))
|
||||
|
||||
/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
|
||||
|
||||
/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGnRE (1U)
|
||||
|
||||
/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGRE (2U)
|
||||
|
||||
/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_GRE (3U)
|
||||
|
||||
/** \brief Memory Attribute
|
||||
* \param O Outer memory attributes
|
||||
* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
|
||||
*/
|
||||
#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U)))
|
||||
|
||||
/** \brief Normal memory non-shareable */
|
||||
#define ARM_MPU_SH_NON (0U)
|
||||
|
||||
/** \brief Normal memory outer shareable */
|
||||
#define ARM_MPU_SH_OUTER (2U)
|
||||
|
||||
/** \brief Normal memory inner shareable */
|
||||
#define ARM_MPU_SH_INNER (3U)
|
||||
|
||||
/** \brief Memory access permissions
|
||||
* \param RO Read-Only: Set to 1 for read-only memory.
|
||||
* \param NP Non-Privileged: Set to 1 for non-privileged memory.
|
||||
*/
|
||||
#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U))
|
||||
|
||||
/** \brief Region Base Address Register value
|
||||
* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
|
||||
* \param SH Defines the Shareability domain for this memory region.
|
||||
* \param RO Read-Only: Set to 1 for a read-only memory region.
|
||||
* \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
|
||||
* \oaram XN eXecute Never: Set to 1 for a non-executable memory region.
|
||||
*/
|
||||
#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
|
||||
((BASE & MPU_RBAR_BASE_Msk) | \
|
||||
((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
|
||||
((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
|
||||
((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
|
||||
|
||||
/** \brief Region Limit Address Register value
|
||||
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
|
||||
* \param IDX The attribute index to be associated with this memory region.
|
||||
*/
|
||||
#define ARM_MPU_RLAR(LIMIT, IDX) \
|
||||
((LIMIT & MPU_RLAR_LIMIT_Msk) | \
|
||||
((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
|
||||
(MPU_RLAR_EN_Msk))
|
||||
|
||||
/**
|
||||
* Struct for a single MPU Region
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t RBAR; /*!< Region Base Address Register value */
|
||||
uint32_t RLAR; /*!< Region Limit Address Register value */
|
||||
} ARM_MPU_Region_t;
|
||||
|
||||
/** Enable the MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Disable the MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable(void)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Enable the Non-secure MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Disable the Non-secure MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable_NS(void)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Set the memory attribute encoding to the given MPU.
|
||||
* \param mpu Pointer to the MPU to be configured.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
|
||||
{
|
||||
const uint8_t reg = idx / 4U;
|
||||
const uint32_t pos = ((idx % 4U) * 8U);
|
||||
const uint32_t mask = 0xFFU << pos;
|
||||
|
||||
if (reg >= (sizeof(mpu->MAIR) / sizeof(mpu->MAIR[0]))) {
|
||||
return; // invalid index
|
||||
}
|
||||
|
||||
mpu->MAIR[reg] = ((mpu->MAIR[reg] & ~mask) | ((attr << pos) & mask));
|
||||
}
|
||||
|
||||
/** Set the memory attribute encoding.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
|
||||
{
|
||||
ARM_MPU_SetMemAttrEx(MPU, idx, attr);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Set the memory attribute encoding to the Non-secure MPU.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
|
||||
{
|
||||
ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Clear and disable the given MPU region of the given MPU.
|
||||
* \param mpu Pointer to MPU to be used.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
|
||||
{
|
||||
mpu->RNR = rnr;
|
||||
mpu->RLAR = 0U;
|
||||
}
|
||||
|
||||
/** Clear and disable the given MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegionEx(MPU, rnr);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Clear and disable the given Non-secure MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegionEx(MPU_NS, rnr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Configure the given MPU region of the given MPU.
|
||||
* \param mpu Pointer to MPU to be used.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
mpu->RNR = rnr;
|
||||
mpu->RBAR = rbar;
|
||||
mpu->RLAR = rlar;
|
||||
}
|
||||
|
||||
/** Configure the given MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Configure the given Non-secure MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Memcopy with strictly ordered memory access, e.g. for register targets.
|
||||
* \param dst Destination data is copied to.
|
||||
* \param src Source data is copied from.
|
||||
* \param len Amount of data words to be copied.
|
||||
*/
|
||||
__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0U; i < len; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table to the given MPU.
|
||||
* \param mpu Pointer to the MPU registers to be used.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
|
||||
if (cnt == 1U) {
|
||||
mpu->RNR = rnr;
|
||||
orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
|
||||
} else {
|
||||
uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U);
|
||||
uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
|
||||
|
||||
mpu->RNR = rnrBase;
|
||||
while ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
|
||||
uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
|
||||
orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
|
||||
table += c;
|
||||
cnt -= c;
|
||||
rnrOffset = 0U;
|
||||
rnrBase += MPU_TYPE_RALIASES;
|
||||
mpu->RNR = rnrBase;
|
||||
}
|
||||
|
||||
orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
ARM_MPU_LoadEx(MPU, rnr, table, cnt);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Load the given number of MPU regions from a table to the Non-secure MPU.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
70
STM32F103_Example/Drivers/CMSIS/Core/Include/tz_context.h
Normal file
70
STM32F103_Example/Drivers/CMSIS/Core/Include/tz_context.h
Normal file
@ -0,0 +1,70 @@
|
||||
/******************************************************************************
|
||||
* @file tz_context.h
|
||||
* @brief Context Management for Armv8-M TrustZone
|
||||
* @version V1.0.1
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef TZ_CONTEXT_H
|
||||
#define TZ_CONTEXT_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef TZ_MODULEID_T
|
||||
#define TZ_MODULEID_T
|
||||
/// \details Data type that identifies secure software modules called by a process.
|
||||
typedef uint32_t TZ_ModuleId_t;
|
||||
#endif
|
||||
|
||||
/// \details TZ Memory ID identifies an allocated memory slot.
|
||||
typedef uint32_t TZ_MemoryId_t;
|
||||
|
||||
/// Initialize secure context memory system
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_InitContextSystem_S (void);
|
||||
|
||||
/// Allocate context memory for calling secure software modules in TrustZone
|
||||
/// \param[in] module identifies software modules called from non-secure mode
|
||||
/// \return value != 0 id TrustZone memory slot identifier
|
||||
/// \return value 0 no memory available or internal error
|
||||
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module);
|
||||
|
||||
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id);
|
||||
|
||||
/// Load secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id);
|
||||
|
||||
/// Store secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id);
|
||||
|
||||
#endif // TZ_CONTEXT_H
|
@ -0,0 +1,58 @@
|
||||
/******************************************************************************
|
||||
* @file main_s.c
|
||||
* @brief Code template for secure main function
|
||||
* @version V1.1.1
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2013-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* Use CMSE intrinsics */
|
||||
#include <arm_cmse.h>
|
||||
|
||||
#include "RTE_Components.h"
|
||||
#include CMSIS_device_header
|
||||
|
||||
/* TZ_START_NS: Start address of non-secure application */
|
||||
#ifndef TZ_START_NS
|
||||
#define TZ_START_NS (0x200000U)
|
||||
#endif
|
||||
|
||||
/* typedef for non-secure callback functions */
|
||||
typedef void (*funcptr_void) (void) __attribute__((cmse_nonsecure_call));
|
||||
|
||||
/* Secure main() */
|
||||
int main(void) {
|
||||
funcptr_void NonSecure_ResetHandler;
|
||||
|
||||
/* Add user setup code for secure part here*/
|
||||
|
||||
/* Set non-secure main stack (MSP_NS) */
|
||||
__TZ_set_MSP_NS(*((uint32_t *)(TZ_START_NS)));
|
||||
|
||||
/* Get non-secure reset handler */
|
||||
NonSecure_ResetHandler = (funcptr_void)(*((uint32_t *)((TZ_START_NS) + 4U)));
|
||||
|
||||
/* Start non-secure state software application */
|
||||
NonSecure_ResetHandler();
|
||||
|
||||
/* Non-secure software does not return, this code is not executed */
|
||||
while (1) {
|
||||
__NOP();
|
||||
}
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
/******************************************************************************
|
||||
* @file tz_context.c
|
||||
* @brief Context Management for Armv8-M TrustZone - Sample implementation
|
||||
* @version V1.1.1
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2016-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "RTE_Components.h"
|
||||
#include CMSIS_device_header
|
||||
#include "tz_context.h"
|
||||
|
||||
/// Number of process slots (threads may call secure library code)
|
||||
#ifndef TZ_PROCESS_STACK_SLOTS
|
||||
#define TZ_PROCESS_STACK_SLOTS 8U
|
||||
#endif
|
||||
|
||||
/// Stack size of the secure library code
|
||||
#ifndef TZ_PROCESS_STACK_SIZE
|
||||
#define TZ_PROCESS_STACK_SIZE 256U
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t sp_top; // stack space top
|
||||
uint32_t sp_limit; // stack space limit
|
||||
uint32_t sp; // current stack pointer
|
||||
} stack_info_t;
|
||||
|
||||
static stack_info_t ProcessStackInfo [TZ_PROCESS_STACK_SLOTS];
|
||||
static uint64_t ProcessStackMemory[TZ_PROCESS_STACK_SLOTS][TZ_PROCESS_STACK_SIZE/8U];
|
||||
static uint32_t ProcessStackFreeSlot = 0xFFFFFFFFU;
|
||||
|
||||
|
||||
/// Initialize secure context memory system
|
||||
/// \return execution status (1: success, 0: error)
|
||||
__attribute__((cmse_nonsecure_entry))
|
||||
uint32_t TZ_InitContextSystem_S (void) {
|
||||
uint32_t n;
|
||||
|
||||
if (__get_IPSR() == 0U) {
|
||||
return 0U; // Thread Mode
|
||||
}
|
||||
|
||||
for (n = 0U; n < TZ_PROCESS_STACK_SLOTS; n++) {
|
||||
ProcessStackInfo[n].sp = 0U;
|
||||
ProcessStackInfo[n].sp_limit = (uint32_t)&ProcessStackMemory[n];
|
||||
ProcessStackInfo[n].sp_top = (uint32_t)&ProcessStackMemory[n] + TZ_PROCESS_STACK_SIZE;
|
||||
*((uint32_t *)ProcessStackMemory[n]) = n + 1U;
|
||||
}
|
||||
*((uint32_t *)ProcessStackMemory[--n]) = 0xFFFFFFFFU;
|
||||
|
||||
ProcessStackFreeSlot = 0U;
|
||||
|
||||
// Default process stack pointer and stack limit
|
||||
__set_PSPLIM((uint32_t)ProcessStackMemory);
|
||||
__set_PSP ((uint32_t)ProcessStackMemory);
|
||||
|
||||
// Privileged Thread Mode using PSP
|
||||
__set_CONTROL(0x02U);
|
||||
|
||||
return 1U; // Success
|
||||
}
|
||||
|
||||
|
||||
/// Allocate context memory for calling secure software modules in TrustZone
|
||||
/// \param[in] module identifies software modules called from non-secure mode
|
||||
/// \return value != 0 id TrustZone memory slot identifier
|
||||
/// \return value 0 no memory available or internal error
|
||||
__attribute__((cmse_nonsecure_entry))
|
||||
TZ_MemoryId_t TZ_AllocModuleContext_S (TZ_ModuleId_t module) {
|
||||
uint32_t slot;
|
||||
|
||||
(void)module; // Ignore (fixed Stack size)
|
||||
|
||||
if (__get_IPSR() == 0U) {
|
||||
return 0U; // Thread Mode
|
||||
}
|
||||
|
||||
if (ProcessStackFreeSlot == 0xFFFFFFFFU) {
|
||||
return 0U; // No slot available
|
||||
}
|
||||
|
||||
slot = ProcessStackFreeSlot;
|
||||
ProcessStackFreeSlot = *((uint32_t *)ProcessStackMemory[slot]);
|
||||
|
||||
ProcessStackInfo[slot].sp = ProcessStackInfo[slot].sp_top;
|
||||
|
||||
return (slot + 1U);
|
||||
}
|
||||
|
||||
|
||||
/// Free context memory that was previously allocated with \ref TZ_AllocModuleContext_S
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
__attribute__((cmse_nonsecure_entry))
|
||||
uint32_t TZ_FreeModuleContext_S (TZ_MemoryId_t id) {
|
||||
uint32_t slot;
|
||||
|
||||
if (__get_IPSR() == 0U) {
|
||||
return 0U; // Thread Mode
|
||||
}
|
||||
|
||||
if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) {
|
||||
return 0U; // Invalid ID
|
||||
}
|
||||
|
||||
slot = id - 1U;
|
||||
|
||||
if (ProcessStackInfo[slot].sp == 0U) {
|
||||
return 0U; // Inactive slot
|
||||
}
|
||||
ProcessStackInfo[slot].sp = 0U;
|
||||
|
||||
*((uint32_t *)ProcessStackMemory[slot]) = ProcessStackFreeSlot;
|
||||
ProcessStackFreeSlot = slot;
|
||||
|
||||
return 1U; // Success
|
||||
}
|
||||
|
||||
|
||||
/// Load secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
__attribute__((cmse_nonsecure_entry))
|
||||
uint32_t TZ_LoadContext_S (TZ_MemoryId_t id) {
|
||||
uint32_t slot;
|
||||
|
||||
if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) {
|
||||
return 0U; // Thread Mode or using Main Stack for threads
|
||||
}
|
||||
|
||||
if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) {
|
||||
return 0U; // Invalid ID
|
||||
}
|
||||
|
||||
slot = id - 1U;
|
||||
|
||||
if (ProcessStackInfo[slot].sp == 0U) {
|
||||
return 0U; // Inactive slot
|
||||
}
|
||||
|
||||
// Setup process stack pointer and stack limit
|
||||
__set_PSPLIM(ProcessStackInfo[slot].sp_limit);
|
||||
__set_PSP (ProcessStackInfo[slot].sp);
|
||||
|
||||
return 1U; // Success
|
||||
}
|
||||
|
||||
|
||||
/// Store secure context (called on RTOS thread context switch)
|
||||
/// \param[in] id TrustZone memory slot identifier
|
||||
/// \return execution status (1: success, 0: error)
|
||||
__attribute__((cmse_nonsecure_entry))
|
||||
uint32_t TZ_StoreContext_S (TZ_MemoryId_t id) {
|
||||
uint32_t slot;
|
||||
uint32_t sp;
|
||||
|
||||
if ((__get_IPSR() == 0U) || ((__get_CONTROL() & 2U) == 0U)) {
|
||||
return 0U; // Thread Mode or using Main Stack for threads
|
||||
}
|
||||
|
||||
if ((id == 0U) || (id > TZ_PROCESS_STACK_SLOTS)) {
|
||||
return 0U; // Invalid ID
|
||||
}
|
||||
|
||||
slot = id - 1U;
|
||||
|
||||
if (ProcessStackInfo[slot].sp == 0U) {
|
||||
return 0U; // Inactive slot
|
||||
}
|
||||
|
||||
sp = __get_PSP();
|
||||
if ((sp < ProcessStackInfo[slot].sp_limit) ||
|
||||
(sp > ProcessStackInfo[slot].sp_top)) {
|
||||
return 0U; // SP out of range
|
||||
}
|
||||
ProcessStackInfo[slot].sp = sp;
|
||||
|
||||
// Default process stack pointer and stack limit
|
||||
__set_PSPLIM((uint32_t)ProcessStackMemory);
|
||||
__set_PSP ((uint32_t)ProcessStackMemory);
|
||||
|
||||
return 1U; // Success
|
||||
}
|
544
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_armcc.h
Normal file
544
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_armcc.h
Normal file
@ -0,0 +1,544 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_armcc.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.0.2
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_ARMCC_H
|
||||
#define __CMSIS_ARMCC_H
|
||||
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
|
||||
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler control architecture macros */
|
||||
#if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A == 1))
|
||||
#define __ARM_ARCH_7A__ 1
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE __forceinline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE static __forceinline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef CMSIS_DEPRECATED
|
||||
#define CMSIS_DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/**
|
||||
\brief No Operation
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __rbit
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Get FPSCR (Floating Point Status/Control)
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set FPSCR (Floating Point Status/Control)
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Get CPSR (Current Program Status Register)
|
||||
\return CPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPSR(void)
|
||||
{
|
||||
register uint32_t __regCPSR __ASM("cpsr");
|
||||
return(__regCPSR);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set CPSR (Current Program Status Register)
|
||||
\param [in] cpsr CPSR value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPSR(uint32_t cpsr)
|
||||
{
|
||||
register uint32_t __regCPSR __ASM("cpsr");
|
||||
__regCPSR = cpsr;
|
||||
}
|
||||
|
||||
/** \brief Get Mode
|
||||
\return Processor Mode
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_mode(void)
|
||||
{
|
||||
return (__get_CPSR() & 0x1FU);
|
||||
}
|
||||
|
||||
/** \brief Set Mode
|
||||
\param [in] mode Mode value to set
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_mode(uint32_t mode)
|
||||
{
|
||||
MOV r1, lr
|
||||
MSR CPSR_C, r0
|
||||
BX r1
|
||||
}
|
||||
|
||||
/** \brief Get Stack Pointer
|
||||
\return Stack Pointer
|
||||
*/
|
||||
__STATIC_INLINE __ASM uint32_t __get_SP(void)
|
||||
{
|
||||
MOV r0, sp
|
||||
BX lr
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
\param [in] stack Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_SP(uint32_t stack)
|
||||
{
|
||||
MOV sp, r0
|
||||
BX lr
|
||||
}
|
||||
|
||||
|
||||
/** \brief Get USR/SYS Stack Pointer
|
||||
\return USR/SYSStack Pointer
|
||||
*/
|
||||
__STATIC_INLINE __ASM uint32_t __get_SP_usr(void)
|
||||
{
|
||||
ARM
|
||||
PRESERVE8
|
||||
|
||||
MRS R1, CPSR
|
||||
CPS #0x1F ;no effect in USR mode
|
||||
MOV R0, SP
|
||||
MSR CPSR_c, R1 ;no effect in USR mode
|
||||
ISB
|
||||
BX LR
|
||||
}
|
||||
|
||||
/** \brief Set USR/SYS Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack)
|
||||
{
|
||||
ARM
|
||||
PRESERVE8
|
||||
|
||||
MRS R1, CPSR
|
||||
CPS #0x1F ;no effect in USR mode
|
||||
MOV SP, R0
|
||||
MSR CPSR_c, R1 ;no effect in USR mode
|
||||
ISB
|
||||
BX LR
|
||||
}
|
||||
|
||||
/** \brief Get FPEXC (Floating Point Exception Control Register)
|
||||
\return Floating Point Exception Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
register uint32_t __regfpexc __ASM("fpexc");
|
||||
return(__regfpexc);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Set FPEXC (Floating Point Exception Control Register)
|
||||
\param [in] fpexc Floating Point Exception Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
register uint32_t __regfpexc __ASM("fpexc");
|
||||
__regfpexc = (fpexc);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Include common core functions to access Coprocessor 15 registers
|
||||
*/
|
||||
|
||||
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); (Rt) = tmp; } while(0)
|
||||
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = (Rt); } while(0)
|
||||
#define __get_CP64(cp, op1, Rt, CRm) \
|
||||
do { \
|
||||
uint32_t ltmp, htmp; \
|
||||
__ASM volatile("MRRC p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \
|
||||
(Rt) = ((((uint64_t)htmp) << 32U) | ((uint64_t)ltmp)); \
|
||||
} while(0)
|
||||
|
||||
#define __set_CP64(cp, op1, Rt, CRm) \
|
||||
do { \
|
||||
const uint64_t tmp = (Rt); \
|
||||
const uint32_t ltmp = (uint32_t)(tmp); \
|
||||
const uint32_t htmp = (uint32_t)(tmp >> 32U); \
|
||||
__ASM volatile("MCRR p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \
|
||||
} while(0)
|
||||
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
/** \brief Enable Floating Point Unit
|
||||
|
||||
Critical section, called from undef handler, so systick is disabled
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __FPU_Enable(void)
|
||||
{
|
||||
ARM
|
||||
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
MRC p15,0,R1,c1,c0,2
|
||||
ORR R1,R1,#0x00F00000
|
||||
MCR p15,0,R1,c1,c0,2
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
ISB
|
||||
|
||||
//Enable VFP/NEON
|
||||
VMRS R1,FPEXC
|
||||
ORR R1,R1,#0x40000000
|
||||
VMSR FPEXC,R1
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
MOV R2,#0
|
||||
|
||||
//Initialise D16 registers to 0
|
||||
VMOV D0, R2,R2
|
||||
VMOV D1, R2,R2
|
||||
VMOV D2, R2,R2
|
||||
VMOV D3, R2,R2
|
||||
VMOV D4, R2,R2
|
||||
VMOV D5, R2,R2
|
||||
VMOV D6, R2,R2
|
||||
VMOV D7, R2,R2
|
||||
VMOV D8, R2,R2
|
||||
VMOV D9, R2,R2
|
||||
VMOV D10,R2,R2
|
||||
VMOV D11,R2,R2
|
||||
VMOV D12,R2,R2
|
||||
VMOV D13,R2,R2
|
||||
VMOV D14,R2,R2
|
||||
VMOV D15,R2,R2
|
||||
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
|
||||
//Initialise D32 registers to 0
|
||||
VMOV D16,R2,R2
|
||||
VMOV D17,R2,R2
|
||||
VMOV D18,R2,R2
|
||||
VMOV D19,R2,R2
|
||||
VMOV D20,R2,R2
|
||||
VMOV D21,R2,R2
|
||||
VMOV D22,R2,R2
|
||||
VMOV D23,R2,R2
|
||||
VMOV D24,R2,R2
|
||||
VMOV D25,R2,R2
|
||||
VMOV D26,R2,R2
|
||||
VMOV D27,R2,R2
|
||||
VMOV D28,R2,R2
|
||||
VMOV D29,R2,R2
|
||||
VMOV D30,R2,R2
|
||||
VMOV D31,R2,R2
|
||||
ENDIF
|
||||
|
||||
//Initialise FPSCR to a known state
|
||||
VMRS R2,FPSCR
|
||||
LDR R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
AND R2,R2,R3
|
||||
VMSR FPSCR,R2
|
||||
|
||||
BX LR
|
||||
}
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
503
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_armclang.h
Normal file
503
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_armclang.h
Normal file
@ -0,0 +1,503 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_armclang.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.0.2
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_ARMCLANG_H
|
||||
#define __CMSIS_ARMCLANG_H
|
||||
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
|
||||
#ifndef __ARM_COMPAT_H
|
||||
#include <arm_compat.h> /* Compatibility header for Arm Compiler 5 intrinsics */
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE __attribute__((always_inline))
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((__noreturn__))
|
||||
#endif
|
||||
#ifndef CMSIS_DEPRECATED
|
||||
#define CMSIS_DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/**
|
||||
\brief No Operation
|
||||
*/
|
||||
#define __NOP __builtin_arm_nop
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
*/
|
||||
#define __WFI __builtin_arm_wfi
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
*/
|
||||
#define __WFE __builtin_arm_wfe
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
*/
|
||||
#define __SEV __builtin_arm_sev
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__builtin_arm_isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__builtin_arm_dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__builtin_arm_dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0U)
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV(value) __builtin_bswap32(value)
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV16(value) __ROR(__REV(value), 16)
|
||||
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REVSH(value) (int16_t)__builtin_bswap16(value)
|
||||
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
op2 %= 32U;
|
||||
if (op2 == 0U)
|
||||
{
|
||||
return op1;
|
||||
}
|
||||
return (op1 >> op2) | (op1 << (32U - op2));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __RBIT __builtin_arm_rbit
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ (uint8_t)__builtin_clz
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB (uint8_t)__builtin_arm_ldrex
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH (uint16_t)__builtin_arm_ldrex
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW (uint32_t)__builtin_arm_ldrex
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB (uint32_t)__builtin_arm_strex
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH (uint32_t)__builtin_arm_strex
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW (uint32_t)__builtin_arm_strex
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
#define __CLREX __builtin_arm_clrex
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __builtin_arm_ssat
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __builtin_arm_usat
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\details Returns the current value of the Floating Point Status/Control register.
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
#define __get_FPSCR __builtin_arm_get_fpscr
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\details Assigns the given value to the Floating Point Status/Control register.
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
#define __set_FPSCR __builtin_arm_set_fpscr
|
||||
|
||||
/** \brief Get CPSR Register
|
||||
\return CPSR Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, cpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/** \brief Set CPSR Register
|
||||
\param [in] cpsr CPSR value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr)
|
||||
{
|
||||
__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get Mode
|
||||
\return Processor Mode
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_mode(void)
|
||||
{
|
||||
return (__get_CPSR() & 0x1FU);
|
||||
}
|
||||
|
||||
/** \brief Set Mode
|
||||
\param [in] mode Mode value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_mode(uint32_t mode)
|
||||
{
|
||||
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get Stack Pointer
|
||||
\return Stack Pointer value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_SP()
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MOV %0, sp" : "=r" (result) : : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
\param [in] stack Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_SP(uint32_t stack)
|
||||
{
|
||||
__ASM volatile("MOV sp, %0" : : "r" (stack) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get USR/SYS Stack Pointer
|
||||
\return USR/SYS Stack Pointer value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_SP_usr()
|
||||
{
|
||||
uint32_t cpsr;
|
||||
uint32_t result;
|
||||
__ASM volatile(
|
||||
"MRS %0, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV %1, sp \n"
|
||||
"MSR cpsr_c, %2 \n" // no effect in USR mode
|
||||
"ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory"
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set USR/SYS Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack)
|
||||
{
|
||||
uint32_t cpsr;
|
||||
__ASM volatile(
|
||||
"MRS %0, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV sp, %1 \n"
|
||||
"MSR cpsr_c, %2 \n" // no effect in USR mode
|
||||
"ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/** \brief Get FPEXC
|
||||
\return Floating Point Exception Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
uint32_t result;
|
||||
__ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory");
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Set FPEXC
|
||||
\param [in] fpexc Floating Point Exception Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Include common core functions to access Coprocessor 15 registers
|
||||
*/
|
||||
|
||||
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
|
||||
#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
|
||||
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
/** \brief Enable Floating Point Unit
|
||||
|
||||
Critical section, called from undef handler, so systick is disabled
|
||||
*/
|
||||
__STATIC_INLINE void __FPU_Enable(void)
|
||||
{
|
||||
__ASM volatile(
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
" MRC p15,0,R1,c1,c0,2 \n"
|
||||
" ORR R1,R1,#0x00F00000 \n"
|
||||
" MCR p15,0,R1,c1,c0,2 \n"
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
" ISB \n"
|
||||
|
||||
//Enable VFP/NEON
|
||||
" VMRS R1,FPEXC \n"
|
||||
" ORR R1,R1,#0x40000000 \n"
|
||||
" VMSR FPEXC,R1 \n"
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
" MOV R2,#0 \n"
|
||||
|
||||
//Initialise D16 registers to 0
|
||||
" VMOV D0, R2,R2 \n"
|
||||
" VMOV D1, R2,R2 \n"
|
||||
" VMOV D2, R2,R2 \n"
|
||||
" VMOV D3, R2,R2 \n"
|
||||
" VMOV D4, R2,R2 \n"
|
||||
" VMOV D5, R2,R2 \n"
|
||||
" VMOV D6, R2,R2 \n"
|
||||
" VMOV D7, R2,R2 \n"
|
||||
" VMOV D8, R2,R2 \n"
|
||||
" VMOV D9, R2,R2 \n"
|
||||
" VMOV D10,R2,R2 \n"
|
||||
" VMOV D11,R2,R2 \n"
|
||||
" VMOV D12,R2,R2 \n"
|
||||
" VMOV D13,R2,R2 \n"
|
||||
" VMOV D14,R2,R2 \n"
|
||||
" VMOV D15,R2,R2 \n"
|
||||
|
||||
#if __ARM_NEON == 1
|
||||
//Initialise D32 registers to 0
|
||||
" VMOV D16,R2,R2 \n"
|
||||
" VMOV D17,R2,R2 \n"
|
||||
" VMOV D18,R2,R2 \n"
|
||||
" VMOV D19,R2,R2 \n"
|
||||
" VMOV D20,R2,R2 \n"
|
||||
" VMOV D21,R2,R2 \n"
|
||||
" VMOV D22,R2,R2 \n"
|
||||
" VMOV D23,R2,R2 \n"
|
||||
" VMOV D24,R2,R2 \n"
|
||||
" VMOV D25,R2,R2 \n"
|
||||
" VMOV D26,R2,R2 \n"
|
||||
" VMOV D27,R2,R2 \n"
|
||||
" VMOV D28,R2,R2 \n"
|
||||
" VMOV D29,R2,R2 \n"
|
||||
" VMOV D30,R2,R2 \n"
|
||||
" VMOV D31,R2,R2 \n"
|
||||
#endif
|
||||
|
||||
//Initialise FPSCR to a known state
|
||||
" VMRS R2,FPSCR \n"
|
||||
" LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
" AND R2,R2,R3 \n"
|
||||
" VMSR FPSCR,R2 "
|
||||
);
|
||||
}
|
||||
|
||||
#endif /* __CMSIS_ARMCLANG_H */
|
201
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_compiler.h
Normal file
201
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_compiler.h
Normal file
@ -0,0 +1,201 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_compiler.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.0.2
|
||||
* @date 10. January 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_COMPILER_H
|
||||
#define __CMSIS_COMPILER_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
* Arm Compiler 4/5
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#include "cmsis_armcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* Arm Compiler 6 (armclang)
|
||||
*/
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#include "cmsis_armclang.h"
|
||||
|
||||
|
||||
/*
|
||||
* GNU Compiler
|
||||
*/
|
||||
#elif defined ( __GNUC__ )
|
||||
#include "cmsis_gcc.h"
|
||||
|
||||
|
||||
/*
|
||||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
#include "cmsis_iccarm.h"
|
||||
|
||||
|
||||
/*
|
||||
* TI Arm Compiler
|
||||
*/
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef CMSIS_DEPRECATED
|
||||
#define CMSIS_DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* TASKING Compiler
|
||||
*/
|
||||
#elif defined ( __TASKING__ )
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef CMSIS_DEPRECATED
|
||||
#define CMSIS_DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
struct __packed__ T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __align(x)
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed__
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* COSMIC Compiler
|
||||
*/
|
||||
#elif defined ( __CSMC__ )
|
||||
#include <cmsis_csm.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM _asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
// NO RETURN is automatically detected hence no warning here
|
||||
#define __NO_RETURN
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#warning No compiler specific solution for __USED. __USED is ignored.
|
||||
#define __USED
|
||||
#endif
|
||||
#ifndef CMSIS_DEPRECATED
|
||||
#warning No compiler specific solution for CMSIS_DEPRECATED. CMSIS_DEPRECATED is ignored.
|
||||
#define CMSIS_DEPRECATED
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
@packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED @packed
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
#error Unknown compiler.
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __CMSIS_COMPILER_H */
|
||||
|
514
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_cp15.h
Normal file
514
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_cp15.h
Normal file
@ -0,0 +1,514 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_cp15.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.0.1
|
||||
* @date 07. Sep 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CMSIS_CP15_H
|
||||
#define __CMSIS_CP15_H
|
||||
|
||||
/** \brief Get ACTLR
|
||||
\return Auxiliary Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_ACTLR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 1, 0, 1);
|
||||
return(result);
|
||||
}
|
||||
|
||||
/** \brief Set ACTLR
|
||||
\param [in] actlr Auxiliary Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr)
|
||||
{
|
||||
__set_CP(15, 0, actlr, 1, 0, 1);
|
||||
}
|
||||
|
||||
/** \brief Get CPACR
|
||||
\return Coprocessor Access Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CPACR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 1, 0, 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CPACR
|
||||
\param [in] cpacr Coprocessor Access Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr)
|
||||
{
|
||||
__set_CP(15, 0, cpacr, 1, 0, 2);
|
||||
}
|
||||
|
||||
/** \brief Get DFSR
|
||||
\return Data Fault Status Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_DFSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 5, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set DFSR
|
||||
\param [in] dfsr Data Fault Status value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr)
|
||||
{
|
||||
__set_CP(15, 0, dfsr, 5, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get IFSR
|
||||
\return Instruction Fault Status Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_IFSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 5, 0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set IFSR
|
||||
\param [in] ifsr Instruction Fault Status value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr)
|
||||
{
|
||||
__set_CP(15, 0, ifsr, 5, 0, 1);
|
||||
}
|
||||
|
||||
/** \brief Get ISR
|
||||
\return Interrupt Status Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_ISR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 12, 1, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get CBAR
|
||||
\return Configuration Base Address register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CBAR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 4, result, 15, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get TTBR0
|
||||
|
||||
This function returns the value of the Translation Table Base Register 0.
|
||||
|
||||
\return Translation Table Base Register 0 value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_TTBR0(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 2, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set TTBR0
|
||||
|
||||
This function assigns the given value to the Translation Table Base Register 0.
|
||||
|
||||
\param [in] ttbr0 Translation Table Base Register 0 value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_TTBR0(uint32_t ttbr0)
|
||||
{
|
||||
__set_CP(15, 0, ttbr0, 2, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get DACR
|
||||
|
||||
This function returns the value of the Domain Access Control Register.
|
||||
|
||||
\return Domain Access Control Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_DACR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 3, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set DACR
|
||||
|
||||
This function assigns the given value to the Domain Access Control Register.
|
||||
|
||||
\param [in] dacr Domain Access Control Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DACR(uint32_t dacr)
|
||||
{
|
||||
__set_CP(15, 0, dacr, 3, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Set SCTLR
|
||||
|
||||
This function assigns the given value to the System Control Register.
|
||||
|
||||
\param [in] sctlr System Control Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr)
|
||||
{
|
||||
__set_CP(15, 0, sctlr, 1, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get SCTLR
|
||||
\return System Control Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_SCTLR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 1, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set ACTRL
|
||||
\param [in] actrl Auxiliary Control Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl)
|
||||
{
|
||||
__set_CP(15, 0, actrl, 1, 0, 1);
|
||||
}
|
||||
|
||||
/** \brief Get ACTRL
|
||||
\return Auxiliary Control Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_ACTRL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 1, 0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get MPIDR
|
||||
|
||||
This function returns the value of the Multiprocessor Affinity Register.
|
||||
|
||||
\return Multiprocessor Affinity Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_MPIDR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 0, 0, 5);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get VBAR
|
||||
|
||||
This function returns the value of the Vector Base Address Register.
|
||||
|
||||
\return Vector Base Address Register
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_VBAR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 12, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set VBAR
|
||||
|
||||
This function assigns the given value to the Vector Base Address Register.
|
||||
|
||||
\param [in] vbar Vector Base Address Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar)
|
||||
{
|
||||
__set_CP(15, 0, vbar, 12, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get MVBAR
|
||||
|
||||
This function returns the value of the Monitor Vector Base Address Register.
|
||||
|
||||
\return Monitor Vector Base Address Register
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_MVBAR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 12, 0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set MVBAR
|
||||
|
||||
This function assigns the given value to the Monitor Vector Base Address Register.
|
||||
|
||||
\param [in] mvbar Monitor Vector Base Address Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_MVBAR(uint32_t mvbar)
|
||||
{
|
||||
__set_CP(15, 0, mvbar, 12, 0, 1);
|
||||
}
|
||||
|
||||
#if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \
|
||||
defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \
|
||||
defined(DOXYGEN)
|
||||
|
||||
/** \brief Set CNTFRQ
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ).
|
||||
|
||||
\param [in] value CNTFRQ Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 14, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get CNTFRQ
|
||||
|
||||
This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ).
|
||||
|
||||
\return CNTFRQ Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 14, 0 , 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_TVAL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\param [in] value CNTP_TVAL Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 14, 2, 0);
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_TVAL
|
||||
|
||||
This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\return CNTP_TVAL Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 14, 2, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get CNTPCT
|
||||
|
||||
This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT).
|
||||
|
||||
\return CNTPCT Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint64_t __get_CNTPCT(void)
|
||||
{
|
||||
uint64_t result;
|
||||
__get_CP64(15, 0, result, 14);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_CVAL
|
||||
|
||||
This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
|
||||
|
||||
\param [in] value CNTP_CVAL Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CNTP_CVAL(uint64_t value)
|
||||
{
|
||||
__set_CP64(15, 2, value, 14);
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_CVAL
|
||||
|
||||
This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
|
||||
|
||||
\return CNTP_CVAL Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint64_t __get_CNTP_CVAL(void)
|
||||
{
|
||||
uint64_t result;
|
||||
__get_CP64(15, 2, result, 14);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_CTL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
|
||||
|
||||
\param [in] value CNTP_CTL Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 14, 2, 1);
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_CTL register
|
||||
\return CNTP_CTL Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__get_CP(15, 0, result, 14, 2, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/** \brief Set TLBIALL
|
||||
|
||||
TLB Invalidate All
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_TLBIALL(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 8, 7, 0);
|
||||
}
|
||||
|
||||
/** \brief Set BPIALL.
|
||||
|
||||
Branch Predictor Invalidate All
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_BPIALL(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 7, 5, 6);
|
||||
}
|
||||
|
||||
/** \brief Set ICIALLU
|
||||
|
||||
Instruction Cache Invalidate All
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 7, 5, 0);
|
||||
}
|
||||
|
||||
/** \brief Set DCCMVAC
|
||||
|
||||
Data cache clean
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 7, 10, 1);
|
||||
}
|
||||
|
||||
/** \brief Set DCIMVAC
|
||||
|
||||
Data cache invalidate
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 7, 6, 1);
|
||||
}
|
||||
|
||||
/** \brief Set DCCIMVAC
|
||||
|
||||
Data cache clean and invalidate
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value)
|
||||
{
|
||||
__set_CP(15, 0, value, 7, 14, 1);
|
||||
}
|
||||
|
||||
/** \brief Set CSSELR
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CSSELR(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory");
|
||||
__set_CP(15, 2, value, 0, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get CSSELR
|
||||
\return CSSELR Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CSSELR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 2, %0, c0, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 2, result, 0, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CCSIDR
|
||||
\deprecated CCSIDR itself is read-only. Use __set_CSSELR to select cache level instead.
|
||||
*/
|
||||
CMSIS_DEPRECATED
|
||||
__STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value)
|
||||
{
|
||||
__set_CSSELR(value);
|
||||
}
|
||||
|
||||
/** \brief Get CCSIDR
|
||||
\return CCSIDR Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CCSIDR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 1, result, 0, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get CLIDR
|
||||
\return CLIDR Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CLIDR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 1, result, 0, 0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set DCISW
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCISW(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(value) : "memory")
|
||||
__set_CP(15, 0, value, 7, 6, 2);
|
||||
}
|
||||
|
||||
/** \brief Set DCCSW
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCCSW(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(value) : "memory")
|
||||
__set_CP(15, 0, value, 7, 10, 2);
|
||||
}
|
||||
|
||||
/** \brief Set DCCISW
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCCISW(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(value) : "memory")
|
||||
__set_CP(15, 0, value, 7, 14, 2);
|
||||
}
|
||||
|
||||
#endif
|
679
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_gcc.h
Normal file
679
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_gcc.h
Normal file
@ -0,0 +1,679 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_gcc.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.0.2
|
||||
* @date 09. April 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Arm Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_GCC_H
|
||||
#define __CMSIS_GCC_H
|
||||
|
||||
/* ignore some GCC warnings */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
/* Fallback for __has_builtin */
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) (0)
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE __attribute__((always_inline))
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((__noreturn__))
|
||||
#endif
|
||||
#ifndef CMSIS_DEPRECATED
|
||||
#define CMSIS_DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#pragma GCC diagnostic pop
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#pragma GCC diagnostic pop
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#pragma GCC diagnostic pop
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#pragma GCC diagnostic pop
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/**
|
||||
\brief No Operation
|
||||
*/
|
||||
#define __NOP() __ASM volatile ("nop")
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
*/
|
||||
#define __WFI() __ASM volatile ("wfi")
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
*/
|
||||
#define __WFE() __ASM volatile ("wfe")
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
*/
|
||||
#define __SEV() __ASM volatile ("sev")
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or memory,
|
||||
after the instruction has been completed.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb 0xF":::"memory");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
\details Acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb 0xF":::"memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
\details Ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb 0xF":::"memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
return __builtin_bswap32(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("rev16 %0, %1" : "=r" (result) : "r" (value));
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE int16_t __REVSH(int16_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
return (int16_t)__builtin_bswap16(value);
|
||||
#else
|
||||
int16_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
op2 %= 32U;
|
||||
if (op2 == 0U) {
|
||||
return op1;
|
||||
}
|
||||
return (op1 >> op2) | (op1 << (32U - op2));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\details Reverses the bit order of the given value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
#else
|
||||
int32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ (uint8_t)__builtin_clz
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint16_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex" ::: "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
__extension__ \
|
||||
({ \
|
||||
int32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
__extension__ \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Enable IRQ Interrupts
|
||||
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie i" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Disable IRQ Interrupts
|
||||
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid i" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\details Returns the current value of the Floating Point Status/Control register.
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#if __has_builtin(__builtin_arm_get_fpscr)
|
||||
// Re-enable using built-in when GCC has been fixed
|
||||
// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
|
||||
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
|
||||
return __builtin_arm_get_fpscr();
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#endif
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\details Assigns the given value to the Floating Point Status/Control register.
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#if __has_builtin(__builtin_arm_set_fpscr)
|
||||
// Re-enable using built-in when GCC has been fixed
|
||||
// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
|
||||
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
|
||||
__builtin_arm_set_fpscr(fpscr);
|
||||
#else
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory");
|
||||
#endif
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Get CPSR Register
|
||||
\return CPSR Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, cpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/** \brief Set CPSR Register
|
||||
\param [in] cpsr CPSR value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr)
|
||||
{
|
||||
__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get Mode
|
||||
\return Processor Mode
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_mode(void)
|
||||
{
|
||||
return (__get_CPSR() & 0x1FU);
|
||||
}
|
||||
|
||||
/** \brief Set Mode
|
||||
\param [in] mode Mode value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_mode(uint32_t mode)
|
||||
{
|
||||
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get Stack Pointer
|
||||
\return Stack Pointer value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_SP(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MOV %0, sp" : "=r" (result) : : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
\param [in] stack Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_SP(uint32_t stack)
|
||||
{
|
||||
__ASM volatile("MOV sp, %0" : : "r" (stack) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get USR/SYS Stack Pointer
|
||||
\return USR/SYS Stack Pointer value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_SP_usr(void)
|
||||
{
|
||||
uint32_t cpsr = __get_CPSR();
|
||||
uint32_t result;
|
||||
__ASM volatile(
|
||||
"CPS #0x1F \n"
|
||||
"MOV %0, sp " : "=r"(result) : : "memory"
|
||||
);
|
||||
__set_CPSR(cpsr);
|
||||
__ISB();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set USR/SYS Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack)
|
||||
{
|
||||
uint32_t cpsr = __get_CPSR();
|
||||
__ASM volatile(
|
||||
"CPS #0x1F \n"
|
||||
"MOV sp, %0 " : : "r" (topOfProcStack) : "memory"
|
||||
);
|
||||
__set_CPSR(cpsr);
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/** \brief Get FPEXC
|
||||
\return Floating Point Exception Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
uint32_t result;
|
||||
__ASM volatile("VMRS %0, fpexc" : "=r" (result) );
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Set FPEXC
|
||||
\param [in] fpexc Floating Point Exception Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Include common core functions to access Coprocessor 15 registers
|
||||
*/
|
||||
|
||||
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
|
||||
#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
|
||||
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
/** \brief Enable Floating Point Unit
|
||||
|
||||
Critical section, called from undef handler, so systick is disabled
|
||||
*/
|
||||
__STATIC_INLINE void __FPU_Enable(void)
|
||||
{
|
||||
__ASM volatile(
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
" MRC p15,0,R1,c1,c0,2 \n"
|
||||
" ORR R1,R1,#0x00F00000 \n"
|
||||
" MCR p15,0,R1,c1,c0,2 \n"
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
" ISB \n"
|
||||
|
||||
//Enable VFP/NEON
|
||||
" VMRS R1,FPEXC \n"
|
||||
" ORR R1,R1,#0x40000000 \n"
|
||||
" VMSR FPEXC,R1 \n"
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
" MOV R2,#0 \n"
|
||||
|
||||
//Initialise D16 registers to 0
|
||||
" VMOV D0, R2,R2 \n"
|
||||
" VMOV D1, R2,R2 \n"
|
||||
" VMOV D2, R2,R2 \n"
|
||||
" VMOV D3, R2,R2 \n"
|
||||
" VMOV D4, R2,R2 \n"
|
||||
" VMOV D5, R2,R2 \n"
|
||||
" VMOV D6, R2,R2 \n"
|
||||
" VMOV D7, R2,R2 \n"
|
||||
" VMOV D8, R2,R2 \n"
|
||||
" VMOV D9, R2,R2 \n"
|
||||
" VMOV D10,R2,R2 \n"
|
||||
" VMOV D11,R2,R2 \n"
|
||||
" VMOV D12,R2,R2 \n"
|
||||
" VMOV D13,R2,R2 \n"
|
||||
" VMOV D14,R2,R2 \n"
|
||||
" VMOV D15,R2,R2 \n"
|
||||
|
||||
#if (defined(__ARM_NEON) && (__ARM_NEON == 1))
|
||||
//Initialise D32 registers to 0
|
||||
" VMOV D16,R2,R2 \n"
|
||||
" VMOV D17,R2,R2 \n"
|
||||
" VMOV D18,R2,R2 \n"
|
||||
" VMOV D19,R2,R2 \n"
|
||||
" VMOV D20,R2,R2 \n"
|
||||
" VMOV D21,R2,R2 \n"
|
||||
" VMOV D22,R2,R2 \n"
|
||||
" VMOV D23,R2,R2 \n"
|
||||
" VMOV D24,R2,R2 \n"
|
||||
" VMOV D25,R2,R2 \n"
|
||||
" VMOV D26,R2,R2 \n"
|
||||
" VMOV D27,R2,R2 \n"
|
||||
" VMOV D28,R2,R2 \n"
|
||||
" VMOV D29,R2,R2 \n"
|
||||
" VMOV D30,R2,R2 \n"
|
||||
" VMOV D31,R2,R2 \n"
|
||||
#endif
|
||||
|
||||
//Initialise FPSCR to a known state
|
||||
" VMRS R2,FPSCR \n"
|
||||
" LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
" AND R2,R2,R3 \n"
|
||||
" VMSR FPSCR,R2 "
|
||||
);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#endif /* __CMSIS_GCC_H */
|
559
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h
Normal file
559
STM32F103_Example/Drivers/CMSIS/Core_A/Include/cmsis_iccarm.h
Normal file
@ -0,0 +1,559 @@
|
||||
/**************************************************************************//**
|
||||
* @file cmsis_iccarm.h
|
||||
* @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file
|
||||
* @version V5.0.6
|
||||
* @date 02. March 2018
|
||||
******************************************************************************/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017-2018 IAR Systems
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License")
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __CMSIS_ICCARM_H__
|
||||
#define __CMSIS_ICCARM_H__
|
||||
|
||||
#ifndef __ICCARM__
|
||||
#error This file should only be compiled by ICCARM
|
||||
#endif
|
||||
|
||||
#pragma system_include
|
||||
|
||||
#define __IAR_FT _Pragma("inline=forced") __intrinsic
|
||||
|
||||
#if (__VER__ >= 8000000)
|
||||
#define __ICCARM_V8 1
|
||||
#else
|
||||
#define __ICCARM_V8 0
|
||||
#endif
|
||||
|
||||
#pragma language=extended
|
||||
|
||||
#ifndef __ALIGNED
|
||||
#if __ICCARM_V8
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#elif (__VER__ >= 7080000)
|
||||
/* Needs IAR language extensions */
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#else
|
||||
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler macros for CPU architecture, used in CMSIS 5.
|
||||
*/
|
||||
#if __ARM_ARCH_7A__
|
||||
/* Macro already defined */
|
||||
#else
|
||||
#if defined(__ARM7A__)
|
||||
#define __ARM_ARCH_7A__ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#if __ICCARM_V8
|
||||
#define __NO_RETURN __attribute__((__noreturn__))
|
||||
#else
|
||||
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
/* Needs IAR language extensions */
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_STRUCT
|
||||
/* Needs IAR language extensions */
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_UNION
|
||||
/* Needs IAR language extensions */
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
#define __PACKED_UNION __packed union
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE _Pragma("inline=forced")
|
||||
#endif
|
||||
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE
|
||||
#endif
|
||||
|
||||
#ifndef CMSIS_DEPRECATED
|
||||
#define CMSIS_DEPRECATED __attribute__((deprecated))
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint16_t __iar_uint16_read(void const *ptr)
|
||||
{
|
||||
return *(__packed uint16_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val)
|
||||
{
|
||||
*(__packed uint16_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint32_t __iar_uint32_read(void const *ptr)
|
||||
{
|
||||
return *(__packed uint32_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val)
|
||||
{
|
||||
*(__packed uint32_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__packed struct __iar_u32 { uint32_t v; };
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __USED
|
||||
#if __ICCARM_V8
|
||||
#define __USED __attribute__((used))
|
||||
#else
|
||||
#define __USED _Pragma("__root")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __WEAK
|
||||
#if __ICCARM_V8
|
||||
#define __WEAK __attribute__((weak))
|
||||
#else
|
||||
#define __WEAK _Pragma("__weak")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ICCARM_INTRINSICS_VERSION__
|
||||
#define __ICCARM_INTRINSICS_VERSION__ 0
|
||||
#endif
|
||||
|
||||
#if __ICCARM_INTRINSICS_VERSION__ == 2
|
||||
|
||||
#if defined(__CLZ)
|
||||
#undef __CLZ
|
||||
#endif
|
||||
#if defined(__REVSH)
|
||||
#undef __REVSH
|
||||
#endif
|
||||
#if defined(__RBIT)
|
||||
#undef __RBIT
|
||||
#endif
|
||||
#if defined(__SSAT)
|
||||
#undef __SSAT
|
||||
#endif
|
||||
#if defined(__USAT)
|
||||
#undef __USAT
|
||||
#endif
|
||||
|
||||
#include "iccarm_builtin.h"
|
||||
|
||||
#define __enable_irq __iar_builtin_enable_interrupt
|
||||
#define __disable_irq __iar_builtin_disable_interrupt
|
||||
#define __enable_fault_irq __iar_builtin_enable_fiq
|
||||
#define __disable_fault_irq __iar_builtin_disable_fiq
|
||||
#define __arm_rsr __iar_builtin_rsr
|
||||
#define __arm_wsr __iar_builtin_wsr
|
||||
|
||||
#if __FPU_PRESENT
|
||||
#define __get_FPSCR() (__arm_rsr("FPSCR"))
|
||||
#else
|
||||
#define __get_FPSCR() ( 0 )
|
||||
#endif
|
||||
|
||||
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", VALUE))
|
||||
|
||||
#define __get_CPSR() (__arm_rsr("CPSR"))
|
||||
#define __get_mode() (__get_CPSR() & 0x1FU)
|
||||
|
||||
#define __set_CPSR(VALUE) (__arm_wsr("CPSR", (VALUE)))
|
||||
#define __set_mode(VALUE) (__arm_wsr("CPSR_c", (VALUE)))
|
||||
|
||||
|
||||
#define __get_FPEXC() (__arm_rsr("FPEXC"))
|
||||
#define __set_FPEXC(VALUE) (__arm_wsr("FPEXC", VALUE))
|
||||
|
||||
#define __get_CP(cp, op1, RT, CRn, CRm, op2) \
|
||||
((RT) = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2))
|
||||
|
||||
#define __set_CP(cp, op1, RT, CRn, CRm, op2) \
|
||||
(__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, (RT)))
|
||||
|
||||
#define __get_CP64(cp, op1, Rt, CRm) \
|
||||
__ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
|
||||
|
||||
#define __set_CP64(cp, op1, Rt, CRm) \
|
||||
__ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
|
||||
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
#define __NOP __iar_builtin_no_operation
|
||||
|
||||
#define __CLZ __iar_builtin_CLZ
|
||||
#define __CLREX __iar_builtin_CLREX
|
||||
|
||||
#define __DMB __iar_builtin_DMB
|
||||
#define __DSB __iar_builtin_DSB
|
||||
#define __ISB __iar_builtin_ISB
|
||||
|
||||
#define __LDREXB __iar_builtin_LDREXB
|
||||
#define __LDREXH __iar_builtin_LDREXH
|
||||
#define __LDREXW __iar_builtin_LDREX
|
||||
|
||||
#define __RBIT __iar_builtin_RBIT
|
||||
#define __REV __iar_builtin_REV
|
||||
#define __REV16 __iar_builtin_REV16
|
||||
|
||||
__IAR_FT int16_t __REVSH(int16_t val)
|
||||
{
|
||||
return (int16_t) __iar_builtin_REVSH(val);
|
||||
}
|
||||
|
||||
#define __ROR __iar_builtin_ROR
|
||||
#define __RRX __iar_builtin_RRX
|
||||
|
||||
#define __SEV __iar_builtin_SEV
|
||||
|
||||
#define __SSAT __iar_builtin_SSAT
|
||||
|
||||
#define __STREXB __iar_builtin_STREXB
|
||||
#define __STREXH __iar_builtin_STREXH
|
||||
#define __STREXW __iar_builtin_STREX
|
||||
|
||||
#define __USAT __iar_builtin_USAT
|
||||
|
||||
#define __WFE __iar_builtin_WFE
|
||||
#define __WFI __iar_builtin_WFI
|
||||
|
||||
#define __SADD8 __iar_builtin_SADD8
|
||||
#define __QADD8 __iar_builtin_QADD8
|
||||
#define __SHADD8 __iar_builtin_SHADD8
|
||||
#define __UADD8 __iar_builtin_UADD8
|
||||
#define __UQADD8 __iar_builtin_UQADD8
|
||||
#define __UHADD8 __iar_builtin_UHADD8
|
||||
#define __SSUB8 __iar_builtin_SSUB8
|
||||
#define __QSUB8 __iar_builtin_QSUB8
|
||||
#define __SHSUB8 __iar_builtin_SHSUB8
|
||||
#define __USUB8 __iar_builtin_USUB8
|
||||
#define __UQSUB8 __iar_builtin_UQSUB8
|
||||
#define __UHSUB8 __iar_builtin_UHSUB8
|
||||
#define __SADD16 __iar_builtin_SADD16
|
||||
#define __QADD16 __iar_builtin_QADD16
|
||||
#define __SHADD16 __iar_builtin_SHADD16
|
||||
#define __UADD16 __iar_builtin_UADD16
|
||||
#define __UQADD16 __iar_builtin_UQADD16
|
||||
#define __UHADD16 __iar_builtin_UHADD16
|
||||
#define __SSUB16 __iar_builtin_SSUB16
|
||||
#define __QSUB16 __iar_builtin_QSUB16
|
||||
#define __SHSUB16 __iar_builtin_SHSUB16
|
||||
#define __USUB16 __iar_builtin_USUB16
|
||||
#define __UQSUB16 __iar_builtin_UQSUB16
|
||||
#define __UHSUB16 __iar_builtin_UHSUB16
|
||||
#define __SASX __iar_builtin_SASX
|
||||
#define __QASX __iar_builtin_QASX
|
||||
#define __SHASX __iar_builtin_SHASX
|
||||
#define __UASX __iar_builtin_UASX
|
||||
#define __UQASX __iar_builtin_UQASX
|
||||
#define __UHASX __iar_builtin_UHASX
|
||||
#define __SSAX __iar_builtin_SSAX
|
||||
#define __QSAX __iar_builtin_QSAX
|
||||
#define __SHSAX __iar_builtin_SHSAX
|
||||
#define __USAX __iar_builtin_USAX
|
||||
#define __UQSAX __iar_builtin_UQSAX
|
||||
#define __UHSAX __iar_builtin_UHSAX
|
||||
#define __USAD8 __iar_builtin_USAD8
|
||||
#define __USADA8 __iar_builtin_USADA8
|
||||
#define __SSAT16 __iar_builtin_SSAT16
|
||||
#define __USAT16 __iar_builtin_USAT16
|
||||
#define __UXTB16 __iar_builtin_UXTB16
|
||||
#define __UXTAB16 __iar_builtin_UXTAB16
|
||||
#define __SXTB16 __iar_builtin_SXTB16
|
||||
#define __SXTAB16 __iar_builtin_SXTAB16
|
||||
#define __SMUAD __iar_builtin_SMUAD
|
||||
#define __SMUADX __iar_builtin_SMUADX
|
||||
#define __SMMLA __iar_builtin_SMMLA
|
||||
#define __SMLAD __iar_builtin_SMLAD
|
||||
#define __SMLADX __iar_builtin_SMLADX
|
||||
#define __SMLALD __iar_builtin_SMLALD
|
||||
#define __SMLALDX __iar_builtin_SMLALDX
|
||||
#define __SMUSD __iar_builtin_SMUSD
|
||||
#define __SMUSDX __iar_builtin_SMUSDX
|
||||
#define __SMLSD __iar_builtin_SMLSD
|
||||
#define __SMLSDX __iar_builtin_SMLSDX
|
||||
#define __SMLSLD __iar_builtin_SMLSLD
|
||||
#define __SMLSLDX __iar_builtin_SMLSLDX
|
||||
#define __SEL __iar_builtin_SEL
|
||||
#define __QADD __iar_builtin_QADD
|
||||
#define __QSUB __iar_builtin_QSUB
|
||||
#define __PKHBT __iar_builtin_PKHBT
|
||||
#define __PKHTB __iar_builtin_PKHTB
|
||||
|
||||
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#if !__FPU_PRESENT
|
||||
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
|
||||
#endif
|
||||
|
||||
#ifdef __INTRINSICS_INCLUDED
|
||||
#error intrinsics.h is already included previously!
|
||||
#endif
|
||||
|
||||
#include <intrinsics.h>
|
||||
|
||||
#if !__FPU_PRESENT
|
||||
#define __get_FPSCR() (0)
|
||||
#endif
|
||||
|
||||
#pragma diag_suppress=Pe940
|
||||
#pragma diag_suppress=Pe177
|
||||
|
||||
#define __enable_irq __enable_interrupt
|
||||
#define __disable_irq __disable_interrupt
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
#define __NOP __no_operation
|
||||
|
||||
#define __get_xPSR __get_PSR
|
||||
|
||||
__IAR_FT void __set_mode(uint32_t mode)
|
||||
{
|
||||
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr)
|
||||
{
|
||||
return __LDREX((unsigned long *)ptr);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr)
|
||||
{
|
||||
return __STREX(value, (unsigned long *)ptr);
|
||||
}
|
||||
|
||||
|
||||
__IAR_FT uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
uint32_t result;
|
||||
__ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory");
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
__IAR_FT void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) \
|
||||
__ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) \
|
||||
__ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
|
||||
#define __get_CP64(cp, op1, Rt, CRm) \
|
||||
__ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP64(cp, op1, Rt, CRm) \
|
||||
__ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" )
|
||||
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
|
||||
|
||||
|
||||
__IAR_FT uint32_t __get_SP_usr(void)
|
||||
{
|
||||
uint32_t cpsr;
|
||||
uint32_t result;
|
||||
__ASM volatile(
|
||||
"MRS %0, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV %1, sp \n"
|
||||
"MSR cpsr_c, %2 \n" // no effect in USR mode
|
||||
"ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory"
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
__IAR_FT void __set_SP_usr(uint32_t topOfProcStack)
|
||||
{
|
||||
uint32_t cpsr;
|
||||
__ASM volatile(
|
||||
"MRS %0, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV sp, %1 \n"
|
||||
"MSR cpsr_c, %2 \n" // no effect in USR mode
|
||||
"ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#define __get_mode() (__get_CPSR() & 0x1FU)
|
||||
|
||||
__STATIC_INLINE
|
||||
void __FPU_Enable(void)
|
||||
{
|
||||
__ASM volatile(
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
" MRC p15,0,R1,c1,c0,2 \n"
|
||||
" ORR R1,R1,#0x00F00000 \n"
|
||||
" MCR p15,0,R1,c1,c0,2 \n"
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
" ISB \n"
|
||||
|
||||
//Enable VFP/NEON
|
||||
" VMRS R1,FPEXC \n"
|
||||
" ORR R1,R1,#0x40000000 \n"
|
||||
" VMSR FPEXC,R1 \n"
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
" MOV R2,#0 \n"
|
||||
|
||||
//Initialise D16 registers to 0
|
||||
" VMOV D0, R2,R2 \n"
|
||||
" VMOV D1, R2,R2 \n"
|
||||
" VMOV D2, R2,R2 \n"
|
||||
" VMOV D3, R2,R2 \n"
|
||||
" VMOV D4, R2,R2 \n"
|
||||
" VMOV D5, R2,R2 \n"
|
||||
" VMOV D6, R2,R2 \n"
|
||||
" VMOV D7, R2,R2 \n"
|
||||
" VMOV D8, R2,R2 \n"
|
||||
" VMOV D9, R2,R2 \n"
|
||||
" VMOV D10,R2,R2 \n"
|
||||
" VMOV D11,R2,R2 \n"
|
||||
" VMOV D12,R2,R2 \n"
|
||||
" VMOV D13,R2,R2 \n"
|
||||
" VMOV D14,R2,R2 \n"
|
||||
" VMOV D15,R2,R2 \n"
|
||||
|
||||
#ifdef __ARM_ADVANCED_SIMD__
|
||||
//Initialise D32 registers to 0
|
||||
" VMOV D16,R2,R2 \n"
|
||||
" VMOV D17,R2,R2 \n"
|
||||
" VMOV D18,R2,R2 \n"
|
||||
" VMOV D19,R2,R2 \n"
|
||||
" VMOV D20,R2,R2 \n"
|
||||
" VMOV D21,R2,R2 \n"
|
||||
" VMOV D22,R2,R2 \n"
|
||||
" VMOV D23,R2,R2 \n"
|
||||
" VMOV D24,R2,R2 \n"
|
||||
" VMOV D25,R2,R2 \n"
|
||||
" VMOV D26,R2,R2 \n"
|
||||
" VMOV D27,R2,R2 \n"
|
||||
" VMOV D28,R2,R2 \n"
|
||||
" VMOV D29,R2,R2 \n"
|
||||
" VMOV D30,R2,R2 \n"
|
||||
" VMOV D31,R2,R2 \n"
|
||||
#endif
|
||||
|
||||
//Initialise FPSCR to a known state
|
||||
" VMRS R2,FPSCR \n"
|
||||
" MOV32 R3,#0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
" AND R2,R2,R3 \n"
|
||||
" VMSR FPSCR,R2 \n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#undef __IAR_FT
|
||||
#undef __ICCARM_V8
|
||||
|
||||
#pragma diag_default=Pe940
|
||||
#pragma diag_default=Pe177
|
||||
|
||||
#endif /* __CMSIS_ICCARM_H__ */
|
2614
STM32F103_Example/Drivers/CMSIS/Core_A/Include/core_ca.h
Normal file
2614
STM32F103_Example/Drivers/CMSIS/Core_A/Include/core_ca.h
Normal file
File diff suppressed because it is too large
Load Diff
186
STM32F103_Example/Drivers/CMSIS/Core_A/Include/irq_ctrl.h
Normal file
186
STM32F103_Example/Drivers/CMSIS/Core_A/Include/irq_ctrl.h
Normal file
@ -0,0 +1,186 @@
|
||||
/**************************************************************************//**
|
||||
* @file irq_ctrl.h
|
||||
* @brief Interrupt Controller API header file
|
||||
* @version V1.0.0
|
||||
* @date 23. June 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__clang__)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef IRQ_CTRL_H_
|
||||
#define IRQ_CTRL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef IRQHANDLER_T
|
||||
#define IRQHANDLER_T
|
||||
/// Interrupt handler data type
|
||||
typedef void (*IRQHandler_t) (void);
|
||||
#endif
|
||||
|
||||
#ifndef IRQN_ID_T
|
||||
#define IRQN_ID_T
|
||||
/// Interrupt ID number data type
|
||||
typedef int32_t IRQn_ID_t;
|
||||
#endif
|
||||
|
||||
/* Interrupt mode bit-masks */
|
||||
#define IRQ_MODE_TRIG_Pos (0U)
|
||||
#define IRQ_MODE_TRIG_Msk (0x07UL /*<< IRQ_MODE_TRIG_Pos*/)
|
||||
#define IRQ_MODE_TRIG_LEVEL (0x00UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: level triggered interrupt
|
||||
#define IRQ_MODE_TRIG_LEVEL_LOW (0x01UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: low level triggered interrupt
|
||||
#define IRQ_MODE_TRIG_LEVEL_HIGH (0x02UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: high level triggered interrupt
|
||||
#define IRQ_MODE_TRIG_EDGE (0x04UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: edge triggered interrupt
|
||||
#define IRQ_MODE_TRIG_EDGE_RISING (0x05UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising edge triggered interrupt
|
||||
#define IRQ_MODE_TRIG_EDGE_FALLING (0x06UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: falling edge triggered interrupt
|
||||
#define IRQ_MODE_TRIG_EDGE_BOTH (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising and falling edge triggered interrupt
|
||||
|
||||
#define IRQ_MODE_TYPE_Pos (3U)
|
||||
#define IRQ_MODE_TYPE_Msk (0x01UL << IRQ_MODE_TYPE_Pos)
|
||||
#define IRQ_MODE_TYPE_IRQ (0x00UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU IRQ line
|
||||
#define IRQ_MODE_TYPE_FIQ (0x01UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU FIQ line
|
||||
|
||||
#define IRQ_MODE_DOMAIN_Pos (4U)
|
||||
#define IRQ_MODE_DOMAIN_Msk (0x01UL << IRQ_MODE_DOMAIN_Pos)
|
||||
#define IRQ_MODE_DOMAIN_NONSECURE (0x00UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting non-secure domain
|
||||
#define IRQ_MODE_DOMAIN_SECURE (0x01UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting secure domain
|
||||
|
||||
#define IRQ_MODE_CPU_Pos (5U)
|
||||
#define IRQ_MODE_CPU_Msk (0xFFUL << IRQ_MODE_CPU_Pos)
|
||||
#define IRQ_MODE_CPU_ALL (0x00UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets all CPUs
|
||||
#define IRQ_MODE_CPU_0 (0x01UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 0
|
||||
#define IRQ_MODE_CPU_1 (0x02UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 1
|
||||
#define IRQ_MODE_CPU_2 (0x04UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 2
|
||||
#define IRQ_MODE_CPU_3 (0x08UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 3
|
||||
#define IRQ_MODE_CPU_4 (0x10UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 4
|
||||
#define IRQ_MODE_CPU_5 (0x20UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 5
|
||||
#define IRQ_MODE_CPU_6 (0x40UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 6
|
||||
#define IRQ_MODE_CPU_7 (0x80UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 7
|
||||
|
||||
#define IRQ_MODE_ERROR (0x80000000UL) ///< Bit indicating mode value error
|
||||
|
||||
/* Interrupt priority bit-masks */
|
||||
#define IRQ_PRIORITY_Msk (0x0000FFFFUL) ///< Interrupt priority value bit-mask
|
||||
#define IRQ_PRIORITY_ERROR (0x80000000UL) ///< Bit indicating priority value error
|
||||
|
||||
/// Initialize interrupt controller.
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_Initialize (void);
|
||||
|
||||
/// Register interrupt handler.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \param[in] handler interrupt handler function address
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler);
|
||||
|
||||
/// Get the registered interrupt handler.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return registered interrupt handler function address.
|
||||
IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn);
|
||||
|
||||
/// Enable interrupt.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_Enable (IRQn_ID_t irqn);
|
||||
|
||||
/// Disable interrupt.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_Disable (IRQn_ID_t irqn);
|
||||
|
||||
/// Get interrupt enable state.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 - interrupt is disabled, 1 - interrupt is enabled.
|
||||
uint32_t IRQ_GetEnableState (IRQn_ID_t irqn);
|
||||
|
||||
/// Configure interrupt request mode.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \param[in] mode mode configuration
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode);
|
||||
|
||||
/// Get interrupt mode configuration.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return current interrupt mode configuration with optional IRQ_MODE_ERROR bit set.
|
||||
uint32_t IRQ_GetMode (IRQn_ID_t irqn);
|
||||
|
||||
/// Get ID number of current interrupt request (IRQ).
|
||||
/// \return interrupt ID number.
|
||||
IRQn_ID_t IRQ_GetActiveIRQ (void);
|
||||
|
||||
/// Get ID number of current fast interrupt request (FIQ).
|
||||
/// \return interrupt ID number.
|
||||
IRQn_ID_t IRQ_GetActiveFIQ (void);
|
||||
|
||||
/// Signal end of interrupt processing.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn);
|
||||
|
||||
/// Set interrupt pending flag.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetPending (IRQn_ID_t irqn);
|
||||
|
||||
/// Get interrupt pending flag.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 - interrupt is not pending, 1 - interrupt is pending.
|
||||
uint32_t IRQ_GetPending (IRQn_ID_t irqn);
|
||||
|
||||
/// Clear interrupt pending flag.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_ClearPending (IRQn_ID_t irqn);
|
||||
|
||||
/// Set interrupt priority value.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \param[in] priority interrupt priority value
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority);
|
||||
|
||||
/// Get interrupt priority.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return current interrupt priority value with optional IRQ_PRIORITY_ERROR bit set.
|
||||
uint32_t IRQ_GetPriority (IRQn_ID_t irqn);
|
||||
|
||||
/// Set priority masking threshold.
|
||||
/// \param[in] priority priority masking threshold value
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetPriorityMask (uint32_t priority);
|
||||
|
||||
/// Get priority masking threshold
|
||||
/// \return current priority masking threshold value with optional IRQ_PRIORITY_ERROR bit set.
|
||||
uint32_t IRQ_GetPriorityMask (void);
|
||||
|
||||
/// Set priority grouping field split point
|
||||
/// \param[in] bits number of MSB bits included in the group priority field comparison
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetPriorityGroupBits (uint32_t bits);
|
||||
|
||||
/// Get priority grouping field split point
|
||||
/// \return current number of MSB bits included in the group priority field comparison with
|
||||
/// optional IRQ_PRIORITY_ERROR bit set.
|
||||
uint32_t IRQ_GetPriorityGroupBits (void);
|
||||
|
||||
#endif // IRQ_CTRL_H_
|
410
STM32F103_Example/Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c
Normal file
410
STM32F103_Example/Drivers/CMSIS/Core_A/Source/irq_ctrl_gic.c
Normal file
@ -0,0 +1,410 @@
|
||||
/**************************************************************************//**
|
||||
* @file irq_ctrl_gic.c
|
||||
* @brief Interrupt controller handling implementation for GIC
|
||||
* @version V1.0.1
|
||||
* @date 9. April 2018
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "RTE_Components.h"
|
||||
#include CMSIS_device_header
|
||||
|
||||
#include "irq_ctrl.h"
|
||||
|
||||
#if defined(__GIC_PRESENT) && (__GIC_PRESENT == 1U)
|
||||
|
||||
/// Number of implemented interrupt lines
|
||||
#ifndef IRQ_GIC_LINE_COUNT
|
||||
#define IRQ_GIC_LINE_COUNT (1020U)
|
||||
#endif
|
||||
|
||||
static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U };
|
||||
static uint32_t IRQ_ID0;
|
||||
|
||||
/// Initialize interrupt controller.
|
||||
__WEAK int32_t IRQ_Initialize (void) {
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) {
|
||||
IRQTable[i] = (IRQHandler_t)NULL;
|
||||
}
|
||||
GIC_Enable();
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/// Register interrupt handler.
|
||||
__WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
IRQTable[irqn] = handler;
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get the registered interrupt handler.
|
||||
__WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) {
|
||||
IRQHandler_t h;
|
||||
|
||||
// Ignore CPUID field (software generated interrupts)
|
||||
irqn &= 0x3FFU;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
h = IRQTable[irqn];
|
||||
} else {
|
||||
h = (IRQHandler_t)0;
|
||||
}
|
||||
|
||||
return (h);
|
||||
}
|
||||
|
||||
|
||||
/// Enable interrupt.
|
||||
__WEAK int32_t IRQ_Enable (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_EnableIRQ ((IRQn_Type)irqn);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Disable interrupt.
|
||||
__WEAK int32_t IRQ_Disable (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_DisableIRQ ((IRQn_Type)irqn);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get interrupt enable state.
|
||||
__WEAK uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) {
|
||||
uint32_t enable;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
enable = GIC_GetEnableIRQ((IRQn_Type)irqn);
|
||||
} else {
|
||||
enable = 0U;
|
||||
}
|
||||
|
||||
return (enable);
|
||||
}
|
||||
|
||||
|
||||
/// Configure interrupt request mode.
|
||||
__WEAK int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) {
|
||||
uint32_t val;
|
||||
uint8_t cfg;
|
||||
uint8_t secure;
|
||||
uint8_t cpu;
|
||||
int32_t status = 0;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
// Check triggering mode
|
||||
val = (mode & IRQ_MODE_TRIG_Msk);
|
||||
|
||||
if (val == IRQ_MODE_TRIG_LEVEL) {
|
||||
cfg = 0x00U;
|
||||
} else if (val == IRQ_MODE_TRIG_EDGE) {
|
||||
cfg = 0x02U;
|
||||
} else {
|
||||
cfg = 0x00U;
|
||||
status = -1;
|
||||
}
|
||||
|
||||
// Check interrupt type
|
||||
val = mode & IRQ_MODE_TYPE_Msk;
|
||||
|
||||
if (val != IRQ_MODE_TYPE_IRQ) {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
// Check interrupt domain
|
||||
val = mode & IRQ_MODE_DOMAIN_Msk;
|
||||
|
||||
if (val == IRQ_MODE_DOMAIN_NONSECURE) {
|
||||
secure = 0U;
|
||||
} else {
|
||||
// Check security extensions support
|
||||
val = GIC_DistributorInfo() & (1UL << 10U);
|
||||
|
||||
if (val != 0U) {
|
||||
// Security extensions are supported
|
||||
secure = 1U;
|
||||
} else {
|
||||
secure = 0U;
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Check interrupt CPU targets
|
||||
val = mode & IRQ_MODE_CPU_Msk;
|
||||
|
||||
if (val == IRQ_MODE_CPU_ALL) {
|
||||
cpu = 0xFFU;
|
||||
} else {
|
||||
cpu = val >> IRQ_MODE_CPU_Pos;
|
||||
}
|
||||
|
||||
// Apply configuration if no mode error
|
||||
if (status == 0) {
|
||||
GIC_SetConfiguration((IRQn_Type)irqn, cfg);
|
||||
GIC_SetTarget ((IRQn_Type)irqn, cpu);
|
||||
|
||||
if (secure != 0U) {
|
||||
GIC_SetGroup ((IRQn_Type)irqn, secure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get interrupt mode configuration.
|
||||
__WEAK uint32_t IRQ_GetMode (IRQn_ID_t irqn) {
|
||||
uint32_t mode;
|
||||
uint32_t val;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
mode = IRQ_MODE_TYPE_IRQ;
|
||||
|
||||
// Get trigger mode
|
||||
val = GIC_GetConfiguration((IRQn_Type)irqn);
|
||||
|
||||
if ((val & 2U) != 0U) {
|
||||
// Corresponding interrupt is edge triggered
|
||||
mode |= IRQ_MODE_TRIG_EDGE;
|
||||
} else {
|
||||
// Corresponding interrupt is level triggered
|
||||
mode |= IRQ_MODE_TRIG_LEVEL;
|
||||
}
|
||||
|
||||
// Get interrupt CPU targets
|
||||
mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos;
|
||||
|
||||
} else {
|
||||
mode = IRQ_MODE_ERROR;
|
||||
}
|
||||
|
||||
return (mode);
|
||||
}
|
||||
|
||||
|
||||
/// Get ID number of current interrupt request (IRQ).
|
||||
__WEAK IRQn_ID_t IRQ_GetActiveIRQ (void) {
|
||||
IRQn_ID_t irqn;
|
||||
uint32_t prio;
|
||||
|
||||
/* Dummy read to avoid GIC 390 errata 801120 */
|
||||
GIC_GetHighPendingIRQ();
|
||||
|
||||
irqn = GIC_AcknowledgePending();
|
||||
|
||||
__DSB();
|
||||
|
||||
/* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014) */
|
||||
/* The following workaround code is for a single-core system. It would be */
|
||||
/* different in a multi-core system. */
|
||||
/* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */
|
||||
/* so unlock it, otherwise service the interrupt as normal. */
|
||||
/* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 */
|
||||
/* so will not occur here. */
|
||||
|
||||
if ((irqn == 0) || (irqn >= 0x3FE)) {
|
||||
/* Unlock the CPU interface with a dummy write to Interrupt Priority Register */
|
||||
prio = GIC_GetPriority((IRQn_Type)0);
|
||||
GIC_SetPriority ((IRQn_Type)0, prio);
|
||||
|
||||
__DSB();
|
||||
|
||||
if ((irqn == 0U) && ((GIC_GetIRQStatus ((IRQn_Type)irqn) & 1U) != 0U) && (IRQ_ID0 == 0U)) {
|
||||
/* If the ID is 0, is active and has not been seen before */
|
||||
IRQ_ID0 = 1U;
|
||||
}
|
||||
/* End of Workaround GIC 390 errata 733075 */
|
||||
}
|
||||
|
||||
return (irqn);
|
||||
}
|
||||
|
||||
|
||||
/// Get ID number of current fast interrupt request (FIQ).
|
||||
__WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) {
|
||||
return ((IRQn_ID_t)-1);
|
||||
}
|
||||
|
||||
|
||||
/// Signal end of interrupt processing.
|
||||
__WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
IRQn_Type irq = (IRQn_Type)irqn;
|
||||
|
||||
irqn &= 0x3FFU;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_EndInterrupt (irq);
|
||||
|
||||
if (irqn == 0) {
|
||||
IRQ_ID0 = 0U;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Set interrupt pending flag.
|
||||
__WEAK int32_t IRQ_SetPending (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_SetPendingIRQ ((IRQn_Type)irqn);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/// Get interrupt pending flag.
|
||||
__WEAK uint32_t IRQ_GetPending (IRQn_ID_t irqn) {
|
||||
uint32_t pending;
|
||||
|
||||
if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
pending = GIC_GetPendingIRQ ((IRQn_Type)irqn);
|
||||
} else {
|
||||
pending = 0U;
|
||||
}
|
||||
|
||||
return (pending & 1U);
|
||||
}
|
||||
|
||||
|
||||
/// Clear interrupt pending flag.
|
||||
__WEAK int32_t IRQ_ClearPending (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_ClearPendingIRQ ((IRQn_Type)irqn);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Set interrupt priority value.
|
||||
__WEAK int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_SetPriority ((IRQn_Type)irqn, priority);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get interrupt priority.
|
||||
__WEAK uint32_t IRQ_GetPriority (IRQn_ID_t irqn) {
|
||||
uint32_t priority;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
priority = GIC_GetPriority ((IRQn_Type)irqn);
|
||||
} else {
|
||||
priority = IRQ_PRIORITY_ERROR;
|
||||
}
|
||||
|
||||
return (priority);
|
||||
}
|
||||
|
||||
|
||||
/// Set priority masking threshold.
|
||||
__WEAK int32_t IRQ_SetPriorityMask (uint32_t priority) {
|
||||
GIC_SetInterfacePriorityMask (priority);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/// Get priority masking threshold
|
||||
__WEAK uint32_t IRQ_GetPriorityMask (void) {
|
||||
return GIC_GetInterfacePriorityMask();
|
||||
}
|
||||
|
||||
|
||||
/// Set priority grouping field split point
|
||||
__WEAK int32_t IRQ_SetPriorityGroupBits (uint32_t bits) {
|
||||
int32_t status;
|
||||
|
||||
if (bits == IRQ_PRIORITY_Msk) {
|
||||
bits = 7U;
|
||||
}
|
||||
|
||||
if (bits < 8U) {
|
||||
GIC_SetBinaryPoint (7U - bits);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get priority grouping field split point
|
||||
__WEAK uint32_t IRQ_GetPriorityGroupBits (void) {
|
||||
uint32_t bp;
|
||||
|
||||
bp = GIC_GetBinaryPoint() & 0x07U;
|
||||
|
||||
return (7U - bp);
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,220 @@
|
||||
#ifndef _ARR_DESC_H_
|
||||
#define _ARR_DESC_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <string.h> /* memset() */
|
||||
#include "../util/util.h" /* CONCAT() */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Array-descriptor struct.
|
||||
*/
|
||||
typedef struct ARR_DESC_struct
|
||||
{
|
||||
void * data_ptr; /* Pointer to the array contents. */
|
||||
int32_t element_count; /* Number of current elements. */
|
||||
int32_t element_size; /* Size of current elements in bytes. */
|
||||
int32_t underlying_size; /* Size of underlying array in bytes. */
|
||||
} ARR_DESC_t;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Prefix of the array variable's name when creating an array and an array
|
||||
* descriptor at the same time.
|
||||
*/
|
||||
#define ARR_DESC_ARR_PREFIX ARR_DESC_ARR_
|
||||
|
||||
/**
|
||||
* Evaluate to the array variable's name when creating an array and an array
|
||||
* descriptor at the same time.
|
||||
*/
|
||||
#define ARR_DESC_ARR_NAME(name) \
|
||||
CONCAT(ARR_DESC_ARR_PREFIX, name)
|
||||
|
||||
/**
|
||||
* Define an #ARR_DESC_t by itself.
|
||||
*
|
||||
* @note The user must supply an array to store the data used by the
|
||||
* #ARR_DESC_t.
|
||||
*/
|
||||
#define ARR_DESC_INTERNAL_DEFINE(name, data_ptr, \
|
||||
element_count, element_size) \
|
||||
ARR_DESC_t name = { \
|
||||
data_ptr, \
|
||||
element_count, \
|
||||
element_size, \
|
||||
element_count * element_size \
|
||||
} \
|
||||
|
||||
/**
|
||||
* Define both an array and an #ARR_DESC_t that describes it.
|
||||
*
|
||||
* @note Use the #CURLY() macro for the content field; it provides the curly
|
||||
* braces necessary for an array initialization.
|
||||
*/
|
||||
#define ARR_DESC_DEFINE(type, name, element_count, content) \
|
||||
type ARR_DESC_ARR_NAME(name)[element_count] = content; \
|
||||
ARR_DESC_INTERNAL_DEFINE(name, \
|
||||
&ARR_DESC_ARR_NAME(name), \
|
||||
element_count, \
|
||||
sizeof(type)) /* Note the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Create a #ARR_DESC_t which refers to a subset of the data in another.
|
||||
*
|
||||
* The new #ARR_DESC_t shares the same underlying array as the aliased
|
||||
* #ARR_DESC_t, but only describes a subset of the originals values.
|
||||
*/
|
||||
#define ARR_DESC_DEFINE_SUBSET(name, original, element_cnt) \
|
||||
ARR_DESC_INTERNAL_DEFINE(name, \
|
||||
&ARR_DESC_ARR_NAME(original), \
|
||||
element_cnt, \
|
||||
sizeof(ARR_DESC_ARR_NAME(original)[0]) \
|
||||
) /* Note the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Creat an #ARR_DESC_t which points to the data in an existing array.
|
||||
*
|
||||
* @param start_idx Offset in array_ptr of first element.
|
||||
* @param element_cnt Number of elements to include in the #ARR_DESC_t.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* float my_floats[4] = {0.0f, 1.0f, 2.0f, 3.0f};
|
||||
*
|
||||
* ARR_DESC_DEFINE_USING_ARR(my_arr_desc, my_floats, 1, 3);
|
||||
*
|
||||
* printf("Element 0: %f\n", ARR_DESC_ELT(float, 0, &my_arr_desc));
|
||||
* printf("Element 1: %f\n", ARR_DESC_ELT(float, 1, &my_arr_desc));
|
||||
*
|
||||
* Outputs:
|
||||
*
|
||||
* Element 0: 1.000000
|
||||
* Element 1: 2.000000
|
||||
*
|
||||
* @warning There are no checks in place to catch invalid start indices; This
|
||||
* is left to the user.
|
||||
*/
|
||||
#define ARR_DESC_DEFINE_USING_ARR(type, name, array_ptr, start_idx, element_cnt) \
|
||||
ARR_DESC_INTERNAL_DEFINE( \
|
||||
name, \
|
||||
(type *) (array_ptr + start_idx), \
|
||||
element_cnt, \
|
||||
sizeof(type) \
|
||||
) /* Note the lacking semicolon*/
|
||||
|
||||
/**
|
||||
* Declare an #ARR_DESC_t object.
|
||||
*/
|
||||
#define ARR_DESC_DECLARE(name) \
|
||||
extern ARR_DESC_t name /* Note the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Evaluate to the number of bytes stored in the #ARR_DESC_t.
|
||||
*/
|
||||
#define ARR_DESC_BYTES(arr_desc_ptr) \
|
||||
((arr_desc_ptr)->element_count * (arr_desc_ptr)->element_size)
|
||||
|
||||
/**
|
||||
* Set the contents of #ARR_DESC_t to value.
|
||||
*/
|
||||
#define ARR_DESC_MEMSET(arr_desc_ptr, value, bytes) \
|
||||
do \
|
||||
{ \
|
||||
memset((arr_desc_ptr)->data_ptr, \
|
||||
value, \
|
||||
BOUND(0, \
|
||||
(arr_desc_ptr)->underlying_size, \
|
||||
bytes) \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Perform a memcpy of 'bytes' bytes from the source #ARR_DESC_t to the
|
||||
* destination #ARR_DESC_t.
|
||||
*/
|
||||
#define ARR_DESC_MEMCPY(arr_desc_dest_ptr, arr_desc_src_ptr, bytes) \
|
||||
do \
|
||||
{ \
|
||||
memcpy((arr_desc_dest_ptr)->data_ptr, \
|
||||
(arr_desc_src_ptr)->data_ptr, \
|
||||
BOUND(0, \
|
||||
(arr_desc_dest_ptr)->underlying_size, \
|
||||
bytes)); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Evaluate to true if the source #ARR_DESC_t contents will fit into the
|
||||
* destination #ARR_DESC_t and false otherwise.
|
||||
*/
|
||||
#define ARR_DESC_COPYABLE(arr_desc_dest_ptr, arr_desc_src_ptr) \
|
||||
(ARR_DESC_BYTES(arr_desc_src_ptr) <= \
|
||||
(arr_desc_dest_ptr)->underlying_size)
|
||||
|
||||
/**
|
||||
* Copy all the data from the source #ARR_DESC_t to the destination
|
||||
* #ARR_DESC_t.
|
||||
*
|
||||
* @note If the destination #ARR_DESC_t is too small to fit the source data the
|
||||
* copy is aborted and nothing happens.
|
||||
*/
|
||||
#define ARR_DESC_COPY(arr_desc_dest_ptr, arr_desc_src_ptr) \
|
||||
do \
|
||||
{ \
|
||||
if (ARR_DESC_COPYABLE(arr_desc_dest_ptr, \
|
||||
arr_desc_src_ptr)) \
|
||||
{ \
|
||||
ARR_DESC_MEMCPY(arr_desc_dest_ptr, \
|
||||
arr_desc_src_ptr, \
|
||||
ARR_DESC_BYTES(arr_desc_src_ptr)); \
|
||||
/* Update the properties*/ \
|
||||
(arr_desc_dest_ptr)->element_count = \
|
||||
(arr_desc_src_ptr)->element_count; \
|
||||
(arr_desc_dest_ptr)->element_size = \
|
||||
(arr_desc_src_ptr)->element_size; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Compare the data in two #ARR_DESC_t structs for the specified number of
|
||||
* bytes.
|
||||
*/
|
||||
#define ARR_DESC_MEMCMP(arr_desc_ptr_a, arr_desc_ptr_b, bytes) \
|
||||
memcmp((arr_desc_ptr_a)->data_ptr, \
|
||||
(arr_desc_ptr_b)->data_ptr, \
|
||||
bytes) /* Note the lacking semicolon */ \
|
||||
|
||||
/**
|
||||
* Zero out the contents of the #ARR_DESC_t.
|
||||
*/
|
||||
#define ARR_DESC_ZERO(arr_desc_ptr) \
|
||||
ARR_DESC_MEMSET(arr_desc_ptr, \
|
||||
0, \
|
||||
(arr_desc_ptr)->underlying_size)
|
||||
|
||||
/**
|
||||
* Evaluate to the data address in #ARR_DESC_t at offset.
|
||||
*/
|
||||
#define ARR_DESC_DATA_ADDR(type, arr_desc_ptr, offset) \
|
||||
((void*)(((type *) \
|
||||
((arr_desc_ptr)->data_ptr)) \
|
||||
+ offset))
|
||||
|
||||
/**
|
||||
* Evaluate to the element in #ARR_DESC_t with type at idx.
|
||||
*/
|
||||
#define ARR_DESC_ELT(type, idx, arr_desc_ptr) \
|
||||
(*((type *) ARR_DESC_DATA_ADDR(type, \
|
||||
arr_desc_ptr, \
|
||||
idx)))
|
||||
|
||||
#endif /* _ARR_DESC_H_ */
|
@ -0,0 +1,17 @@
|
||||
#ifndef _JTEST_H_
|
||||
#define _JTEST_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_fw.h"
|
||||
#include "jtest_test.h"
|
||||
#include "jtest_test_define.h"
|
||||
#include "jtest_test_call.h"
|
||||
#include "jtest_group.h"
|
||||
#include "jtest_group_define.h"
|
||||
#include "jtest_group_call.h"
|
||||
#include "jtest_cycle.h"
|
||||
|
||||
#endif /* _JTEST_H_ */
|
@ -0,0 +1,65 @@
|
||||
#ifndef _JTEST_CYCLE_H_
|
||||
#define _JTEST_CYCLE_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_fw.h" /* JTEST_DUMP_STRF() */
|
||||
#include "jtest_systick.h"
|
||||
#include "jtest_util.h" /* STR() */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Module Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
extern const char * JTEST_CYCLE_STRF;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Wrap the function call, fn_call, to count execution cycles and display the
|
||||
* results.
|
||||
*/
|
||||
/* skipp function name + param
|
||||
#define JTEST_COUNT_CYCLES(fn_call) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t __jtest_cycle_end_count; \
|
||||
\
|
||||
JTEST_SYSTICK_RESET(SysTick); \
|
||||
JTEST_SYSTICK_START(SysTick); \
|
||||
\
|
||||
fn_call; \
|
||||
\
|
||||
__jtest_cycle_end_count = \
|
||||
JTEST_SYSTICK_VALUE(SysTick); \
|
||||
\
|
||||
JTEST_SYSTICK_RESET(SysTick); \
|
||||
JTEST_DUMP_STRF(JTEST_CYCLE_STRF, \
|
||||
STR(fn_call), \
|
||||
(JTEST_SYSTICK_INITIAL_VALUE - \
|
||||
__jtest_cycle_end_count)); \
|
||||
} while (0)
|
||||
*/
|
||||
#define JTEST_COUNT_CYCLES(fn_call) \
|
||||
do \
|
||||
{ \
|
||||
uint32_t __jtest_cycle_end_count; \
|
||||
\
|
||||
JTEST_SYSTICK_RESET(SysTick); \
|
||||
JTEST_SYSTICK_START(SysTick); \
|
||||
\
|
||||
fn_call; \
|
||||
\
|
||||
__jtest_cycle_end_count = \
|
||||
JTEST_SYSTICK_VALUE(SysTick); \
|
||||
\
|
||||
JTEST_SYSTICK_RESET(SysTick); \
|
||||
JTEST_DUMP_STRF(JTEST_CYCLE_STRF, \
|
||||
(JTEST_SYSTICK_INITIAL_VALUE - \
|
||||
__jtest_cycle_end_count)); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_CYCLE_H_ */
|
@ -0,0 +1,37 @@
|
||||
#ifndef _JTEST_DEFINE_H_
|
||||
#define _JTEST_DEFINE_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Makes a symbol for use as a struct name. Names made this way have two parts;
|
||||
* the first parts is a prefix common to all structs of that class. The second
|
||||
* is a specifier which differs for each instance of that struct type.
|
||||
*/
|
||||
#define JTEST_STRUCT_NAME(prefix, specifier) \
|
||||
CONCAT(prefix, specifier)
|
||||
|
||||
/**
|
||||
* Define a struct with type with a name generated by #JTEST_STRUCT_NAME().
|
||||
*/
|
||||
#define JTEST_DEFINE_STRUCT(type, struct_name) \
|
||||
type struct_name
|
||||
|
||||
/**
|
||||
* Declare a struct with type with a name generated by #JTEST_STRUCT_NAME().
|
||||
*/
|
||||
#define JTEST_DECLARE_STRUCT(struct_definition) \
|
||||
extern struct_definition
|
||||
|
||||
/**
|
||||
* Define and initialize a struct (created with JTEST_DEFINE_STRUCT()) and
|
||||
* initialize it with init_values.
|
||||
*/
|
||||
#define JTEST_INIT_STRUCT(struct_definition, init_values) \
|
||||
struct_definition = { \
|
||||
init_values \
|
||||
}
|
||||
|
||||
#endif /* _JTEST_DEFINE_H_ */
|
@ -0,0 +1,253 @@
|
||||
#ifndef _JTEST_FW_H_
|
||||
#define _JTEST_FW_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h> /* int32_t */
|
||||
#include <string.h> /* strcpy() */
|
||||
#include <stdio.h> /* sprintf() */
|
||||
#include "jtest_pf.h" /* Extend JTEST_FW_t with Pass/Fail data */
|
||||
#include "jtest_group.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* A struct used to interface with the Keil Debugger.
|
||||
*/
|
||||
typedef struct JTEST_FW_struct
|
||||
{
|
||||
/* Action Triggers: The Keil debugger monitors these values for changes. In
|
||||
* response to a change, the debugger executes code on the host. */
|
||||
volatile int32_t test_start;
|
||||
volatile int32_t test_end;
|
||||
volatile int32_t group_start;
|
||||
volatile int32_t group_end;
|
||||
volatile int32_t dump_str;
|
||||
volatile int32_t dump_data;
|
||||
volatile int32_t exit_fw;
|
||||
|
||||
JTEST_GROUP_t * current_group_ptr;
|
||||
|
||||
/* Buffers: The C-code cannot send strings and data directly to the
|
||||
* debugging framework. Instead, the debugger can be told to read 128 byte
|
||||
* (by default) chunks of memory. Data received in this manner requires
|
||||
* post-processing to be legible.*/
|
||||
char * str_buffer;
|
||||
char * data_buffer;
|
||||
|
||||
/* Pass/Fail Data */
|
||||
JTEST_PF_MEMBERS;
|
||||
|
||||
} JTEST_FW_t;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Default name for the JTEST_FW struct.
|
||||
*
|
||||
* Define your own if you want the variable containing the #JTEST_FW_t to have
|
||||
* a different name.
|
||||
*/
|
||||
#ifndef JTEST_FW
|
||||
#define JTEST_FW JTEST_FW
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default name for the JTEST_FW_STR_BUFFER.
|
||||
*
|
||||
* Define your own if you want the variable containing the char buffer to have
|
||||
* a different name.
|
||||
*/
|
||||
#ifndef JTEST_FW_STR_BUFFER
|
||||
#define JTEST_FW_STR_BUFFER JTEST_FW_STR_BUFFER
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Size of the #JTEST_FW_t, output string-buffer.
|
||||
*
|
||||
* If you change this value, make sure the "dump_str_fn" and "dump_data_fn"
|
||||
* functions in jtest_fns.ini uses the same size. If you aren't sure, read the
|
||||
* documentation Keil Debugger Command 'DISPLAY'.
|
||||
*/
|
||||
#define JTEST_BUF_SIZE 256
|
||||
|
||||
|
||||
/**
|
||||
* The maximum number of bytes output at once using #JTEST_DUMP_STRF().
|
||||
*/
|
||||
#define JTEST_STR_MAX_OUTPUT_SIZE 128
|
||||
|
||||
/**
|
||||
* The maximum number of block transimissions needed to send a string from a
|
||||
* buffer with JTEST_BUF_SIZE.
|
||||
*/
|
||||
#define JTEST_STR_MAX_OUTPUT_SEGMENTS \
|
||||
(JTEST_BUF_SIZE / JTEST_STR_MAX_OUTPUT_SIZE)
|
||||
|
||||
/**
|
||||
* Initialize the JTEST framework.
|
||||
*/
|
||||
#define JTEST_INIT() \
|
||||
do \
|
||||
{ \
|
||||
JTEST_FW.str_buffer = JTEST_FW_STR_BUFFER; \
|
||||
} while (0)
|
||||
|
||||
/* Debugger Action-triggering Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Dispatch macro to trigger various actions in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_TRIGGER_ACTION(action_name) \
|
||||
do \
|
||||
{ \
|
||||
action_name(); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Trigger the "Test Start" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_TEST_START() \
|
||||
JTEST_TRIGGER_ACTION(test_start)
|
||||
|
||||
/**
|
||||
* Trigger the "Test End" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_TEST_END() \
|
||||
JTEST_TRIGGER_ACTION(test_end)
|
||||
|
||||
|
||||
/**
|
||||
* Trigger the "Group Start" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_GROUP_START() \
|
||||
JTEST_TRIGGER_ACTION(group_start)
|
||||
|
||||
/**
|
||||
* Trigger the "Group End" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_GROUP_END() \
|
||||
JTEST_TRIGGER_ACTION(group_end)
|
||||
|
||||
|
||||
/**
|
||||
* Fill the buffer named buf_name with value and dump it to the Keil debugger
|
||||
* using action.
|
||||
*/
|
||||
#define JTEST_ACT_DUMP(action, buf_name, value) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_CLEAR_BUFFER(buf_name); \
|
||||
strcpy(JTEST_FW.buf_name, (value)); \
|
||||
JTEST_TRIGGER_ACTION(action); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Trigger the "Exit Framework" action in the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_ACT_EXIT_FW() \
|
||||
do \
|
||||
{ \
|
||||
JTEST_TRIGGER_ACTION(exit_fw); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Buffer Manipulation Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Clear the JTEST_FW buffer with name buf_name.
|
||||
*/
|
||||
#define JTEST_CLEAR_BUFFER(buf_name) \
|
||||
do \
|
||||
{ \
|
||||
memset(JTEST_FW.buf_name, 0, JTEST_BUF_SIZE); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Clear the memory needed for the JTEST_FW's string buffer.
|
||||
*/
|
||||
#define JTEST_CLEAR_STR_BUFFER() \
|
||||
JTEST_CLEAR_BUFFER(str_buffer)
|
||||
|
||||
/**
|
||||
* Clear the memory needed for the JTEST_FW's data buffer.
|
||||
*/
|
||||
#define JTEST_CLEAR_DATA_BUFFER() \
|
||||
JTEST_CLEAR_BUFFER(data_buffer)
|
||||
|
||||
/**
|
||||
* Dump the given string to the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_DUMP_STR(string) \
|
||||
JTEST_ACT_DUMP(dump_str, str_buffer, string)
|
||||
|
||||
/**
|
||||
* Dump a formatted string to the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_DUMP_STRF(format_str, ... ) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_CLEAR_STR_BUFFER(); \
|
||||
sprintf(JTEST_FW.str_buffer,format_str, __VA_ARGS__); \
|
||||
jtest_dump_str_segments(); \
|
||||
} while (0)
|
||||
|
||||
/* Pass/Fail Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Increment the number of passed tests in #JTEST_FW.
|
||||
*/
|
||||
#define JTEST_FW_INC_PASSED(amount) \
|
||||
JTEST_PF_INC_PASSED(&JTEST_FW, amount)
|
||||
|
||||
/**
|
||||
* Increment the number of passed tests in #JTEST_FW.
|
||||
*/
|
||||
#define JTEST_FW_INC_FAILED(amount) \
|
||||
JTEST_PF_INC_FAILED(&JTEST_FW, amount)
|
||||
|
||||
/* Manipulating the Current Group */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Evaluate to the current_group_ptr in #JTEST_FW.
|
||||
*/
|
||||
#define JTEST_CURRENT_GROUP_PTR() \
|
||||
(JTEST_FW.current_group_ptr)
|
||||
|
||||
#define JTEST_SET_CURRENT_GROUP(group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_CURRENT_GROUP_PTR() = group_ptr; \
|
||||
} while (0)
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Global Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
extern char JTEST_FW_STR_BUFFER[JTEST_BUF_SIZE];
|
||||
extern volatile JTEST_FW_t JTEST_FW;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Function Prototypes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
void jtest_dump_str_segments(void);
|
||||
|
||||
void test_start (void);
|
||||
void test_end (void);
|
||||
void group_start (void);
|
||||
void group_end (void);
|
||||
void dump_str (void);
|
||||
void dump_data (void);
|
||||
void exit_fw (void);
|
||||
|
||||
|
||||
#endif /* _JTEST_FW_H_ */
|
@ -0,0 +1,66 @@
|
||||
#ifndef _JTEST_GROUP_H_
|
||||
#define _JTEST_GROUP_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_pf.h"
|
||||
#include "jtest_util.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* A struct which represents a group of #JTEST_TEST_t structs. This struct is
|
||||
* used to run the group of tests, and report on their outcomes.
|
||||
*/
|
||||
typedef struct JTEST_GROUP_struct
|
||||
{
|
||||
void (* group_fn_ptr) (void); /**< Pointer to the test group */
|
||||
char * name_str; /**< Name of the group */
|
||||
|
||||
/* Extend the #JTEST_GROUP_t with Pass/Fail information.*/
|
||||
JTEST_PF_MEMBERS;
|
||||
} JTEST_GROUP_t;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Set the name of JTEST_GROUP_t.
|
||||
*/
|
||||
#define JTEST_GROUP_SET_NAME(group_ptr, name) \
|
||||
JTEST_SET_STRUCT_ATTRIBUTE(group_ptr, name_str, name)
|
||||
|
||||
#define JTEST_GROUP_SET_FN(group_ptr, fn_ptr) \
|
||||
JTEST_SET_STRUCT_ATTRIBUTE(group_ptr, group_fn_ptr, fn_ptr)
|
||||
|
||||
/**
|
||||
* Increment the number of tests passed in the JTEST_GROUP_t pointed to by
|
||||
* group_ptr.
|
||||
*/
|
||||
#define JTEST_GROUP_INC_PASSED(group_ptr, amount) \
|
||||
JTEST_PF_INC_PASSED(group_ptr, amount)
|
||||
|
||||
/**
|
||||
* Increment the number of tests failed in the JTEST_GROUP_t pointed to by
|
||||
* group_ptr.
|
||||
*/
|
||||
#define JTEST_GROUP_INC_FAILED(group_ptr, amount) \
|
||||
JTEST_PF_INC_FAILED(group_ptr, amount)
|
||||
|
||||
/**
|
||||
* Reset the pass/fail information of the #JTEST_GROUP_t pointed to by
|
||||
* group_ptr.
|
||||
*/
|
||||
#define JTEST_GROUP_RESET_PF(group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_PF_RESET_PASSED(group_ptr); \
|
||||
JTEST_PF_RESET_FAILED(group_ptr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_GROUP_H_ */
|
@ -0,0 +1,126 @@
|
||||
#ifndef _JTEST_GROUP_CALL_H_
|
||||
#define _JTEST_GROUP_CALL_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_fw.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Execute the test in the #JTEST_GROUP_t struct associated witht he identifier
|
||||
* group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_RUN(group_fn) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_DUMP_STR("Group Name:\n"); \
|
||||
JTEST_DUMP_STR(JTEST_GROUP_STRUCT_NAME(group_fn).name_str); \
|
||||
JTEST_GROUP_STRUCT_NAME(group_fn).group_fn_ptr(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Update the enclosing #JTEST_GROUP_t's pass/fail information using the
|
||||
* current #JTEST_GROUP_t's.
|
||||
*
|
||||
* @param group_ptr Pointer to the current #JTEST_GROUP_t.
|
||||
* @param parent_ptr Pointer to the enclosing #JTEST_GROUP_t.
|
||||
*
|
||||
* @warning Only run this if the current #JTEST_GROUP_t is being called within
|
||||
* the context of another #JTEST_GROUP_t.
|
||||
*/
|
||||
#define JTEST_GROUP_UPDATE_PARENT_GROUP_PF(group_ptr, parent_group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_GROUP_INC_PASSED(parent_group_ptr, \
|
||||
(group_ptr)->passed); \
|
||||
JTEST_GROUP_INC_FAILED(parent_group_ptr, \
|
||||
(group_ptr)->failed); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the #JTEST_FW's pass/fail information using the current
|
||||
* #JTEST_GROUP_t's.
|
||||
*/
|
||||
#define JTEST_GROUP_UPDATE_FW_PF(group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_FW_INC_PASSED((group_ptr)->passed); \
|
||||
JTEST_FW_INC_FAILED((group_ptr)->failed); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the enclosing context with the current #JTEST_GROUP_t's pass/fail
|
||||
* information. If this group isn't in an enclosing group, it updates the
|
||||
* #JTEST_FW's pass/fail info by default.
|
||||
*/
|
||||
#define JTEST_GROUP_UPDATE_PARENT_GROUP_OR_FW_PF(group_ptr, \
|
||||
parent_group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
/* Update the pass fail counts in the parent group */ \
|
||||
if (parent_group_ptr /* Null implies Top*/) \
|
||||
{ \
|
||||
JTEST_GROUP_UPDATE_PARENT_GROUP_PF( \
|
||||
group_ptr, \
|
||||
parent_group_ptr); \
|
||||
} else { \
|
||||
JTEST_GROUP_UPDATE_FW_PF( \
|
||||
group_ptr); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Dump the results of running the #JTEST_GROUP_t to the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_GROUP_DUMP_RESULTS(group_ptr) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_DUMP_STRF( \
|
||||
"Tests Run: %" PRIu32 "\n" \
|
||||
"----------\n" \
|
||||
" Passed: %" PRIu32 "\n" \
|
||||
" Failed: %" PRIu32 "\n", \
|
||||
(group_ptr)->passed + (group_ptr)->failed, \
|
||||
(group_ptr)->passed, \
|
||||
(group_ptr)->failed); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Call the #JTEST_GROUP_t associated with the identifier group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_CALL(group_fn) \
|
||||
do \
|
||||
{ /* Save the current group from JTEST_FW_t before swapping */ \
|
||||
/* it to this group (in order to restore it later )*/ \
|
||||
JTEST_GROUP_t * __jtest_temp_group_ptr = \
|
||||
JTEST_CURRENT_GROUP_PTR(); \
|
||||
JTEST_SET_CURRENT_GROUP(&JTEST_GROUP_STRUCT_NAME(group_fn)); \
|
||||
\
|
||||
/* Reset this group's pass/fail count. Each group */ \
|
||||
/* should only remember counts for its last execution. */ \
|
||||
JTEST_GROUP_RESET_PF(JTEST_CURRENT_GROUP_PTR()); \
|
||||
\
|
||||
/* Run the current group */ \
|
||||
JTEST_ACT_GROUP_START(); \
|
||||
JTEST_GROUP_RUN(group_fn); \
|
||||
JTEST_ACT_GROUP_END(); \
|
||||
\
|
||||
/* Update the pass fail counts in the parent group (or FW) */ \
|
||||
JTEST_GROUP_UPDATE_PARENT_GROUP_OR_FW_PF( \
|
||||
JTEST_CURRENT_GROUP_PTR(), \
|
||||
__jtest_temp_group_ptr); \
|
||||
\
|
||||
JTEST_GROUP_DUMP_RESULTS(JTEST_CURRENT_GROUP_PTR()); \
|
||||
\
|
||||
/* Restore the previously current group */ \
|
||||
JTEST_SET_CURRENT_GROUP(__jtest_temp_group_ptr); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_GROUP_CALL_H_ */
|
@ -0,0 +1,87 @@
|
||||
#ifndef _JTEST_GROUP_DEFINE_H_
|
||||
#define _JTEST_GROUP_DEFINE_H_
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_util.h"
|
||||
#include "jtest_define.h"
|
||||
#include "jtest_group.h"
|
||||
|
||||
/* For defining macros with optional arguments */
|
||||
#include "opt_arg/opt_arg.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Prefix for all #JTEST_GROUP_t structs.
|
||||
*/
|
||||
#define JTEST_GROUP_STRUCT_NAME_PREFIX G_JTEST_GROUP_STRUCT_
|
||||
|
||||
/**
|
||||
* Define test template used by #JTEST_GROUP_t tests.
|
||||
*/
|
||||
#define JTEST_GROUP_FN_TEMPLATE(group_fn) \
|
||||
void group_fn(void)
|
||||
|
||||
#define JTEST_GROUP_FN_PROTOTYPE JTEST_GROUP_FN_TEMPLATE /**< Alias for
|
||||
#JTEST_GROUP_FN_TEMPLATE. */
|
||||
|
||||
/**
|
||||
* Evaluate to the name of the #JTEST_GROUP_t struct associated with group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_STRUCT_NAME(group_fn) \
|
||||
JTEST_STRUCT_NAME(JTEST_GROUP_STRUCT_NAME_PREFIX, group_fn)
|
||||
|
||||
/**
|
||||
* Define a #JTEST_GROUP_t struct based on the given group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_DEFINE_STRUCT(group_fn) \
|
||||
JTEST_DEFINE_STRUCT(JTEST_GROUP_t, \
|
||||
JTEST_GROUP_STRUCT_NAME(group_fn))
|
||||
|
||||
/**
|
||||
* Declare a #JTEST_GROUP_t struct based on the given group_fn.
|
||||
*/
|
||||
#define JTEST_GROUP_DECLARE_STRUCT(group_fn) \
|
||||
JTEST_DECLARE_STRUCT(JTEST_GROUP_DEFINE_STRUCT(group_fn))
|
||||
|
||||
/**
|
||||
* Contents needed to initialize a JTEST_GROUP_t struct.
|
||||
*/
|
||||
#define JTEST_GROUP_STRUCT_INIT(group_fn) \
|
||||
group_fn, \
|
||||
STR_NL(group_fn), \
|
||||
JTEST_PF_MEMBER_INIT
|
||||
|
||||
/**
|
||||
* Initialize the contents of a #JTEST_GROUP_t struct.
|
||||
*/
|
||||
#define JTEST_GROUP_INIT(group_fn) \
|
||||
JTEST_GROUP_DEFINE_STRUCT(group_fn) = { \
|
||||
JTEST_GROUP_STRUCT_INIT(group_fn) \
|
||||
}
|
||||
|
||||
/* Test Definition Macro */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Define a #JTEST_GROUP_t object and a test function.
|
||||
*/
|
||||
#define JTEST_DEFINE_GROUP(group_fn) \
|
||||
JTEST_GROUP_FN_PROTOTYPE(group_fn); \
|
||||
JTEST_GROUP_INIT(group_fn); \
|
||||
JTEST_GROUP_FN_PROTOTYPE(group_fn) /* Notice the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Declare a #JTEST_GROUP_t object and a test function prototype.
|
||||
*/
|
||||
#define JTEST_DECLARE_GROUP(group_fn) \
|
||||
JTEST_GROUP_FN_PROTOTYPE(group_fn); \
|
||||
JTEST_GROUP_DECLARE_STRUCT(group_fn) /* Note the lacking semicolon */
|
||||
|
||||
#endif /* _JTEST_GROUP_DEFINE_H_ */
|
@ -0,0 +1,85 @@
|
||||
#ifndef _JTEST_PF_H_
|
||||
#define _JTEST_PF_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Purpose */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* jtest_pf.h Contains macros useful for capturing pass/fail data. */
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Members that can be added to other structs to extend them pass/fail data and
|
||||
* corresponding functionality.
|
||||
*/
|
||||
#define JTEST_PF_MEMBERS \
|
||||
uint32_t passed; \
|
||||
uint32_t failed /* Note the lacking semicolon*/ \
|
||||
|
||||
/**
|
||||
* Used for initializing JTEST_PF_MEMBERS in a struct declaration.
|
||||
*/
|
||||
#define JTEST_PF_MEMBER_INIT \
|
||||
0, \
|
||||
0
|
||||
|
||||
/* Member-Incrementing Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Dispatch macro for incrementing #JTEST_PF_MEMBERS.
|
||||
*
|
||||
* @param xxx Values: 'passed', 'failed'
|
||||
*/
|
||||
#define JTEST_PF_INC_XXX(xxx, struct_pf_ptr, amount) \
|
||||
do \
|
||||
{ \
|
||||
((struct_pf_ptr)->xxx) += (amount); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Specialization of the #JTEST_PF_INC_XXX macro to increment the passed
|
||||
* member.
|
||||
*/
|
||||
#define JTEST_PF_INC_PASSED(struct_pf_ptr, amount) \
|
||||
JTEST_PF_INC_XXX(passed, struct_pf_ptr, amount)
|
||||
|
||||
|
||||
/**
|
||||
* Specialization of the #JTEST_PF_INC_XXX macro to increment the failed
|
||||
* member.
|
||||
*/
|
||||
#define JTEST_PF_INC_FAILED(struct_pf_ptr, amount) \
|
||||
JTEST_PF_INC_XXX(failed, struct_pf_ptr, amount)
|
||||
|
||||
|
||||
/* Member-Resetting Macros */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Dispatch macro for setting #JTEST_PF_MEMBERS to zero.
|
||||
*
|
||||
* @param xxx Values: 'passed', 'failed'
|
||||
*/
|
||||
#define JTEST_PF_RESET_XXX(xxx, struct_pf_ptr) \
|
||||
do \
|
||||
{ \
|
||||
((struct_pf_ptr)->xxx) = UINT32_C(0); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Specialization of #JTEST_PF_RESET_XXX for the 'passed' member.
|
||||
*/
|
||||
#define JTEST_PF_RESET_PASSED(struct_pf_ptr) \
|
||||
JTEST_PF_RESET_XXX(passed, struct_pf_ptr)
|
||||
|
||||
/**
|
||||
* Specialization of #JTEST_PF_RESET_XXX for the 'failed' member.
|
||||
*/
|
||||
#define JTEST_PF_RESET_FAILED(struct_pf_ptr) \
|
||||
JTEST_PF_RESET_XXX(failed, struct_pf_ptr)
|
||||
|
||||
#endif /* _JTEST_PF_H_ */
|
@ -0,0 +1,93 @@
|
||||
#ifndef _JTEST_SYSTICK_H_
|
||||
#define _JTEST_SYSTICK_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* Get access to the SysTick structure. */
|
||||
#if defined ARMCM0
|
||||
#include "ARMCM0.h"
|
||||
#elif defined ARMCM0P
|
||||
#include "ARMCM0plus.h"
|
||||
#elif defined ARMCM3
|
||||
#include "ARMCM3.h"
|
||||
#elif defined ARMCM4
|
||||
#include "ARMCM4.h"
|
||||
#elif defined ARMCM4_FP
|
||||
#include "ARMCM4_FP.h"
|
||||
#elif defined ARMCM7
|
||||
#include "ARMCM7.h"
|
||||
#elif defined ARMCM7_SP
|
||||
#include "ARMCM7_SP.h"
|
||||
#elif defined ARMCM7_DP
|
||||
#include "ARMCM7_DP.h"
|
||||
#elif defined ARMSC000
|
||||
#include "ARMSC000.h"
|
||||
#elif defined ARMSC300
|
||||
#include "ARMSC300.h"
|
||||
#elif defined ARMv8MBL
|
||||
#include "ARMv8MBL.h"
|
||||
#elif defined ARMv8MML
|
||||
#include "ARMv8MML.h"
|
||||
#elif defined ARMv8MML_DSP
|
||||
#include "ARMv8MML_DSP.h"
|
||||
#elif defined ARMv8MML_SP
|
||||
#include "ARMv8MML_SP.h"
|
||||
#elif defined ARMv8MML_DSP_SP
|
||||
#include "ARMv8MML_DSP_SP.h"
|
||||
#elif defined ARMv8MML_DP
|
||||
#include "ARMv8MML_DP.h"
|
||||
#elif defined ARMv8MML_DSP_DP
|
||||
#include "ARMv8MML_DSP_DP.h"
|
||||
|
||||
#else
|
||||
#warning "no appropriate header file found!"
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Initial value for the SysTick module.
|
||||
*
|
||||
* @note This is also the maximum value, important as SysTick is a decrementing
|
||||
* counter.
|
||||
*/
|
||||
#define JTEST_SYSTICK_INITIAL_VALUE 0xFFFFFF
|
||||
|
||||
/**
|
||||
* Reset the SysTick, decrementing timer to it's maximum value and disable it.
|
||||
*
|
||||
* This macro should leave the SysTick timer in a state that's ready for cycle
|
||||
* counting.
|
||||
*/
|
||||
#define JTEST_SYSTICK_RESET(systick_ptr) \
|
||||
do \
|
||||
{ \
|
||||
(systick_ptr)->LOAD = JTEST_SYSTICK_INITIAL_VALUE; \
|
||||
(systick_ptr)->VAL = 1; \
|
||||
\
|
||||
/* Disable the SysTick module. */ \
|
||||
(systick_ptr)->CTRL = UINT32_C(0x000000); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Start the SysTick timer, sourced by the processor clock.
|
||||
*/
|
||||
#define JTEST_SYSTICK_START(systick_ptr) \
|
||||
do \
|
||||
{ \
|
||||
(systick_ptr)->CTRL = \
|
||||
SysTick_CTRL_ENABLE_Msk | \
|
||||
SysTick_CTRL_CLKSOURCE_Msk; /* Internal clk*/ \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Evaluate to the current value of the SysTick timer.
|
||||
*/
|
||||
#define JTEST_SYSTICK_VALUE(systick_ptr) \
|
||||
((systick_ptr)->VAL)
|
||||
|
||||
#endif /* _JTEST_SYSTICK_H_ */
|
@ -0,0 +1,100 @@
|
||||
#ifndef _JTEST_TEST_H_
|
||||
#define _JTEST_TEST_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "jtest_util.h"
|
||||
#include "jtest_test_ret.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* A struct which represents a Test in the JTEST framework. This struct is
|
||||
* used to enable, run, and describe the test it represents.
|
||||
*/
|
||||
typedef struct JTEST_TEST_struct
|
||||
{
|
||||
JTEST_TEST_RET_t ( * test_fn_ptr)(void); /**< Pointer to the test function. */
|
||||
char * test_fn_str; /**< Name of the test function */
|
||||
char * fut_str; /**< Name of the function under test. */
|
||||
|
||||
/**
|
||||
* Flags that govern how the #JTEST_TEST_t behaves.
|
||||
*/
|
||||
union {
|
||||
struct {
|
||||
unsigned enabled : 1;
|
||||
unsigned unused : 7;
|
||||
} bits;
|
||||
uint8_t byte; /* Access all flags at once. */
|
||||
} flags;
|
||||
|
||||
} JTEST_TEST_t;
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Assign a test function to the #JTEST_TEST_t struct.
|
||||
*/
|
||||
#define JTEST_TEST_SET_FN(jtest_test_ptr, fn_ptr) \
|
||||
JTEST_SET_STRUCT_ATTRIBUTE(jtest_test_ptr, test_fn_ptr, fn_ptr)
|
||||
|
||||
/**
|
||||
* Specify a function under test (FUT) for the #JTEST_TEST_t struct.
|
||||
*/
|
||||
#define JTEST_TEST_SET_FUT(jtest_test_ptr, str) \
|
||||
JTEST_SET_STRUCT_ATTRIBUTE(jtest_test_ptr, fut_str, str)
|
||||
|
||||
/* Macros concerning JTEST_TEST_t flags */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#define JTEST_TEST_FLAG_SET 1 /**< Value of a set #JTEST_TEST_t flag. */
|
||||
#define JTEST_TEST_FLAG_CLR 0 /**< Value of a cleared #JTEST_TEST_t flag. */
|
||||
|
||||
/**
|
||||
* Evaluate to the flag in #JTEST_TEST_t having flag_name.
|
||||
*/
|
||||
#define JTEST_TEST_FLAG(jtest_test_ptr, flag_name) \
|
||||
((jtest_test_ptr)->flags.bits.flag_name)
|
||||
|
||||
/**
|
||||
* Dispatch macro for setting and clearing #JTEST_TEST_t flags.
|
||||
*
|
||||
* @param jtest_test_ptr Pointer to a #JTEST_TEST_t struct.
|
||||
* @param flag_name Name of the flag to set in #JTEST_TEST_t.flags.bits
|
||||
* @param xxx Vaid values: "SET" or "CLR"
|
||||
*
|
||||
* @note This function depends on JTEST_TEST_FLAG_SET and JTEST_TEST_FLAG_CLR.
|
||||
*/
|
||||
#define JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, xxx) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_TEST_FLAG(jtest_test_ptr, flag_name) = JTEST_TEST_FLAG_##xxx ; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Specification of #JTEST_TEST_XXX_FLAG to set #JTEST_TEST_t flags.
|
||||
*/
|
||||
#define JTEST_TEST_SET_FLAG(jtest_test_ptr, flag_name) \
|
||||
JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, SET)
|
||||
|
||||
/**
|
||||
* Specification of #JTEST_TEST_XXX_FLAG to clear #JTEST_TEST_t flags.
|
||||
*/
|
||||
#define JTEST_TEST_CLR_FLAG(jtest_test_ptr, flag_name) \
|
||||
JTEST_TEST_XXX_FLAG(jtest_test_ptr, flag_name, CLR)
|
||||
|
||||
/**
|
||||
* Evaluate to true if the #JTEST_TEST_t is enabled.
|
||||
*/
|
||||
#define JTEST_TEST_IS_ENABLED(jtest_test_ptr) \
|
||||
(JTEST_TEST_FLAG(jtest_test_ptr, enabled) == JTEST_TEST_FLAG_SET)
|
||||
|
||||
#endif /* _JTEST_TEST_H_ */
|
@ -0,0 +1,121 @@
|
||||
#ifndef _JTEST_TEST_CALL_H_
|
||||
#define _JTEST_TEST_CALL_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#include "jtest_test.h"
|
||||
#include "jtest_test_define.h"
|
||||
#include "jtest_fw.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Exectute the test in the #JTEST_TEST_t struct associated with the identifier
|
||||
* test_fn and store the result in retval.
|
||||
*/
|
||||
#define JTEST_TEST_RUN(retval, test_fn) \
|
||||
do \
|
||||
{ \
|
||||
JTEST_DUMP_STR("Test Name:\n"); \
|
||||
JTEST_DUMP_STR(JTEST_TEST_STRUCT_NAME(test_fn).test_fn_str); \
|
||||
JTEST_DUMP_STR("Function Under Test:\n"); \
|
||||
JTEST_DUMP_STR(JTEST_TEST_STRUCT_NAME(test_fn).fut_str); \
|
||||
retval = JTEST_TEST_STRUCT_NAME(test_fn).test_fn_ptr(); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the enclosing #JTEST_GROUP_t's pass/fail information based on
|
||||
* test_retval.
|
||||
*
|
||||
* @param test_retval A #JTEST_TEST_RET_enum for the current test.
|
||||
*
|
||||
* @warning Only use if #JTEST_TEST_t is called in the context of a
|
||||
* #JTEST_GROUP_t.
|
||||
*/
|
||||
#define JTEST_TEST_UPDATE_PARENT_GROUP_PF(test_retval) \
|
||||
do \
|
||||
{ \
|
||||
/* Update enclosing JTEST_GROUP_t with pass/fail info */ \
|
||||
if (test_retval == JTEST_TEST_PASSED) \
|
||||
{ \
|
||||
JTEST_GROUP_INC_PASSED(JTEST_CURRENT_GROUP_PTR(), 1); \
|
||||
} else { \
|
||||
JTEST_GROUP_INC_FAILED(JTEST_CURRENT_GROUP_PTR(), 1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the #JTEST_FW with pass/fail information based on test_retval.
|
||||
*
|
||||
* @param test_retval A #JTEST_TEST_RET_enum for the current test.
|
||||
*/
|
||||
#define JTEST_TEST_UPDATE_FW_PF(test_retval) \
|
||||
do \
|
||||
{ \
|
||||
/* Update the JTEST_FW with pass/fail info */ \
|
||||
if (test_retval == JTEST_TEST_PASSED) \
|
||||
{ \
|
||||
JTEST_FW_INC_PASSED( 1); \
|
||||
} else { \
|
||||
JTEST_FW_INC_FAILED(1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Update the enclosing JTEST_GROUP_t's pass/fail information, or the
|
||||
* #JTEST_FW's if this test has no enclosing #JTEST_GROUP_t.
|
||||
*
|
||||
* @param test_retval A #JTEST_TEST_RET_enum for the current test.
|
||||
*/
|
||||
#define JTEST_TEST_UPDATE_PARENT_GROUP_OR_FW_PF(test_retval) \
|
||||
do \
|
||||
{ \
|
||||
/* Update pass-fail information */ \
|
||||
if (JTEST_CURRENT_GROUP_PTR() /* Non-null */) \
|
||||
{ \
|
||||
JTEST_TEST_UPDATE_PARENT_GROUP_PF(test_retval); \
|
||||
} else { \
|
||||
JTEST_TEST_UPDATE_FW_PF(test_retval); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Dump the results of the test to the Keil Debugger.
|
||||
*/
|
||||
#define JTEST_TEST_DUMP_RESULTS(test_retval) \
|
||||
do \
|
||||
{ \
|
||||
if (test_retval == JTEST_TEST_PASSED) \
|
||||
{ \
|
||||
JTEST_DUMP_STR("Test Passed\n"); \
|
||||
} else { \
|
||||
JTEST_DUMP_STR("Test Failed\n"); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Call the #JTEST_TEST_t assocaited with the identifier test_fn.
|
||||
*/
|
||||
#define JTEST_TEST_CALL(test_fn) \
|
||||
do \
|
||||
{ \
|
||||
if (JTEST_TEST_IS_ENABLED(&JTEST_TEST_STRUCT_NAME(test_fn))) \
|
||||
{ \
|
||||
/* Default to failure */ \
|
||||
JTEST_TEST_RET_t __jtest_test_ret = JTEST_TEST_FAILED; \
|
||||
\
|
||||
JTEST_ACT_TEST_START(); \
|
||||
JTEST_TEST_RUN(__jtest_test_ret, test_fn); \
|
||||
\
|
||||
/* Update pass-fail information */ \
|
||||
JTEST_TEST_UPDATE_PARENT_GROUP_OR_FW_PF(__jtest_test_ret); \
|
||||
\
|
||||
JTEST_TEST_DUMP_RESULTS(__jtest_test_ret); \
|
||||
JTEST_ACT_TEST_END(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_TEST_CALL_H_ */
|
@ -0,0 +1,133 @@
|
||||
#ifndef _JTEST_TEST_DEFINE_H_
|
||||
#define _JTEST_TEST_DEFINE_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "jtest_util.h"
|
||||
#include "jtest_define.h"
|
||||
#include "jtest_test.h"
|
||||
|
||||
/* For defining macros with optional arguments */
|
||||
#include "opt_arg/opt_arg.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Prefix for all #JTEST_TEST_t structs.
|
||||
*/
|
||||
#define JTEST_TEST_STRUCT_NAME_PREFIX G_JTEST_TEST_STRUCT_
|
||||
|
||||
/**
|
||||
* Define test template used by #JTEST_TEST_t tests.
|
||||
*/
|
||||
#define JTEST_TEST_FN_TEMPLATE(test_fn) \
|
||||
JTEST_TEST_RET_t test_fn(void)
|
||||
|
||||
#define JTEST_TEST_FN_PROTOTYPE JTEST_TEST_FN_TEMPLATE /**< Alias for
|
||||
* #JTEST_TEST_FN_TEMPLATE. */
|
||||
|
||||
/**
|
||||
* Evaluate to the name of the #JTEST_TEST_t struct associated with test_fn.
|
||||
*/
|
||||
#define JTEST_TEST_STRUCT_NAME(test_fn) \
|
||||
JTEST_STRUCT_NAME(JTEST_TEST_STRUCT_NAME_PREFIX, test_fn)
|
||||
|
||||
/**
|
||||
* Define a #JTEST_TEST_t struct based on the given test_fn.
|
||||
*/
|
||||
#define JTEST_TEST_DEFINE_STRUCT(test_fn) \
|
||||
JTEST_DEFINE_STRUCT(JTEST_TEST_t, \
|
||||
JTEST_TEST_STRUCT_NAME(test_fn))
|
||||
|
||||
/**
|
||||
* Declare a #JTEST_TEST_t struct based on the given test_fn.
|
||||
*/
|
||||
#define JTEST_TEST_DECLARE_STRUCT(test_fn) \
|
||||
JTEST_DECLARE_STRUCT(JTEST_TEST_DEFINE_STRUCT(test_fn))
|
||||
|
||||
/**
|
||||
* Contents needed to initialize a JTEST_TEST_t struct.
|
||||
*/
|
||||
#define JTEST_TEST_STRUCT_INIT(test_fn, fut, enable) \
|
||||
test_fn, \
|
||||
STR_NL(test_fn), \
|
||||
STR_NL(fut), \
|
||||
{ \
|
||||
{ \
|
||||
enable, \
|
||||
0 \
|
||||
} \
|
||||
} \
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the contents of a #JTEST_TEST_t struct.
|
||||
*/
|
||||
#define JTEST_TEST_INIT(test_fn, fut, enable) \
|
||||
JTEST_TEST_DEFINE_STRUCT(test_fn) = { \
|
||||
JTEST_TEST_STRUCT_INIT(test_fn, fut, enable) \
|
||||
}
|
||||
|
||||
/* Test Definition Macro */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Define a #JTEST_TEST_t object and a test function.
|
||||
*/
|
||||
#define _JTEST_DEFINE_TEST(test_fn, fut, enable) \
|
||||
JTEST_TEST_FN_PROTOTYPE(test_fn); \
|
||||
JTEST_TEST_INIT(test_fn, fut, enable); \
|
||||
JTEST_TEST_FN_PROTOTYPE(test_fn) /* Notice the lacking semicolon */
|
||||
|
||||
/**
|
||||
* Declare a #JTEST_TEST_t object and a test function prototype.
|
||||
*/
|
||||
#define JTEST_DECLARE_TEST(test_fn) \
|
||||
JTEST_TEST_FN_PROTOTYPE(test_fn); \
|
||||
JTEST_TEST_DECLARE_STRUCT(test_fn) /* Note the lacking semicolon */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros with optional arguments */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* Top-level Interface */
|
||||
#define JTEST_DEFINE_TEST(...) \
|
||||
JTEST_DEFINE_TEST_(PP_NARG(__VA_ARGS__), ##__VA_ARGS__)
|
||||
|
||||
/* Dispatch Macro*/
|
||||
#define JTEST_DEFINE_TEST_(N, ...) \
|
||||
SPLICE(JTEST_DEFINE_TEST_, N)(__VA_ARGS__)
|
||||
|
||||
/* Default Arguments */
|
||||
#define JTEST_DEFINE_TEST_DEFAULT_FUT /* Blank */
|
||||
#define JTEST_DEFINE_TEST_DEFAULT_ENABLE \
|
||||
JTEST_TRUE /* Tests enabled by
|
||||
* default. */
|
||||
|
||||
/* Dispatch Cases*/
|
||||
#define JTEST_DEFINE_TEST_1(_1) \
|
||||
_JTEST_DEFINE_TEST( \
|
||||
_1, \
|
||||
JTEST_DEFINE_TEST_DEFAULT_FUT, \
|
||||
JTEST_DEFINE_TEST_DEFAULT_ENABLE \
|
||||
)
|
||||
|
||||
#define JTEST_DEFINE_TEST_2(_1, _2) \
|
||||
_JTEST_DEFINE_TEST( \
|
||||
_1, \
|
||||
_2, \
|
||||
JTEST_DEFINE_TEST_DEFAULT_ENABLE \
|
||||
)
|
||||
|
||||
#define JTEST_DEFINE_TEST_3(_1, _2, _3) \
|
||||
_JTEST_DEFINE_TEST( \
|
||||
_1, \
|
||||
_2, \
|
||||
_3 \
|
||||
)
|
||||
|
||||
#endif /* _JTEST_TEST_DEFINE_H_ */
|
@ -0,0 +1,17 @@
|
||||
#ifndef _JTEST_TEST_RET_H_
|
||||
#define _JTEST_TEST_RET_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Values a #JTEST_TEST_t can return.
|
||||
*/
|
||||
typedef enum JTEST_TEST_RET_enum
|
||||
{
|
||||
JTEST_TEST_PASSED,
|
||||
JTEST_TEST_FAILED
|
||||
} JTEST_TEST_RET_t;
|
||||
|
||||
#endif /* _JTEST_TEST_RET_H_ */
|
@ -0,0 +1,27 @@
|
||||
#ifndef _JTEST_UTIL_H_
|
||||
#define _JTEST_UTIL_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "util/util.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* Define boolean values for the framework. */
|
||||
#define JTEST_TRUE 1 /**< Value used for TRUE in JTEST. */
|
||||
#define JTEST_FALSE 0 /**< Value used for FALSE in JTEST. */
|
||||
|
||||
/**
|
||||
* Set the value of the attribute in the struct to by struct_ptr to value.
|
||||
*/
|
||||
#define JTEST_SET_STRUCT_ATTRIBUTE(struct_ptr, attribute, value) \
|
||||
do \
|
||||
{ \
|
||||
(struct_ptr)->attribute = (value); \
|
||||
} while (0)
|
||||
|
||||
#endif /* _JTEST_UTIL_H_ */
|
@ -0,0 +1,15 @@
|
||||
#ifndef _OPT_ARG_H_
|
||||
#define _OPT_ARG_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "pp_narg.h"
|
||||
#include "splice.h"
|
||||
|
||||
/* If you are Joseph Jaoudi, you have a snippet which expands into an
|
||||
example. If you are not Joseph, but possess his code, study the examples. If
|
||||
you have no examples, turn back contact Joseph. */
|
||||
|
||||
#endif /* _OPT_ARG_H_ */
|
@ -0,0 +1,25 @@
|
||||
#ifndef _PP_NARG_H_
|
||||
#define _PP_NARG_H_
|
||||
|
||||
#define PP_NARG(...) \
|
||||
PP_NARG_(__VA_ARGS__,PP_RSEQ_N())
|
||||
#define PP_NARG_(...) \
|
||||
PP_ARG_N(__VA_ARGS__)
|
||||
#define PP_ARG_N( \
|
||||
_1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \
|
||||
_11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \
|
||||
_21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \
|
||||
_31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \
|
||||
_41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \
|
||||
_51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \
|
||||
_61,_62,_63,N,...) N
|
||||
#define PP_RSEQ_N() \
|
||||
63,62,61,60, \
|
||||
59,58,57,56,55,54,53,52,51,50, \
|
||||
49,48,47,46,45,44,43,42,41,40, \
|
||||
39,38,37,36,35,34,33,32,31,30, \
|
||||
29,28,27,26,25,24,23,22,21,20, \
|
||||
19,18,17,16,15,14,13,12,11,10, \
|
||||
9,8,7,6,5,4,3,2,1,0
|
||||
|
||||
#endif /* _PP_NARG_H_ */
|
@ -0,0 +1,8 @@
|
||||
#ifndef _SPLICE_H_
|
||||
#define _SPLICE_H_
|
||||
|
||||
#define SPLICE(a,b) SPLICE_1(a,b)
|
||||
#define SPLICE_1(a,b) SPLICE_2(a,b)
|
||||
#define SPLICE_2(a,b) a##b
|
||||
|
||||
#endif /* _SPLICE_H_ */
|
@ -0,0 +1,52 @@
|
||||
#ifndef _UTIL_H_
|
||||
#define _UTIL_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Convert a symbol to a string and add a 'NewLine'.
|
||||
*/
|
||||
#define STR_NL(x) STR1_NL(x)
|
||||
#define STR1_NL(x) (STR2_NL(x)"\n")
|
||||
#define STR2_NL(x) #x
|
||||
|
||||
/**
|
||||
* Convert a symbol to a string.
|
||||
*/
|
||||
#define STR(x) STR1(x)
|
||||
#define STR1(x) STR2(x)
|
||||
#define STR2(x) #x
|
||||
|
||||
/**
|
||||
* Concatenate two symbols.
|
||||
*/
|
||||
#define CONCAT(a, b) CONCAT1(a, b)
|
||||
#define CONCAT1(a, b) CONCAT2(a, b)
|
||||
#define CONCAT2(a, b) a##b
|
||||
|
||||
|
||||
/**
|
||||
* Place curly braces around a varaible number of macro arguments.
|
||||
*/
|
||||
#define CURLY(...) {__VA_ARGS__}
|
||||
|
||||
/**
|
||||
* Place parenthesis around a variable number of macro arguments.
|
||||
*/
|
||||
#define PAREN(...) (__VA_ARGS__)
|
||||
|
||||
/* Standard min/max macros. */
|
||||
#define MIN(x,y) (((x) < (y)) ? (x) : (y) )
|
||||
#define MAX(x,y) (((x) > (y)) ? (x) : (y) )
|
||||
|
||||
/**
|
||||
* Bound value using low and high limits.
|
||||
*
|
||||
* Evaluate to a number in the range, endpoint inclusive.
|
||||
*/
|
||||
#define BOUND(low, high, value) \
|
||||
MAX(MIN(high, value), low)
|
||||
|
||||
#endif /* _UTIL_H_ */
|
@ -0,0 +1,9 @@
|
||||
#include "../inc/jtest_cycle.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Define Module Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* const char * JTEST_CYCLE_STRF = "Running: %s\nCycles: %" PRIu32 "\n"; */
|
||||
const char * JTEST_CYCLE_STRF = "Cycles: %" PRIu32 "\n"; /* function name + parameter string skipped */
|
@ -0,0 +1,36 @@
|
||||
#include "jtest_fw.h"
|
||||
|
||||
/**
|
||||
* Dump the JTEST_FW.str_buffer the Keil framework in pieces.
|
||||
*
|
||||
* The JTEST_FW.str_buffer contains more characters than the Keil framework can
|
||||
* dump at once. This function dumps them in blocks.
|
||||
*/
|
||||
void jtest_dump_str_segments(void)
|
||||
{
|
||||
uint32_t seg_idx = 0;
|
||||
uint32_t memmove_idx = 0;
|
||||
uint32_t seg_cnt =
|
||||
(strlen(JTEST_FW.str_buffer) / JTEST_STR_MAX_OUTPUT_SIZE) + 1;
|
||||
|
||||
for( seg_idx = 0; seg_idx < seg_cnt; ++seg_idx)
|
||||
{
|
||||
JTEST_TRIGGER_ACTION(dump_str);
|
||||
|
||||
if (seg_idx < JTEST_STR_MAX_OUTPUT_SEGMENTS)
|
||||
{
|
||||
memmove_idx = 0;
|
||||
while (memmove_idx < (seg_cnt - seg_idx -1) )
|
||||
{
|
||||
memmove(
|
||||
JTEST_FW.str_buffer+
|
||||
(memmove_idx* JTEST_STR_MAX_OUTPUT_SIZE),
|
||||
JTEST_FW.str_buffer+
|
||||
((memmove_idx+1)*JTEST_STR_MAX_OUTPUT_SIZE),
|
||||
JTEST_BUF_SIZE);
|
||||
++memmove_idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#include "../inc/jtest.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Define Global Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
char JTEST_FW_STR_BUFFER[JTEST_BUF_SIZE] = {0};
|
||||
|
||||
volatile JTEST_FW_t JTEST_FW = {0};
|
@ -0,0 +1,37 @@
|
||||
|
||||
#include "jtest_fw.h"
|
||||
|
||||
void test_start (void) {
|
||||
// ;
|
||||
JTEST_FW.test_start++;
|
||||
}
|
||||
|
||||
void test_end (void) {
|
||||
// ;
|
||||
JTEST_FW.test_end++;
|
||||
}
|
||||
|
||||
void group_start (void) {
|
||||
// ;
|
||||
JTEST_FW.group_start++;
|
||||
}
|
||||
|
||||
void group_end (void) {
|
||||
// ;
|
||||
JTEST_FW.group_end++;
|
||||
}
|
||||
|
||||
void dump_str (void) {
|
||||
// ;
|
||||
JTEST_FW.dump_str++;
|
||||
}
|
||||
|
||||
void dump_data (void) {
|
||||
// ;
|
||||
JTEST_FW.dump_data++;
|
||||
}
|
||||
|
||||
void exit_fw (void) {
|
||||
// ;
|
||||
JTEST_FW.exit_fw++;
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
#ifndef _ALL_TESTS_H_
|
||||
#define _ALL_TESTS_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Test Groups */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(all_tests);
|
||||
|
||||
#endif /* _ALL_TESTS_H_ */
|
@ -0,0 +1,267 @@
|
||||
#ifndef _BASIC_MATH_TEMPLATES_H_
|
||||
#define _BASIC_MATH_TEMPLATES_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#include "test_templates.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Group Specific Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Compare the outputs used by basic math tests for the function under test and
|
||||
* the reference function.
|
||||
*/
|
||||
#define BASIC_MATH_COMPARE_INTERFACE(block_size, output_type) \
|
||||
TEST_ASSERT_BUFFERS_EQUAL( \
|
||||
basic_math_output_ref.data_ptr, \
|
||||
basic_math_output_fut.data_ptr, \
|
||||
block_size * sizeof(output_type))
|
||||
|
||||
/*
|
||||
* Comparison SNR thresholds for the data types used in basic_math_tests.
|
||||
*/
|
||||
#define BASIC_MATH_SNR_THRESHOLD_float32_t 120
|
||||
#define BASIC_MATH_SNR_THRESHOLD_q31_t 100
|
||||
#define BASIC_MATH_SNR_THRESHOLD_q15_t 75
|
||||
#define BASIC_MATH_SNR_THRESHOLD_q7_t 25
|
||||
|
||||
/**
|
||||
* Compare reference and fut outputs using SNR.
|
||||
*
|
||||
* @note The outputs are converted to float32_t before comparison.
|
||||
*/
|
||||
#define BASIC_MATH_SNR_COMPARE_INTERFACE(block_size, output_type) \
|
||||
do \
|
||||
{ \
|
||||
TEST_CONVERT_AND_ASSERT_SNR( \
|
||||
basic_math_output_f32_ref, \
|
||||
basic_math_output_ref.data_ptr, \
|
||||
basic_math_output_f32_fut, \
|
||||
basic_math_output_fut.data_ptr, \
|
||||
block_size, \
|
||||
output_type, \
|
||||
BASIC_MATH_SNR_THRESHOLD_##output_type \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/**
|
||||
* Compare reference and fut outputs using SNR.
|
||||
*
|
||||
* @note The outputs are converted to float32_t before comparison.
|
||||
*/
|
||||
#define BASIC_MATH_SNR_ELT1_COMPARE_INTERFACE(block_size, output_type) \
|
||||
do \
|
||||
{ \
|
||||
TEST_CONVERT_AND_ASSERT_SNR( \
|
||||
basic_math_output_f32_ref, \
|
||||
basic_math_output_ref.data_ptr, \
|
||||
basic_math_output_f32_fut, \
|
||||
basic_math_output_fut.data_ptr, \
|
||||
1, \
|
||||
output_type, \
|
||||
BASIC_MATH_SNR_THRESHOLD_##output_type \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Input Interfaces */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* General:
|
||||
* Input interfaces provide inputs to functions inside test templates. They
|
||||
* ONLY provide the inputs. The output variables should be hard coded.
|
||||
*
|
||||
* The input interfaces must have the following format:
|
||||
*
|
||||
* ARM_xxx_INPUT_INTERFACE() or
|
||||
* REF_xxx_INPUT_INTERFACE()
|
||||
*
|
||||
* The xxx must be lowercase, and is intended to be the indentifying substring
|
||||
* in the function's name. Acceptable values are 'sub' or 'add' from the
|
||||
* functions arm_add_q31.
|
||||
*/
|
||||
|
||||
#define ARM_abs_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, basic_math_output_fut.data_ptr, block_size)
|
||||
|
||||
#define REF_abs_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, basic_math_output_ref.data_ptr, block_size)
|
||||
|
||||
#define ARM_add_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, basic_math_output_fut.data_ptr, block_size) \
|
||||
|
||||
#define REF_add_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, basic_math_output_ref.data_ptr, block_size) \
|
||||
|
||||
#define ARM_dot_prod_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, block_size, basic_math_output_fut.data_ptr) \
|
||||
|
||||
#define REF_dot_prod_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, block_size, basic_math_output_ref.data_ptr) \
|
||||
|
||||
#define ARM_mult_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, basic_math_output_fut.data_ptr, block_size) \
|
||||
|
||||
#define REF_mult_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, basic_math_output_ref.data_ptr, block_size) \
|
||||
|
||||
#define ARM_negate_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, basic_math_output_fut.data_ptr, block_size)
|
||||
|
||||
#define REF_negate_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, basic_math_output_ref.data_ptr, block_size)
|
||||
|
||||
#define ARM_offset_INPUT_INTERFACE(input, elt, block_size) \
|
||||
PAREN(input, elt, basic_math_output_fut.data_ptr, block_size) \
|
||||
|
||||
#define REF_offset_INPUT_INTERFACE(input, elt, block_size) \
|
||||
PAREN(input, elt, basic_math_output_ref.data_ptr, block_size) \
|
||||
|
||||
#define ARM_shift_INPUT_INTERFACE(input, elt, block_size) \
|
||||
PAREN(input, elt, basic_math_output_fut.data_ptr, block_size) \
|
||||
|
||||
#define REF_shift_INPUT_INTERFACE(input, elt, block_size) \
|
||||
PAREN(input, elt, basic_math_output_ref.data_ptr, block_size) \
|
||||
|
||||
#define ARM_scale_float_INPUT_INTERFACE(input, elt, block_size) \
|
||||
PAREN(input, elt, basic_math_output_fut.data_ptr, block_size) \
|
||||
|
||||
#define REF_scale_float_INPUT_INTERFACE(input, elt, block_size) \
|
||||
PAREN(input, elt, basic_math_output_ref.data_ptr, block_size) \
|
||||
|
||||
/* These two are for the fixed point functions */
|
||||
#define ARM_scale_INPUT_INTERFACE(input, elt1, elt2, block_size) \
|
||||
PAREN(input, elt1, elt2, basic_math_output_fut.data_ptr, block_size) \
|
||||
|
||||
#define REF_scale_INPUT_INTERFACE(input, elt1, elt2, block_size) \
|
||||
PAREN(input, elt1, elt2, basic_math_output_ref.data_ptr, block_size) \
|
||||
|
||||
#define ARM_sub_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, basic_math_output_fut.data_ptr, block_size) \
|
||||
|
||||
#define REF_sub_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, basic_math_output_ref.data_ptr, block_size) \
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Test Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Specialization of #TEST_TEMPLATE_BUF1_BLK() for basic math tests.
|
||||
*
|
||||
* @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and
|
||||
* REF_xxx_INPUT_INTERFACEs.
|
||||
*/
|
||||
#define BASIC_MATH_DEFINE_TEST_TEMPLATE_BUF1_BLK(fn_name, \
|
||||
suffix, \
|
||||
input_type, \
|
||||
output_type) \
|
||||
JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test, \
|
||||
arm_##fn_name##_##suffix) \
|
||||
{ \
|
||||
TEST_TEMPLATE_BUF1_BLK( \
|
||||
basic_math_f_all, \
|
||||
basic_math_block_sizes, \
|
||||
input_type, \
|
||||
output_type, \
|
||||
arm_##fn_name##_##suffix, \
|
||||
ARM_##fn_name##_INPUT_INTERFACE, \
|
||||
ref_##fn_name##_##suffix, \
|
||||
REF_##fn_name##_INPUT_INTERFACE, \
|
||||
BASIC_MATH_COMPARE_INTERFACE); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of #TEST_TEMPLATE_BUF2_BLK() for basic math tests.
|
||||
*
|
||||
* @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and
|
||||
* REF_xxx_INPUT_INTERFACEs.
|
||||
*/
|
||||
#define BASIC_MATH_DEFINE_TEST_TEMPLATE_BUF2_BLK(fn_name, \
|
||||
suffix, \
|
||||
input_type, \
|
||||
output_type, \
|
||||
comparison_interface) \
|
||||
JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test, \
|
||||
arm_##fn_name##_##suffix) \
|
||||
{ \
|
||||
TEST_TEMPLATE_BUF2_BLK( \
|
||||
basic_math_f_all, \
|
||||
basic_math_f_all, \
|
||||
basic_math_block_sizes, \
|
||||
input_type, \
|
||||
output_type, \
|
||||
arm_##fn_name##_##suffix, \
|
||||
ARM_##fn_name##_INPUT_INTERFACE, \
|
||||
ref_##fn_name##_##suffix, \
|
||||
REF_##fn_name##_INPUT_INTERFACE, \
|
||||
comparison_interface); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of #TEST_TEMPLATE_BUF1_ELT1_BLK() for basic math tests.
|
||||
*
|
||||
* @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and
|
||||
* REF_xxx_INPUT_INTERFACEs.
|
||||
*/
|
||||
#define BASIC_MATH_DEFINE_TEST_TEMPLATE_BUF1_ELT1_BLK(fn_name, \
|
||||
suffix, \
|
||||
input_type, \
|
||||
elt_type, \
|
||||
output_type) \
|
||||
JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test, \
|
||||
arm_##fn_name##_##suffix) \
|
||||
{ \
|
||||
TEST_TEMPLATE_BUF1_ELT1_BLK( \
|
||||
basic_math_f_all, \
|
||||
basic_math_elts, \
|
||||
basic_math_block_sizes, \
|
||||
input_type, \
|
||||
elt_type, \
|
||||
output_type, \
|
||||
arm_##fn_name##_##suffix, \
|
||||
ARM_##fn_name##_INPUT_INTERFACE, \
|
||||
ref_##fn_name##_##suffix, \
|
||||
REF_##fn_name##_INPUT_INTERFACE, \
|
||||
BASIC_MATH_COMPARE_INTERFACE); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of #TEST_TEMPLATE_BUF1_ELT2_BLK() for basic math tests.
|
||||
*
|
||||
* @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and
|
||||
* REF_xxx_INPUT_INTERFACEs.
|
||||
*/
|
||||
#define BASIC_MATH_DEFINE_TEST_TEMPLATE_BUF1_ELT2_BLK(fn_name, \
|
||||
suffix, \
|
||||
input_type, \
|
||||
elt1_type, \
|
||||
elt2_type, \
|
||||
output_type) \
|
||||
JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test, \
|
||||
arm_##fn_name##_##suffix) \
|
||||
{ \
|
||||
TEST_TEMPLATE_BUF1_ELT2_BLK( \
|
||||
basic_math_f_all, \
|
||||
basic_math_elts, \
|
||||
basic_math_elts2, \
|
||||
basic_math_block_sizes, \
|
||||
input_type, \
|
||||
elt1_type, \
|
||||
elt2_type, \
|
||||
output_type, \
|
||||
arm_##fn_name##_##suffix, \
|
||||
ARM_##fn_name##_INPUT_INTERFACE, \
|
||||
ref_##fn_name##_##suffix, \
|
||||
REF_##fn_name##_INPUT_INTERFACE, \
|
||||
BASIC_MATH_COMPARE_INTERFACE); \
|
||||
}
|
||||
|
||||
#endif /* _BASIC_MATH_TEMPLATES_H_ */
|
@ -0,0 +1,46 @@
|
||||
#ifndef ARM_BASIC_MATH_TEST_DATA_H
|
||||
#define ARM_BASIC_MATH_TEST_DATA_H
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "arr_desc.h"
|
||||
#include "arm_math.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#define BASIC_MATH_MAX_INPUT_ELEMENTS 32
|
||||
#define BASIC_MATH_BIGGEST_INPUT_TYPE float32_t
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* Input/Output Buffers */
|
||||
ARR_DESC_DECLARE(basic_math_output_fut);
|
||||
ARR_DESC_DECLARE(basic_math_output_ref);
|
||||
|
||||
extern BASIC_MATH_BIGGEST_INPUT_TYPE
|
||||
basic_math_output_f32_ref[BASIC_MATH_MAX_INPUT_ELEMENTS];
|
||||
|
||||
extern BASIC_MATH_BIGGEST_INPUT_TYPE
|
||||
basic_math_output_f32_fut[BASIC_MATH_MAX_INPUT_ELEMENTS];
|
||||
|
||||
/* Block Sizes*/
|
||||
ARR_DESC_DECLARE(basic_math_block_sizes);
|
||||
|
||||
/* Numbers */
|
||||
ARR_DESC_DECLARE(basic_math_elts);
|
||||
ARR_DESC_DECLARE(basic_math_elts2);
|
||||
ARR_DESC_DECLARE(basic_math_eltsf);
|
||||
|
||||
/* Float Inputs */
|
||||
ARR_DESC_DECLARE(basic_math_zeros);
|
||||
ARR_DESC_DECLARE(basic_math_f_2);
|
||||
ARR_DESC_DECLARE(basic_math_f_15);
|
||||
ARR_DESC_DECLARE(basic_math_f_32);
|
||||
ARR_DESC_DECLARE(basic_math_f_all);
|
||||
|
||||
#endif
|
@ -0,0 +1,9 @@
|
||||
#ifndef _BASIC_MATH_TEST_GROUP_H_
|
||||
#define _BASIC_MATH_TEST_GROUP_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Test Groups */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(basic_math_tests);
|
||||
|
||||
#endif /* _BASIC_MATH_TEST_GROUP_H_ */
|
@ -0,0 +1,17 @@
|
||||
#ifndef _BASIC_MATH_TESTS_H_
|
||||
#define _BASIC_MATH_TESTS_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Test/Group Declarations */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(abs_tests);
|
||||
JTEST_DECLARE_GROUP(add_tests);
|
||||
JTEST_DECLARE_GROUP(dot_prod_tests);
|
||||
JTEST_DECLARE_GROUP(mult_tests);
|
||||
JTEST_DECLARE_GROUP(negate_tests);
|
||||
JTEST_DECLARE_GROUP(offset_tests);
|
||||
JTEST_DECLARE_GROUP(scale_tests);
|
||||
JTEST_DECLARE_GROUP(shift_tests);
|
||||
JTEST_DECLARE_GROUP(sub_tests);
|
||||
|
||||
#endif /* _BASIC_MATH_TESTS_H_ */
|
@ -0,0 +1,222 @@
|
||||
#ifndef _COMPLEX_MATH_TEMPLATES_H_
|
||||
#define _COMPLEX_MATH_TEMPLATES_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#include "test_templates.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Group Specific Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Compare the real outputs from the function under test and the reference
|
||||
* function.
|
||||
*/
|
||||
#define COMPLEX_MATH_COMPARE_RE_INTERFACE(block_size, output_type) \
|
||||
TEST_ASSERT_BUFFERS_EQUAL( \
|
||||
complex_math_output_ref_a.data_ptr, \
|
||||
complex_math_output_fut_a.data_ptr, \
|
||||
block_size * sizeof(output_type))
|
||||
|
||||
/**
|
||||
* Compare the real and imaginary outputs from the function under test and the
|
||||
* reference function.
|
||||
*/
|
||||
#define COMPLEX_MATH_COMPARE_CMPLX_INTERFACE(block_size, output_type) \
|
||||
do \
|
||||
{ \
|
||||
COMPLEX_MATH_COMPARE_RE_INTERFACE(block_size * 2, output_type); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*
|
||||
* Comparison SNR thresholds for the data types used in complex_math_tests.
|
||||
*/
|
||||
#define COMPLEX_MATH_SNR_THRESHOLD_float32_t 120
|
||||
#define COMPLEX_MATH_SNR_THRESHOLD_q31_t 100
|
||||
#define COMPLEX_MATH_SNR_THRESHOLD_q15_t 75
|
||||
|
||||
/**
|
||||
* Compare reference and fut outputs using SNR.
|
||||
*
|
||||
* The output_suffix specifies which output buffers to use for the
|
||||
* comparison. An output_suffix of 'a' expands to the following buffers:
|
||||
*
|
||||
* - complex_math_output_f32_ref_a
|
||||
* - complex_math_output_f32_fut_a
|
||||
* - complex_math_output_ref_a
|
||||
* - complex_math_output_fut_a
|
||||
*
|
||||
* @note The outputs are converted to float32_t before comparison.
|
||||
*/
|
||||
#define COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size, \
|
||||
output_type, \
|
||||
output_suffix) \
|
||||
do \
|
||||
{ \
|
||||
TEST_CONVERT_AND_ASSERT_SNR( \
|
||||
complex_math_output_f32_ref_##output_suffix, \
|
||||
complex_math_output_ref_##output_suffix.data_ptr, \
|
||||
complex_math_output_f32_fut_##output_suffix, \
|
||||
complex_math_output_fut_##output_suffix.data_ptr, \
|
||||
block_size, \
|
||||
output_type, \
|
||||
COMPLEX_MATH_SNR_THRESHOLD_##output_type \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Specification of #COMPLEX_MATH_SNR_COMPARE_INTERFACE() for real outputs.
|
||||
*/
|
||||
#define COMPLEX_MATH_SNR_COMPARE_RE_INTERFACE(block_size, \
|
||||
output_type) \
|
||||
COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size, \
|
||||
output_type, \
|
||||
a)
|
||||
|
||||
/**
|
||||
* Specification of #COMPLEX_MATH_SNR_COMPARE_INTERFACE() for complex outputs.
|
||||
*/
|
||||
#define COMPLEX_MATH_SNR_COMPARE_CMPLX_INTERFACE(block_size, \
|
||||
output_type) \
|
||||
COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size * 2, \
|
||||
output_type, \
|
||||
a)
|
||||
|
||||
/**
|
||||
* Compare reference and fut split outputs using SNR.
|
||||
*
|
||||
* 'Split' refers to two separate output buffers; one for real and one for
|
||||
* complex.
|
||||
*/
|
||||
#define COMPLEX_MATH_SNR_COMPARE_SPLIT_INTERFACE(block_size, \
|
||||
output_type) \
|
||||
do \
|
||||
{ \
|
||||
COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size, \
|
||||
output_type, \
|
||||
a); \
|
||||
COMPLEX_MATH_SNR_COMPARE_OUT_INTERFACE(block_size, \
|
||||
output_type, \
|
||||
b); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Input Interfaces */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* General:
|
||||
* Input interfaces provide inputs to functions inside test templates. They
|
||||
* ONLY provide the inputs. The output variables should be hard coded.
|
||||
*
|
||||
* The input interfaces must have the following format:
|
||||
*
|
||||
* ARM_xxx_INPUT_INTERFACE() or
|
||||
* REF_xxx_INPUT_INTERFACE()
|
||||
*
|
||||
* The xxx must be lowercase, and is intended to be the indentifying substring
|
||||
* in the function's name. Acceptable values are 'sub' or 'add' from the
|
||||
* functions arm_add_q31.
|
||||
*/
|
||||
|
||||
#define ARM_cmplx_conj_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, complex_math_output_fut_a.data_ptr, block_size)
|
||||
|
||||
#define REF_cmplx_conj_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, complex_math_output_ref_a.data_ptr, block_size)
|
||||
|
||||
#define ARM_cmplx_dot_prod_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, block_size, \
|
||||
complex_math_output_fut_a.data_ptr, \
|
||||
complex_math_output_fut_b.data_ptr)
|
||||
|
||||
#define REF_cmplx_dot_prod_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, block_size, \
|
||||
complex_math_output_ref_a.data_ptr, \
|
||||
complex_math_output_ref_b.data_ptr)
|
||||
|
||||
#define ARM_cmplx_mag_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, complex_math_output_fut_a.data_ptr, block_size)
|
||||
|
||||
#define REF_cmplx_mag_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, complex_math_output_ref_a.data_ptr, block_size)
|
||||
|
||||
#define ARM_cmplx_mag_squared_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, complex_math_output_fut_a.data_ptr, block_size)
|
||||
|
||||
#define REF_cmplx_mag_squared_INPUT_INTERFACE(input, block_size) \
|
||||
PAREN(input, complex_math_output_ref_a.data_ptr, block_size)
|
||||
|
||||
#define ARM_cmplx_mult_cmplx_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, complex_math_output_fut_a.data_ptr, block_size)
|
||||
|
||||
#define REF_cmplx_mult_cmplx_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, complex_math_output_ref_a.data_ptr, block_size)
|
||||
|
||||
#define ARM_cmplx_mult_real_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, complex_math_output_fut_a.data_ptr, block_size)
|
||||
|
||||
#define REF_cmplx_mult_real_INPUT_INTERFACE(input_a, input_b, block_size) \
|
||||
PAREN(input_a, input_b, complex_math_output_ref_a.data_ptr, block_size)
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Test Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Specialization of #TEST_TEMPLATE_BUF1_BLK() for complex math tests.
|
||||
*
|
||||
* @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and
|
||||
* REF_xxx_INPUT_INTERFACEs.
|
||||
*/
|
||||
#define COMPLEX_MATH_DEFINE_TEST_TEMPLATE_BUF1_BLK(fn_name, \
|
||||
suffix, \
|
||||
input_type, \
|
||||
output_type, \
|
||||
comparison_interface) \
|
||||
JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test, \
|
||||
arm_##fn_name##_##suffix) \
|
||||
{ \
|
||||
TEST_TEMPLATE_BUF1_BLK( \
|
||||
complex_math_f_all, \
|
||||
complex_math_block_sizes, \
|
||||
input_type, \
|
||||
output_type, \
|
||||
arm_##fn_name##_##suffix, \
|
||||
ARM_##fn_name##_INPUT_INTERFACE, \
|
||||
ref_##fn_name##_##suffix, \
|
||||
REF_##fn_name##_INPUT_INTERFACE, \
|
||||
comparison_interface); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Specialization of #TEST_TEMPLATE_BUF2_BLK1() for complex math tests.
|
||||
*
|
||||
* @note This macro relies on the existance of ARM_xxx_INPUT_INTERFACE and
|
||||
* REF_xxx_INPUT_INTERFACEs.
|
||||
*/
|
||||
#define COMPLEX_MATH_DEFINE_TEST_TEMPLATE_BUF2_BLK(fn_name, \
|
||||
suffix, \
|
||||
input_type, \
|
||||
output_type, \
|
||||
comparison_interface) \
|
||||
JTEST_DEFINE_TEST(arm_##fn_name##_##suffix##_test, \
|
||||
arm_##fn_name##_##suffix) \
|
||||
{ \
|
||||
TEST_TEMPLATE_BUF2_BLK( \
|
||||
complex_math_f_all, \
|
||||
complex_math_f_all, \
|
||||
complex_math_block_sizes, \
|
||||
input_type, \
|
||||
output_type, \
|
||||
arm_##fn_name##_##suffix, \
|
||||
ARM_##fn_name##_INPUT_INTERFACE, \
|
||||
ref_##fn_name##_##suffix, \
|
||||
REF_##fn_name##_INPUT_INTERFACE, \
|
||||
comparison_interface); \
|
||||
}
|
||||
|
||||
#endif /* _COMPLEX_MATH_TEMPLATES_H_ */
|
@ -0,0 +1,50 @@
|
||||
#ifndef _COMPLEX_MATH_TEST_DATA_H_
|
||||
#define _COMPLEX_MATH_TEST_DATA_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "arr_desc.h"
|
||||
#include "arm_math.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#define COMPLEX_MATH_MAX_INPUT_ELEMENTS 32
|
||||
#define COMPLEX_MATH_BIGGEST_INPUT_TYPE float32_t
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Decalare Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* Input/Output Buffers */
|
||||
ARR_DESC_DECLARE(complex_math_output_fut_a);
|
||||
ARR_DESC_DECLARE(complex_math_output_fut_b);
|
||||
ARR_DESC_DECLARE(complex_math_output_ref_a);
|
||||
ARR_DESC_DECLARE(complex_math_output_ref_b);
|
||||
|
||||
extern COMPLEX_MATH_BIGGEST_INPUT_TYPE
|
||||
complex_math_output_f32_ref_a[COMPLEX_MATH_MAX_INPUT_ELEMENTS * 2];
|
||||
|
||||
extern COMPLEX_MATH_BIGGEST_INPUT_TYPE
|
||||
complex_math_output_f32_ref_b[COMPLEX_MATH_MAX_INPUT_ELEMENTS * 2];
|
||||
|
||||
extern COMPLEX_MATH_BIGGEST_INPUT_TYPE
|
||||
complex_math_output_f32_fut_a[COMPLEX_MATH_MAX_INPUT_ELEMENTS * 2];
|
||||
|
||||
extern COMPLEX_MATH_BIGGEST_INPUT_TYPE
|
||||
complex_math_output_f32_fut_b[COMPLEX_MATH_MAX_INPUT_ELEMENTS * 2];
|
||||
|
||||
/* Block Sizes*/
|
||||
ARR_DESC_DECLARE(complex_math_block_sizes);
|
||||
|
||||
/* Float Inputs */
|
||||
ARR_DESC_DECLARE(complex_math_zeros);
|
||||
ARR_DESC_DECLARE(complex_math_f_2);
|
||||
ARR_DESC_DECLARE(complex_math_f_15);
|
||||
ARR_DESC_DECLARE(complex_math_f_32);
|
||||
ARR_DESC_DECLARE(complex_math_f_all);
|
||||
|
||||
|
||||
#endif /* _COMPLEX_MATH_TEST_DATA_H_ */
|
@ -0,0 +1,9 @@
|
||||
#ifndef _COMPLEX_MATH_TEST_GROUP_H_
|
||||
#define _COMPLEX_MATH_TEST_GROUP_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Test Groups */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(complex_math_tests);
|
||||
|
||||
#endif /* _COMPLEX_MATH_TEST_GROUP_H_ */
|
@ -0,0 +1,14 @@
|
||||
#ifndef _COMPLEX_MATH_TESTS_H_
|
||||
#define _COMPLEX_MATH_TESTS_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Test/Group Declarations */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(cmplx_conj_tests);
|
||||
JTEST_DECLARE_GROUP(cmplx_dot_prod_tests);
|
||||
JTEST_DECLARE_GROUP(cmplx_mag_tests);
|
||||
JTEST_DECLARE_GROUP(cmplx_mag_squared_tests);
|
||||
JTEST_DECLARE_GROUP(cmplx_mult_cmplx_tests);
|
||||
JTEST_DECLARE_GROUP(cmplx_mult_real_tests);
|
||||
|
||||
#endif /* _COMPLEX_MATH_TESTS_H_ */
|
@ -0,0 +1,46 @@
|
||||
#ifndef _CONTROLLER_TEMPLATES_H_
|
||||
#define _CONTROLLER_TEMPLATES_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "test_templates.h"
|
||||
#include <string.h> /* memcpy() */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Group Specific Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Comparison SNR thresholds for the data types used in transform_tests.
|
||||
*/
|
||||
#define CONTROLLER_SNR_THRESHOLD_float32_t 110
|
||||
#define CONTROLLER_SNR_THRESHOLD_q31_t 100
|
||||
#define CONTROLLER_SNR_THRESHOLD_q15_t 45
|
||||
|
||||
/**
|
||||
* Compare the outputs from the function under test and the reference
|
||||
* function using SNR.
|
||||
*/
|
||||
#define CONTROLLER_SNR_COMPARE_INTERFACE(block_size, \
|
||||
output_type) \
|
||||
do \
|
||||
{ \
|
||||
TEST_CONVERT_AND_ASSERT_SNR( \
|
||||
controller_output_f32_ref, \
|
||||
(output_type *) controller_output_ref, \
|
||||
controller_output_f32_fut, \
|
||||
(output_type *) controller_output_fut, \
|
||||
block_size, \
|
||||
output_type, \
|
||||
CONTROLLER_SNR_THRESHOLD_##output_type \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* TEST Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* _CONTROLLER_TEMPLATES_H_ */
|
@ -0,0 +1,33 @@
|
||||
#ifndef _CONTROLLER_TEST_DATA_H_
|
||||
#define _CONTROLLER_TEST_DATA_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#define CONTROLLER_MAX_LEN 1024
|
||||
#define CONTROLLER_MAX_COEFFS_LEN (12 * 3)
|
||||
#define TRANFORM_BIGGEST_INPUT_TYPE float32_t
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Variable Declarations */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
extern float32_t controller_output_fut[CONTROLLER_MAX_LEN];
|
||||
extern float32_t controller_output_ref[CONTROLLER_MAX_LEN];
|
||||
extern float32_t controller_output_f32_fut[CONTROLLER_MAX_LEN];
|
||||
extern float32_t controller_output_f32_ref[CONTROLLER_MAX_LEN];
|
||||
extern const float32_t controller_f32_inputs[CONTROLLER_MAX_LEN];
|
||||
extern const q31_t controller_q31_inputs[CONTROLLER_MAX_LEN];
|
||||
extern const q15_t * controller_q15_inputs;
|
||||
extern const float32_t controller_f32_coeffs[CONTROLLER_MAX_COEFFS_LEN];
|
||||
extern const q31_t controller_q31_coeffs[CONTROLLER_MAX_COEFFS_LEN];
|
||||
extern const q15_t controller_q15_coeffs[CONTROLLER_MAX_COEFFS_LEN];
|
||||
|
||||
#endif /* _CONTROLLER_TEST_DATA_H_ */
|
@ -0,0 +1,9 @@
|
||||
#ifndef _CONTROLLER_TEST_GROUP_H_
|
||||
#define _CONTROLLER_TEST_GROUP_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Test Group */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(controller_tests);
|
||||
|
||||
#endif /* _CONTROLLER_TEST_GROUP_H_ */
|
@ -0,0 +1,11 @@
|
||||
#ifndef _CONTROLLER_TESTS_H_
|
||||
#define _CONTROLLER_TESTS_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Test/Group Declarations */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(pid_reset_tests);
|
||||
JTEST_DECLARE_GROUP(sin_cos_tests);
|
||||
JTEST_DECLARE_GROUP(pid_tests);
|
||||
|
||||
#endif /* _CONTROLLER_TESTS_H_ */
|
@ -0,0 +1,102 @@
|
||||
#ifndef _FAST_MATH_TEMPLATES_H_
|
||||
#define _FAST_MATH_TEMPLATES_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "test_templates.h"
|
||||
#include <string.h> /* memcpy() */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Group Specific Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Comparison SNR thresholds for the data types used in transform_tests.
|
||||
*/
|
||||
#define FAST_MATH_SNR_THRESHOLD_float32_t 95
|
||||
#define FAST_MATH_SNR_THRESHOLD_q31_t 95
|
||||
#define FAST_MATH_SNR_THRESHOLD_q15_t 45
|
||||
|
||||
/**
|
||||
* Compare the outputs from the function under test and the reference
|
||||
* function using SNR.
|
||||
*/
|
||||
#define FAST_MATH_SNR_COMPARE_INTERFACE(block_size, \
|
||||
output_type) \
|
||||
do \
|
||||
{ \
|
||||
TEST_CONVERT_AND_ASSERT_SNR( \
|
||||
fast_math_output_f32_ref, \
|
||||
(output_type *) fast_math_output_ref, \
|
||||
fast_math_output_f32_fut, \
|
||||
(output_type *) fast_math_output_fut, \
|
||||
block_size, \
|
||||
output_type, \
|
||||
FAST_MATH_SNR_THRESHOLD_##output_type \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* TEST Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#define SQRT_TEST_TEMPLATE_ELT1(suffix) \
|
||||
\
|
||||
JTEST_DEFINE_TEST(arm_sqrt_##suffix##_test, arm_sqrt_##suffix) \
|
||||
{ \
|
||||
uint32_t i; \
|
||||
\
|
||||
JTEST_COUNT_CYCLES( \
|
||||
for(i=0;i<FAST_MATH_MAX_LEN;i++) \
|
||||
{ \
|
||||
arm_sqrt_##suffix( \
|
||||
(suffix##_t)fast_math_##suffix##_inputs[i] \
|
||||
,(suffix##_t*)fast_math_output_fut + i); \
|
||||
}); \
|
||||
\
|
||||
for(i=0;i<FAST_MATH_MAX_LEN;i++) \
|
||||
{ \
|
||||
ref_sqrt_##suffix( \
|
||||
(suffix##_t)fast_math_##suffix##_inputs[i] \
|
||||
,(suffix##_t*)fast_math_output_ref + i); \
|
||||
} \
|
||||
\
|
||||
FAST_MATH_SNR_COMPARE_INTERFACE( \
|
||||
FAST_MATH_MAX_LEN, \
|
||||
suffix##_t); \
|
||||
\
|
||||
return JTEST_TEST_PASSED; \
|
||||
}
|
||||
|
||||
|
||||
#define SIN_COS_TEST_TEMPLATE_ELT1(suffix, type, func) \
|
||||
\
|
||||
JTEST_DEFINE_TEST(arm_##func##_##suffix##_test, arm_##func##_##suffix) \
|
||||
{ \
|
||||
uint32_t i; \
|
||||
\
|
||||
JTEST_COUNT_CYCLES( \
|
||||
for(i=0;i<FAST_MATH_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((type*)fast_math_output_fut + i) = arm_##func##_##suffix( \
|
||||
fast_math_##suffix##_inputs[i]); \
|
||||
}); \
|
||||
\
|
||||
JTEST_COUNT_CYCLES( \
|
||||
for(i=0;i<FAST_MATH_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((type*)fast_math_output_ref + i) = ref_##func##_##suffix( \
|
||||
fast_math_##suffix##_inputs[i]); \
|
||||
}); \
|
||||
\
|
||||
FAST_MATH_SNR_COMPARE_INTERFACE( \
|
||||
FAST_MATH_MAX_LEN, \
|
||||
type); \
|
||||
\
|
||||
return JTEST_TEST_PASSED; \
|
||||
}
|
||||
|
||||
#endif /* _FAST_MATH_TEMPLATES_H_ */
|
@ -0,0 +1,29 @@
|
||||
#ifndef _FAST_MATH_TEST_DATA_H_
|
||||
#define _FAST_MATH_TEST_DATA_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#define FAST_MATH_MAX_LEN 1024
|
||||
#define TRANFORM_BIGGEST_INPUT_TYPE float32_t
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Variable Declarations */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
extern float32_t fast_math_output_fut[FAST_MATH_MAX_LEN];
|
||||
extern float32_t fast_math_output_ref[FAST_MATH_MAX_LEN];
|
||||
extern float32_t fast_math_output_f32_fut[FAST_MATH_MAX_LEN];
|
||||
extern float32_t fast_math_output_f32_ref[FAST_MATH_MAX_LEN];
|
||||
extern const float32_t fast_math_f32_inputs[FAST_MATH_MAX_LEN];
|
||||
extern const q31_t fast_math_q31_inputs[FAST_MATH_MAX_LEN];
|
||||
extern const q15_t * fast_math_q15_inputs;
|
||||
|
||||
#endif /* _FAST_MATH_TEST_DATA_H_ */
|
@ -0,0 +1,9 @@
|
||||
#ifndef _FAST_MATH_TEST_GROUP_H_
|
||||
#define _FAST_MATH_TEST_GROUP_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Test Groups */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(fast_math_tests);
|
||||
|
||||
#endif /* _FAST_MATH_TEST_GROUP_H_ */
|
@ -0,0 +1,91 @@
|
||||
#ifndef _FILTERING_TEMPLATES_H_
|
||||
#define _FILTERING_TEMPLATES_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
#include "test_templates.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Group Specific Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Comparison SNR thresholds for the data types used in statistics_tests.
|
||||
*/
|
||||
#define FILTERING_SNR_THRESHOLD_float64_t 120
|
||||
#define FILTERING_SNR_THRESHOLD_float32_t 99
|
||||
#define FILTERING_SNR_THRESHOLD_q31_t 90
|
||||
#define FILTERING_SNR_THRESHOLD_q15_t 60
|
||||
#define FILTERING_SNR_THRESHOLD_q7_t 30
|
||||
|
||||
/**
|
||||
* Compare reference and fut outputs using SNR.
|
||||
*
|
||||
* @note The outputs are converted to float32_t before comparison.
|
||||
*/
|
||||
#define FILTERING_SNR_COMPARE_INTERFACE(block_size, \
|
||||
output_type) \
|
||||
FILTERING_SNR_COMPARE_INTERFACE_OFFSET(0, block_size, output_type)
|
||||
|
||||
/**
|
||||
* Compare reference and fut outputs starting at some offset using SNR.
|
||||
*/
|
||||
#define FILTERING_SNR_COMPARE_INTERFACE_OFFSET(offset, \
|
||||
block_size, \
|
||||
output_type) \
|
||||
do \
|
||||
{ \
|
||||
TEST_CONVERT_AND_ASSERT_SNR( \
|
||||
filtering_output_f32_ref, \
|
||||
(output_type *) filtering_output_ref + offset, \
|
||||
filtering_output_f32_fut, \
|
||||
(output_type *) filtering_output_fut + offset, \
|
||||
block_size, \
|
||||
output_type, \
|
||||
FILTERING_SNR_THRESHOLD_##output_type \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* Compare reference and fut outputs starting at some offset using SNR.
|
||||
* Special case for float64_t
|
||||
*/
|
||||
#define FILTERING_DBL_SNR_COMPARE_INTERFACE(block_size, \
|
||||
output_type) \
|
||||
do \
|
||||
{ \
|
||||
TEST_ASSERT_DBL_SNR( \
|
||||
(float64_t*)filtering_output_ref, \
|
||||
(float64_t*)filtering_output_fut, \
|
||||
block_size, \
|
||||
FILTERING_SNR_THRESHOLD_##output_type \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Input Interfaces */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/*
|
||||
* General:
|
||||
* Input interfaces provide inputs to functions inside test templates. They
|
||||
* ONLY provide the inputs. The output variables should be hard coded.
|
||||
*
|
||||
* The input interfaces must have the following format:
|
||||
*
|
||||
* ARM_xxx_INPUT_INTERFACE() or
|
||||
* REF_xxx_INPUT_INTERFACE()
|
||||
*
|
||||
* The xxx must be lowercase, and is intended to be the indentifying substring
|
||||
* in the function's name. Acceptable values are 'sub' or 'add' from the
|
||||
* functions arm_add_q31.
|
||||
*/
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Test Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#endif /* _FILTERING_TEMPLATES_H_ */
|
@ -0,0 +1,81 @@
|
||||
#ifndef FILTERING_TEST_DATA_H
|
||||
#define FILTERING_TEST_DATA_H
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "arr_desc.h"
|
||||
#include "arm_math.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#define FILTERING_MAX_BLOCKSIZE 33
|
||||
#define LMS_MAX_BLOCKSIZE 512
|
||||
#define FILTERING_MAX_NUMTAPS 34
|
||||
#define FILTERING_MAX_NUMSTAGES 14
|
||||
#define FILTERING_MAX_POSTSHIFT 8
|
||||
#define FILTERING_MAX_TAP_DELAY 0xFF
|
||||
#define FILTERING_MAX_L 3
|
||||
#define FILTERING_MAX_M 33
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Variables */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* Input/Output Buffers */
|
||||
extern float32_t filtering_output_fut[LMS_MAX_BLOCKSIZE*2];
|
||||
extern float32_t filtering_output_ref[LMS_MAX_BLOCKSIZE*2];
|
||||
extern float32_t filtering_output_f32_fut[LMS_MAX_BLOCKSIZE*2];
|
||||
extern float32_t filtering_output_f32_ref[LMS_MAX_BLOCKSIZE*2];
|
||||
extern float32_t filtering_input_lms[LMS_MAX_BLOCKSIZE*2];
|
||||
extern float32_t filtering_pState[LMS_MAX_BLOCKSIZE + FILTERING_MAX_NUMTAPS];
|
||||
extern float32_t filtering_scratch[FILTERING_MAX_BLOCKSIZE * 3];
|
||||
extern float32_t filtering_scratch2[FILTERING_MAX_BLOCKSIZE * 3];
|
||||
extern float32_t filtering_coeffs_lms[FILTERING_MAX_NUMTAPS];
|
||||
|
||||
extern const float64_t filtering_f64_inputs[FILTERING_MAX_BLOCKSIZE * FILTERING_MAX_M + FILTERING_MAX_NUMTAPS];
|
||||
extern const float32_t filtering_f32_inputs[FILTERING_MAX_BLOCKSIZE * FILTERING_MAX_M + FILTERING_MAX_NUMTAPS];
|
||||
extern const q31_t filtering_q31_inputs[FILTERING_MAX_BLOCKSIZE * FILTERING_MAX_M + FILTERING_MAX_NUMTAPS];
|
||||
extern const q15_t * filtering_q15_inputs;
|
||||
extern const q7_t * filtering_q7_inputs;
|
||||
|
||||
/* Block Sizes */
|
||||
ARR_DESC_DECLARE(filtering_blocksizes);
|
||||
ARR_DESC_DECLARE(lms_blocksizes);
|
||||
ARR_DESC_DECLARE(filtering_numtaps);
|
||||
ARR_DESC_DECLARE(filtering_numtaps2);
|
||||
ARR_DESC_DECLARE(filtering_postshifts);
|
||||
ARR_DESC_DECLARE(filtering_numstages);
|
||||
ARR_DESC_DECLARE(filtering_Ls);
|
||||
ARR_DESC_DECLARE(filtering_Ms);
|
||||
|
||||
/* Coefficient Lists */
|
||||
extern const float64_t filtering_coeffs_f64[FILTERING_MAX_NUMSTAGES * 6 + 2];
|
||||
extern const float64_t filtering_coeffs_b_f64[FILTERING_MAX_NUMSTAGES * 6 + 2];
|
||||
extern const float32_t filtering_coeffs_f32[FILTERING_MAX_NUMSTAGES * 6 + 2];
|
||||
extern const float32_t filtering_coeffs_b_f32[FILTERING_MAX_NUMSTAGES * 6 + 2];
|
||||
extern const float32_t *filtering_coeffs_c_f32;
|
||||
extern float32_t filtering_coeffs_lms_f32[FILTERING_MAX_NUMTAPS];
|
||||
extern const q31_t filtering_coeffs_q31[FILTERING_MAX_NUMSTAGES * 6 + 2];
|
||||
extern const q31_t *filtering_coeffs_b_q31;
|
||||
extern const q31_t *filtering_coeffs_c_q31;
|
||||
extern q31_t filtering_coeffs_lms_q31[FILTERING_MAX_NUMTAPS];
|
||||
extern const q15_t filtering_coeffs_q15[FILTERING_MAX_NUMSTAGES * 6 + 4];
|
||||
extern const q15_t *filtering_coeffs_b_q15;
|
||||
extern const q15_t *filtering_coeffs_c_q15;
|
||||
extern q15_t filtering_coeffs_lms_q15[FILTERING_MAX_NUMTAPS];
|
||||
extern const q7_t filtering_coeffs_q7[FILTERING_MAX_NUMSTAGES * 6 + 8];
|
||||
extern const q7_t *filtering_coeffs_b_q7;
|
||||
extern const q7_t *filtering_coeffs_c_q7;
|
||||
|
||||
/* Tap Delay Lists */
|
||||
extern const int32_t filtering_tap_delay[FILTERING_MAX_NUMTAPS];
|
||||
|
||||
/* Numbers */
|
||||
|
||||
/* Float Inputs */
|
||||
|
||||
#endif
|
@ -0,0 +1,9 @@
|
||||
#ifndef _FILTERING_TEST_GROUP_H_
|
||||
#define _FILTERING_TEST_GROUP_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Test Groups */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(filtering_tests);
|
||||
|
||||
#endif /* _FILTERING_TEST_GROUP_H_ */
|
@ -0,0 +1,15 @@
|
||||
#ifndef _FILTERING_TESTS_H_
|
||||
#define _FILTERING_TESTS_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Test/Group Declarations */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
JTEST_DECLARE_GROUP(biquad_tests);
|
||||
JTEST_DECLARE_GROUP(conv_tests);
|
||||
JTEST_DECLARE_GROUP(correlate_tests);
|
||||
JTEST_DECLARE_GROUP(fir_tests);
|
||||
JTEST_DECLARE_GROUP(iir_tests);
|
||||
JTEST_DECLARE_GROUP(lms_tests);
|
||||
|
||||
#endif /* _FILTERING_TESTS_H_ */
|
@ -0,0 +1,166 @@
|
||||
#ifndef _INTRINSICS_TEMPLATES_H_
|
||||
#define _INTRINSICS_TEMPLATES_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "test_templates.h"
|
||||
#include <string.h> /* memcpy() */
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Group Specific Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Comparison SNR thresholds for the data types used in transform_tests.
|
||||
*/
|
||||
#define INTRINSICS_SNR_THRESHOLD_q63_t 120
|
||||
#define INTRINSICS_SNR_THRESHOLD_q31_t 95
|
||||
|
||||
/**
|
||||
* Compare the outputs from the function under test and the reference
|
||||
* function using SNR.
|
||||
*/
|
||||
#define INTRINSICS_SNR_COMPARE_INTERFACE(block_size, \
|
||||
output_type) \
|
||||
do \
|
||||
{ \
|
||||
TEST_CONVERT_AND_ASSERT_SNR( \
|
||||
intrinsics_output_f32_ref, \
|
||||
(output_type##_t *) intrinsics_output_ref, \
|
||||
intrinsics_output_f32_fut, \
|
||||
(output_type##_t *) intrinsics_output_fut, \
|
||||
block_size, \
|
||||
output_type, \
|
||||
INTRINSICS_SNR_THRESHOLD_##output_type##_t \
|
||||
); \
|
||||
} while (0)
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* TEST Templates */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#define INTRINSICS_TEST_TEMPLATE_ELT1(functionName, dataType) \
|
||||
\
|
||||
JTEST_DEFINE_TEST(functionName##_test, functionName) \
|
||||
{ \
|
||||
uint32_t i; \
|
||||
\
|
||||
JTEST_COUNT_CYCLES( \
|
||||
for(i=0;i<INTRINSICS_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((dataType##_t*)intrinsics_output_fut + i) = \
|
||||
functionName( \
|
||||
(dataType##_t)intrinsics_##dataType##_inputs[i]); \
|
||||
}); \
|
||||
\
|
||||
for(i=0;i<INTRINSICS_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((dataType##_t*)intrinsics_output_ref + i) = \
|
||||
ref##functionName( \
|
||||
(dataType##_t)intrinsics_##dataType##_inputs[i]); \
|
||||
} \
|
||||
\
|
||||
INTRINSICS_SNR_COMPARE_INTERFACE( \
|
||||
INTRINSICS_MAX_LEN, \
|
||||
dataType); \
|
||||
\
|
||||
return JTEST_TEST_PASSED; \
|
||||
}
|
||||
|
||||
#define INTRINSICS_TEST_TEMPLATE_ELT2(functionName, dataType) \
|
||||
\
|
||||
JTEST_DEFINE_TEST(functionName##_test, functionName) \
|
||||
{ \
|
||||
uint32_t i; \
|
||||
\
|
||||
JTEST_COUNT_CYCLES( \
|
||||
for(i=0;i<INTRINSICS_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((dataType##_t*)intrinsics_output_fut + i) = \
|
||||
functionName( \
|
||||
(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType##_t)intrinsics_##dataType##_inputs[i]); \
|
||||
}); \
|
||||
\
|
||||
for(i=0;i<INTRINSICS_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((dataType##_t*)intrinsics_output_ref + i) = \
|
||||
ref##functionName( \
|
||||
(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType##_t)intrinsics_##dataType##_inputs[i]); \
|
||||
} \
|
||||
\
|
||||
INTRINSICS_SNR_COMPARE_INTERFACE( \
|
||||
INTRINSICS_MAX_LEN, \
|
||||
dataType); \
|
||||
\
|
||||
return JTEST_TEST_PASSED; \
|
||||
}
|
||||
|
||||
#define INTRINSICS_TEST_TEMPLATE_ELT3(functionName, dataType) \
|
||||
\
|
||||
JTEST_DEFINE_TEST(functionName##_test, functionName) \
|
||||
{ \
|
||||
uint32_t i; \
|
||||
\
|
||||
JTEST_COUNT_CYCLES( \
|
||||
for(i=0;i<INTRINSICS_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((dataType##_t*)intrinsics_output_fut + i) = \
|
||||
functionName( \
|
||||
(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType##_t)intrinsics_##dataType##_inputs[i]); \
|
||||
}); \
|
||||
\
|
||||
for(i=0;i<INTRINSICS_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((dataType##_t*)intrinsics_output_ref + i) = \
|
||||
ref##functionName( \
|
||||
(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType##_t)intrinsics_##dataType##_inputs[i]); \
|
||||
} \
|
||||
\
|
||||
INTRINSICS_SNR_COMPARE_INTERFACE( \
|
||||
INTRINSICS_MAX_LEN, \
|
||||
dataType); \
|
||||
\
|
||||
return JTEST_TEST_PASSED; \
|
||||
}
|
||||
|
||||
#define INTRINSICS_TEST_TEMPLATE_ELT4(functionName, dataType, dataType2) \
|
||||
JTEST_DEFINE_TEST(functionName##_test, functionName) \
|
||||
{ \
|
||||
uint32_t i; \
|
||||
\
|
||||
JTEST_COUNT_CYCLES( \
|
||||
for(i=0;i<INTRINSICS_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((dataType2##_t*)intrinsics_output_fut + i) = \
|
||||
functionName( \
|
||||
(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType2##_t)intrinsics_##dataType2##_inputs[i]); \
|
||||
}); \
|
||||
\
|
||||
for(i=0;i<INTRINSICS_MAX_LEN;i++) \
|
||||
{ \
|
||||
*((dataType2##_t*)intrinsics_output_ref + i) = \
|
||||
ref##functionName( \
|
||||
(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType##_t)intrinsics_##dataType##_inputs[i] \
|
||||
,(dataType2##_t)intrinsics_##dataType2##_inputs[i]); \
|
||||
} \
|
||||
\
|
||||
INTRINSICS_SNR_COMPARE_INTERFACE( \
|
||||
INTRINSICS_MAX_LEN, \
|
||||
dataType2); \
|
||||
\
|
||||
return JTEST_TEST_PASSED; \
|
||||
}
|
||||
|
||||
#endif /* _INTRINSICS_TEMPLATES_H_ */
|
@ -0,0 +1,27 @@
|
||||
#ifndef _INTRINSICS_TEST_DATA_H_
|
||||
#define _INTRINSICS_TEST_DATA_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Includes */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Macros and Defines */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
#define INTRINSICS_MAX_LEN 1024
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Variable Declarations */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
extern q63_t intrinsics_output_fut[INTRINSICS_MAX_LEN];
|
||||
extern q63_t intrinsics_output_ref[INTRINSICS_MAX_LEN];
|
||||
extern float32_t intrinsics_output_f32_fut[INTRINSICS_MAX_LEN];
|
||||
extern float32_t intrinsics_output_f32_ref[INTRINSICS_MAX_LEN];
|
||||
extern const q63_t intrinsics_q63_inputs[INTRINSICS_MAX_LEN];
|
||||
extern const q31_t *intrinsics_q31_inputs;
|
||||
|
||||
#endif /* _INTRINSICS_TEST_DATA_H_ */
|
@ -0,0 +1,9 @@
|
||||
#ifndef _INTRINSICS_TEST_GROUP_H_
|
||||
#define _INTRINSICS_TEST_GROUP_H_
|
||||
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
/* Declare Test Groups */
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
JTEST_DECLARE_GROUP(intrinsics_tests);
|
||||
|
||||
#endif /* _INTRINSICS_TEST_GROUP_H_ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user