Migrated to a new HAL version; FW now works; Adress is 38, board type is 12

This commit is contained in:
Anton Mukhin
2024-07-25 16:25:03 +03:00
parent 7da825917f
commit 07be2f747f
12 changed files with 4757 additions and 16 deletions

File diff suppressed because one or more lines are too long

66
Core/Inc/board_logic.h Normal file
View File

@@ -0,0 +1,66 @@
/*
* board_logic.h
*
* Created on: Jul 25, 2024
* Author: User
*/
#ifndef INC_BOARD_LOGIC_H_
#define INC_BOARD_LOGIC_H_
#define MODBUS_FIRMWARE_VERSION ( /*major*/ 10 + /*minor*/ 0 * 0x100)
#define MODBUS_BOARD_TYPE (12) //BSV Module board ID
#define HVS_U_LIMIT 30.0 //[kV]
#define HVS_I_LIMIT 11500 //[uA]
#define K_ADC_CURRENT 0.272
#define K_ADC_VOLTAGE 124.666
#define K_ADC_15V 160.0 // Really should be 161.8972 (but 160 gives a number closer to reality)
#define K_ADC_24V 111.0 // Really should be 112.8193 (but 111 gives a number closer to reality)
#define K_DAC_CURRENT 0.302
#define K_DAC_VOLTAGE 124.533
#define CONF_BIT_HVS_EN (1u<<0)
// ADC channels
#define ADC_CH_VOLTAGE 6
#define ADC_CH_CURRENT 7
#define ADC_CH_15V 14
#define ADC_CH_24V 15
#define ADC_BUFF_LENGTH 20 // ADC buffer length (to smooth the result). 1 per ms
// PIN macros
#define GET_HVS_ENABLE (HAL_GPIO_ReadPin(HVS_ENABLE_GPIO_Port, HVS_ENABLE_Pin) == GPIO_PIN_SET)
#define GET_HVS_CONN (HAL_GPIO_ReadPin(HVS_CONN_GPIO_Port, HVS_CONN_Pin) == GPIO_PIN_RESET)
#define GET_HVS_READY (HAL_GPIO_ReadPin(HVS_READY_GPIO_Port, HVS_READY_Pin) == GPIO_PIN_SET)
#define GET_HVS_XRAYON (HAL_GPIO_ReadPin(HVS_XRAYON_GPIO_Port, HVS_XRAYON_Pin) == GPIO_PIN_SET)
#define GET_HVS_NOLINK (HAL_GPIO_ReadPin(HVS_NOLINK_GPIO_Port, HVS_NOLINK_Pin) == GPIO_PIN_SET)
#define GET_HVS_OVERHEAT (HAL_GPIO_ReadPin(HVS_OVERHEAT_GPIO_Port, HVS_OVERHEAT_Pin) == GPIO_PIN_SET)
#define GET_HVS_OVERLOAD (HAL_GPIO_ReadPin(HVS_OVERLOAD_GPIO_Port, HVS_OVERLOAD_Pin) == GPIO_PIN_SET)
#define SET_HVS_ON HAL_GPIO_WritePin(HVS_ENABLE_GPIO_Port, HVS_ENABLE_Pin, GPIO_PIN_SET)
#define SET_HVS_OFF HAL_GPIO_WritePin(HVS_ENABLE_GPIO_Port, HVS_ENABLE_Pin, GPIO_PIN_RESET)
typedef struct hvs_t {
float voltage; //[kV]
float current; //[uA]
float v_24; //[V]
float v_15; //[V]
float set_voltage; //[kV]
float set_current; //[uA]
uint8_t update_voltage_flag; //Need update voltage DAC flag
uint8_t update_current_flag; //Need update current DAC flag
} hvs_t;
void board_init(void);
void loop_iterate();
void update_service_indication(void);
#endif /* INC_BOARD_LOGIC_H_ */

37
Core/Inc/modbus_logic.h Normal file
View File

@@ -0,0 +1,37 @@
/*
* modbus_logic.h
*
* Created on: Jul 25, 2024
* Author: User
*/
#ifndef INC_MODBUS_LOGIC_H_
#define INC_MODBUS_LOGIC_H_
#include <stdint.h>
#define BOARD_ADRESS 38 //BSV Module 1
//#define BOARD_ADRESS 39 //BSV Module 2
#define BUS_IDLE_TIME 3
#define MODBUS_PROTOCOL_VERSION (1)
#define MODBUS_HEADER_SIZE (13)
#define BUFFERS_SIZE (100 + 9)
#define MAX_REGS_PER_QUERY (32)
#define ADDRESS_UNDEFINED (0xff)
enum recv_state {RECV_IDLE, RECV_READ_HEADER, RECV_READ_DATA, RECV_READ_COMPLETE, RECV_ERROR};
enum send_state {SEND_IDLE, SEND_BUSY};
#define TXEN_ON HAL_GPIO_WritePin(TXEN_GPIO_Port, TXEN_Pin, GPIO_PIN_SET)
#define TXEN_OFF HAL_GPIO_WritePin(TXEN_GPIO_Port, TXEN_Pin, GPIO_PIN_RESET)
void UART_RxCpltCallback(void);
void UART_TxCpltCallback(void);
void process_incoming_packet();
void modbus_loop_iterate();
uint8_t read_register(uint16_t address, uint16_t* value);
uint8_t write_register(uint16_t address, uint16_t value);
#endif /* INC_MODBUS_LOGIC_H_ */

View File

@@ -64,7 +64,7 @@
/*#define HAL_SMARTCARD_MODULE_ENABLED */ /*#define HAL_SMARTCARD_MODULE_ENABLED */
/*#define HAL_SPI_MODULE_ENABLED */ /*#define HAL_SPI_MODULE_ENABLED */
/*#define HAL_SRAM_MODULE_ENABLED */ /*#define HAL_SRAM_MODULE_ENABLED */
/*#define HAL_TIM_MODULE_ENABLED */ #define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED #define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */ /*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */ /*#define HAL_WWDG_MODULE_ENABLED */

View File

@@ -55,9 +55,11 @@ void SVC_Handler(void);
void DebugMon_Handler(void); void DebugMon_Handler(void);
void PendSV_Handler(void); void PendSV_Handler(void);
void SysTick_Handler(void); void SysTick_Handler(void);
void DMA1_Channel1_IRQHandler(void);
void DMA1_Channel4_IRQHandler(void); void DMA1_Channel4_IRQHandler(void);
void DMA1_Channel5_IRQHandler(void); void DMA1_Channel5_IRQHandler(void);
void USART1_IRQHandler(void); void USART1_IRQHandler(void);
void TIM6_IRQHandler(void);
/* USER CODE BEGIN EFP */ /* USER CODE BEGIN EFP */
/* USER CODE END EFP */ /* USER CODE END EFP */

262
Core/Src/board_logic.c Normal file
View File

@@ -0,0 +1,262 @@
/*
* board_logic.c
*
* Created on: Jul 25, 2024
* Author: User
*/
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "main.h"
#include "modbus_logic.h"
#include "board_logic.h"
#define BOARD_DESC_LEN (14)
static const char board_description[BOARD_DESC_LEN] = "RS485_BSV V1R1";
extern uint16_t tranfer_errors_count;
extern TIM_HandleTypeDef htim6;
extern ADC_HandleTypeDef hadc1;
extern DAC_HandleTypeDef hdac;
#define LED_ACT_ON HAL_GPIO_WritePin(LED_ACT_GPIO_Port, LED_ACT_Pin, GPIO_PIN_SET)
#define LED_ACT_OFF HAL_GPIO_WritePin(LED_ACT_GPIO_Port, LED_ACT_Pin, GPIO_PIN_RESET)
hvs_t hvs = {0};
// Time for LED_ACT to be on
uint16_t led_time_act = 0;
// Raw ADC values buffer (circular DMA)
uint32_t rawADC[4] = {0};
// ADC Buffers
uint16_t volt_buff[ADC_BUFF_LENGTH] = {0};
uint16_t curr_buff[ADC_BUFF_LENGTH] = {0};
uint8_t buff_index = 0;
uint16_t config = 0;
uint16_t config_new = 0;
uint8_t config_update_flag = 0;
uint8_t adc_sum_flag = 0;
void board_init(void) {
// ADC
HAL_ADCEx_Calibration_Start(&hadc1);
HAL_ADC_Start_DMA(&hadc1, rawADC, 4);
// DAC
HAL_DAC_Start(&hdac, DAC_CHANNEL_1);
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, 0);
HAL_DAC_Start(&hdac, DAC_CHANNEL_2);
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, 0);
// 1ms timer start
HAL_TIM_Base_Start_IT(&htim6);
}
void loop_iterate() {
if(hvs.update_voltage_flag) {
uint32_t value = (uint32_t)(hvs.set_voltage*K_DAC_VOLTAGE);
if(value > 4095) value = 4095;
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_1, DAC_ALIGN_12B_R, value);
hvs.update_voltage_flag = 0;
}
if(hvs.update_current_flag)
{
uint32_t value = (uint32_t)(hvs.set_current*K_DAC_CURRENT);
if(value > 4095) value = 4095;
HAL_DAC_SetValue(&hdac, DAC_CHANNEL_2, DAC_ALIGN_12B_R, value);
hvs.update_current_flag = 0;
}
if(config_update_flag) {
// HVS ON
if((config^config_new) & CONF_BIT_HVS_EN) {
if(config_new & CONF_BIT_HVS_EN) SET_HVS_ON;
else SET_HVS_OFF;
}
config = config_new;
config_update_flag = 0;
}
// Time to calculate ADC results
if (adc_sum_flag) {
uint32_t volt_sum = 0, curr_sum = 0;
for (uint8_t i = 0; i < ADC_BUFF_LENGTH; i++) {
volt_sum += volt_buff[i];
curr_sum += curr_buff[i];
}
volt_sum = volt_sum / ADC_BUFF_LENGTH;
curr_sum = curr_sum / ADC_BUFF_LENGTH;
hvs.voltage = (float)volt_sum / K_ADC_VOLTAGE;
hvs.current = (float)curr_sum / K_ADC_CURRENT;
hvs.v_15 = (float)rawADC[2] / K_ADC_15V;
hvs.v_24 = (float)rawADC[3] / K_ADC_24V;
adc_sum_flag = 0;
}
/* */
modbus_loop_iterate();
HAL_Delay(1);
}
void update_service_indication(void) {
if (led_time_act) {
LED_ACT_ON;
led_time_act--;
} else
LED_ACT_OFF;
}
uint16_t update_status(void) {
uint16_t s = 0;
if(GET_HVS_CONN) {
// 0 - COVER OPEN - Xray board
// 1 - GLASS OPEN - Xray board
// 2 - NO WATER - Xray board
// 3 - JP1 - Xray board
// 4 - JP2 - Xray board
// 5 - was reserved but now it is Connection flag:
s |= (1u<<5);
if(GET_HVS_ENABLE) s |= (1u<<6);
if(GET_HVS_READY) s |= (1u<<7);
if(GET_HVS_XRAYON) s |= (1u<<8);
if(GET_HVS_NOLINK) s |= (1u<<9);
if(GET_HVS_OVERHEAT) s |= (1u<<10);
if(GET_HVS_OVERLOAD) s |= (1u<<11);
//12 - reserved
//13 - THERMSW - Xray board
//14 - SHTR_OPTO - Xray board
}
return s;
}
void adc_bufferize(void) {
volt_buff[buff_index] = rawADC[0];
curr_buff[buff_index] = rawADC[1];
if (++buff_index >= ADC_BUFF_LENGTH) {
buff_index = 0;
adc_sum_flag = 1;
}
}
uint8_t read_register(uint16_t address, uint16_t* value)
{
if (address == 0x0001)
*value = MODBUS_PROTOCOL_VERSION;
else if (address == 0x0002)
*value = MODBUS_FIRMWARE_VERSION;
else if (address == 0x0003)
*value = MODBUS_BOARD_TYPE;
else if (address == 0x0004)
*value = tranfer_errors_count;
else if (address == 0x0005)
*value = 0; // supported data rate: unknown
else if (address >= 0x0010 && address <= 0x0099) {
int index = address - 0x0010;
if (index < BOARD_DESC_LEN)
*value = board_description[index];
else
*value = 0;
}
else if (address == 0x2001) { //Read status
*value = update_status();
}
else if (address == 0x2002) { //Read config
*value = config;
}
else if (address == 0x2010) { //Read tube voltage set
*value = ceil(hvs.set_voltage*100);
}
else if (address == 0x2011) { //Read tube current set
*value = ceil(hvs.set_current);
}
else if (address == 0x2012) { //Read tube voltage
if (GET_HVS_CONN)
*value = ceil(hvs.voltage*100);
else
*value = 0;
}
else if (address == 0x2013) { //Read tube current
if (GET_HVS_CONN)
*value = ceil(hvs.current);
else
*value = 0;
}
else if (address == 0x2014) { //Read 24V supply voltage
if (GET_HVS_CONN)
*value = ceil(hvs.v_24*100);
else
*value = 0;
}
else if (address == 0x2015) { //Read 15V supply voltage
if (GET_HVS_CONN)
*value = ceil(hvs.v_15*100);
else
*value = 0;
}
else
return 1;
return 0;
}
uint8_t write_register(uint16_t address, uint16_t value)
{
uint8_t ret = 0;
#ifdef UART_DEBUG
printf("Write A=0x%X D=0x%X\n\r",address,value);
#endif
switch (address) {
case 0x2002: //Write config
config_new = value;
config_update_flag = 1;
break;
case 0x2010: //Voltage set
hvs.set_voltage = (float)value/100;
if (hvs.set_voltage > HVS_U_LIMIT) hvs.set_voltage = HVS_U_LIMIT;
hvs.update_voltage_flag = 1;
break;
case 0x2011: //Current set
hvs.set_current = (float)value;
if (hvs.set_current > HVS_I_LIMIT) hvs.set_current = HVS_I_LIMIT;
hvs.update_current_flag = 1;
break;
default:
ret = 1;
}
return ret;
}
// Timers overflow interrupt
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
// check if the interrupt comes from TIM6 (1ms timer)
if(htim->Instance == TIM6) {
// ACT LED update
update_service_indication();
// bufferize the ADC values
adc_bufferize();
}
}

View File

@@ -21,7 +21,7 @@
/* Private includes ----------------------------------------------------------*/ /* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
#include "board_logic.h"
/* USER CODE END Includes */ /* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/
@@ -41,15 +41,20 @@
/* Private variables ---------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1; ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;
DAC_HandleTypeDef hdac; DAC_HandleTypeDef hdac;
TIM_HandleTypeDef htim6;
UART_HandleTypeDef huart1; UART_HandleTypeDef huart1;
DMA_HandleTypeDef hdma_usart1_rx; DMA_HandleTypeDef hdma_usart1_rx;
DMA_HandleTypeDef hdma_usart1_tx; DMA_HandleTypeDef hdma_usart1_tx;
/* USER CODE BEGIN PV */ /* USER CODE BEGIN PV */
// TIM6 - basic 1ms timer
/* USER CODE END PV */ /* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/ /* Private function prototypes -----------------------------------------------*/
@@ -59,6 +64,7 @@ static void MX_DMA_Init(void);
static void MX_USART1_UART_Init(void); static void MX_USART1_UART_Init(void);
static void MX_DAC_Init(void); static void MX_DAC_Init(void);
static void MX_ADC1_Init(void); static void MX_ADC1_Init(void);
static void MX_TIM6_Init(void);
/* USER CODE BEGIN PFP */ /* USER CODE BEGIN PFP */
/* USER CODE END PFP */ /* USER CODE END PFP */
@@ -101,8 +107,11 @@ int main(void)
MX_USART1_UART_Init(); MX_USART1_UART_Init();
MX_DAC_Init(); MX_DAC_Init();
MX_ADC1_Init(); MX_ADC1_Init();
MX_TIM6_Init();
/* USER CODE BEGIN 2 */ /* USER CODE BEGIN 2 */
board_init();
/* USER CODE END 2 */ /* USER CODE END 2 */
/* Infinite loop */ /* Infinite loop */
@@ -112,6 +121,8 @@ int main(void)
/* USER CODE END WHILE */ /* USER CODE END WHILE */
/* USER CODE BEGIN 3 */ /* USER CODE BEGIN 3 */
loop_iterate();
} }
/* USER CODE END 3 */ /* USER CODE END 3 */
} }
@@ -187,12 +198,12 @@ static void MX_ADC1_Init(void)
/** Common config /** Common config
*/ */
hadc1.Instance = ADC1; hadc1.Instance = ADC1;
hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
hadc1.Init.ContinuousConvMode = DISABLE; hadc1.Init.ContinuousConvMode = ENABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE; hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1; hadc1.Init.NbrOfConversion = 4;
if (HAL_ADC_Init(&hadc1) != HAL_OK) if (HAL_ADC_Init(&hadc1) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
@@ -202,7 +213,34 @@ static void MX_ADC1_Init(void)
*/ */
sConfig.Channel = ADC_CHANNEL_6; sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = ADC_REGULAR_RANK_2;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_14;
sConfig.Rank = ADC_REGULAR_RANK_3;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
/** Configure Regular Channel
*/
sConfig.Channel = ADC_CHANNEL_15;
sConfig.Rank = ADC_REGULAR_RANK_4;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK) if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{ {
Error_Handler(); Error_Handler();
@@ -260,6 +298,44 @@ static void MX_DAC_Init(void)
} }
/**
* @brief TIM6 Initialization Function
* @param None
* @retval None
*/
static void MX_TIM6_Init(void)
{
/* USER CODE BEGIN TIM6_Init 0 */
/* USER CODE END TIM6_Init 0 */
TIM_MasterConfigTypeDef sMasterConfig = {0};
/* USER CODE BEGIN TIM6_Init 1 */
/* USER CODE END TIM6_Init 1 */
htim6.Instance = TIM6;
htim6.Init.Prescaler = 72-1;
htim6.Init.CounterMode = TIM_COUNTERMODE_UP;
htim6.Init.Period = 1000-1;
htim6.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim6) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim6, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN TIM6_Init 2 */
/* USER CODE END TIM6_Init 2 */
}
/** /**
* @brief USART1 Initialization Function * @brief USART1 Initialization Function
* @param None * @param None
@@ -303,6 +379,9 @@ static void MX_DMA_Init(void)
__HAL_RCC_DMA1_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */ /* DMA interrupt init */
/* DMA1_Channel1_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
/* DMA1_Channel4_IRQn interrupt configuration */ /* DMA1_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0); HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn); HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);

269
Core/Src/modbus_logic.c Normal file
View File

@@ -0,0 +1,269 @@
/*
* modbus_logic.c
*
* Created on: Jul 25, 2024
* Author: User
*/
#include <stdint.h>
#include "main.h"
#include "modbus_logic.h"
extern UART_HandleTypeDef huart1;
extern DMA_HandleTypeDef hdma_usart1_rx;
uint8_t recv_buffer[BUFFERS_SIZE];
uint8_t send_buffer[BUFFERS_SIZE];
uint16_t bytes_to_send = 0;
//uint16_t last_rx_time = 0xFFFF;
enum recv_state cmd_receiving = RECV_IDLE;
enum send_state cmd_sending = SEND_IDLE;
uint16_t tranfer_errors_count;
extern uint16_t led_time_act;
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1)
{
if (recv_buffer[5] != BOARD_ADRESS)
{
cmd_receiving = RECV_ERROR;
return;
}
// Check function code
if (recv_buffer[6] == 3 || recv_buffer[6] == 4 || recv_buffer[6] == 6)
{
if(Size==MODBUS_HEADER_SIZE)cmd_receiving = RECV_READ_COMPLETE;
return;
}
else if (recv_buffer[6] == 0x10)
{
uint16_t pdu_size = *((uint16_t*)(recv_buffer + 2));
uint16_t remaining_size = pdu_size - (MODBUS_HEADER_SIZE - 4) + 2;
if (remaining_size + MODBUS_HEADER_SIZE == Size)
cmd_receiving = RECV_READ_COMPLETE;
else
{
cmd_receiving = RECV_ERROR;
tranfer_errors_count++;
}
return;
}
else
{
tranfer_errors_count++;
cmd_receiving = RECV_ERROR;
return;
}
}
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
cmd_sending = SEND_IDLE;
TXEN_OFF;
}
}
void modbus_loop_iterate()
{
if (cmd_sending == SEND_IDLE)
{
if (cmd_receiving == RECV_ERROR)
{
cmd_receiving = RECV_IDLE;
}
if (cmd_receiving == RECV_IDLE)
{
if(HAL_UARTEx_ReceiveToIdle_DMA(&huart1, recv_buffer, BUFFERS_SIZE)==HAL_OK)
{
cmd_receiving = RECV_READ_HEADER;
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
}
}
else if (cmd_receiving == RECV_READ_COMPLETE)
{
process_incoming_packet();
cmd_receiving = RECV_IDLE;
}
}
else if (cmd_sending == SEND_BUSY && bytes_to_send != 0)
{
TXEN_ON;
HAL_UART_Transmit_DMA(&huart1, send_buffer, bytes_to_send);
bytes_to_send = 0;
}
}
static uint16_t checksum(int size)
{
uint16_t index;
uint16_t checksum = 0;
for (index = 0; index < size; index++)
checksum += send_buffer[index];
return checksum;
}
void process_incoming_packet()
{
uint8_t source;
uint8_t dest;
uint8_t func_code;
uint16_t checksum_recv;
uint16_t transaction_id;
uint16_t pdu_size;
uint16_t checksum_real;
uint16_t response_pdu_length;
uint16_t address;
uint8_t write_result;
uint16_t size;
uint16_t i;
led_time_act=100;
dest = recv_buffer[5];
if(dest!=BOARD_ADRESS)return;
transaction_id = *((uint16_t*)(recv_buffer));
pdu_size = *((uint16_t*)(recv_buffer + 2));
if (pdu_size + 6 > BUFFERS_SIZE)
{
tranfer_errors_count++;
return;
}
source = recv_buffer[4];
func_code = recv_buffer[6];
//checksum_recv = *((uint16_t*)(recv_buffer + 4 + pdu_size));
checksum_recv = recv_buffer[4 + pdu_size];
checksum_recv += ((uint16_t)recv_buffer[5 + pdu_size])<<8;
checksum_real = 0;
for (i = 0; i < 4 + pdu_size; i++)
checksum_real += recv_buffer[i];
if (checksum_recv != checksum_real)
{
tranfer_errors_count++;
return;
}
// Prepare response header
*(uint16_t*)(send_buffer) = transaction_id;
send_buffer[4] = BOARD_ADRESS;
send_buffer[5] = source;
response_pdu_length = 0;
if ((func_code == 3 || func_code == 4) && pdu_size == 7) // Read holding/input registers
{
uint16_t start_address = *((uint16_t*)(recv_buffer + 7));
uint16_t quantity = *((uint16_t*)(recv_buffer + 9));
if (quantity > MAX_REGS_PER_QUERY)
{
tranfer_errors_count++;
return;
}
response_pdu_length = 2 * quantity + 1 + 3;
send_buffer[6] = func_code;
send_buffer[7] = 0; // bytes counter
for (address = start_address; address < start_address + quantity; address++)
{
uint16_t value;
uint8_t read_result = read_register(address, &value);
if (read_result != 0)
{
send_buffer[6] = func_code + 0x80;
send_buffer[7] = read_result;
response_pdu_length = 4;
break;
}
send_buffer[7] += 2;
*((uint16_t*)(&(send_buffer[8 + 2 * (address - start_address)]))) = value;
}
}
else if (func_code == 6 && pdu_size == 7) // Write holding register
{
uint16_t address = *((uint16_t*)(recv_buffer + 7));
uint16_t value = *((uint16_t*)(recv_buffer + 9));
response_pdu_length = 7;
send_buffer[6] = func_code;
write_result = write_register(address, value);
if (write_result == 0)
{
//*((uint16_t*)(send_buffer + 7)) = address;
send_buffer[7] = (uint8_t)(address&0x00FF);
send_buffer[8] = (uint8_t)((address&0xFF00)>>8);
//*((uint16_t*)(send_buffer + 9)) = value;
send_buffer[9] = (uint8_t)(value&0x00FF);
send_buffer[10] = (uint8_t)((value&0xFF00)>>8);
}
else
{
response_pdu_length = 4;
send_buffer[6] = 0x86;
send_buffer[7] = write_result;
}
}
else if (func_code == 0x10) // Write multiple registers
{
uint16_t start_address = *((uint16_t*)(recv_buffer + 7));
uint16_t quantity = *((uint16_t*)(recv_buffer + 9));
uint8_t byte_count = recv_buffer[11];
if (pdu_size != 3 + 5 + quantity * 2 || quantity * 2 != byte_count)
{
tranfer_errors_count++;
return;
}
response_pdu_length = 7;
send_buffer[6] = func_code;
//*((uint16_t*)(send_buffer + 7)) = start_address;
send_buffer[7] = (uint8_t)(start_address&0x00FF);
send_buffer[8] = (uint8_t)((start_address&0xFF00)>>8);
//*((uint16_t*)(send_buffer + 9)) = quantity;
send_buffer[9] = (uint8_t)(quantity&0x00FF);
send_buffer[10] = (uint8_t)((quantity&0xFF00)>>8);
for (address = start_address; address < start_address + quantity; address++)
{
uint16_t value = *((uint16_t*)(recv_buffer + 12u + 2u * (address - start_address)));
write_result = write_register(address, value);
if (write_result != 0)
{
response_pdu_length = 4;
send_buffer[6] = 0x90;
send_buffer[7] = write_result;
break;
}
}
}
else
{
tranfer_errors_count++;
return;
}
//*((uint16_t*)(send_buffer + 2)) = response_pdu_length;
send_buffer[2] = (uint8_t)(response_pdu_length&0x00FF);
send_buffer[3] = (uint8_t)((response_pdu_length&0xFF00)>>8);
size = 4 + response_pdu_length;
//*((uint16_t*)(send_buffer + size)) = checksum(size);
uint16_t s = checksum(size);
send_buffer[size] = (uint8_t)(s&0x00FF);
send_buffer[size+1] = (uint8_t)((s&0xFF00)>>8);
if (cmd_sending == SEND_IDLE)
{
bytes_to_send = size + 2;
cmd_sending = SEND_BUSY;
}
else
{
tranfer_errors_count++;
}
}

View File

@@ -1,3 +1,4 @@
/* USER CODE BEGIN Header */ /* USER CODE BEGIN Header */
/** /**
****************************************************************************** ******************************************************************************
@@ -23,6 +24,8 @@
/* USER CODE BEGIN Includes */ /* USER CODE BEGIN Includes */
/* USER CODE END Includes */ /* USER CODE END Includes */
extern DMA_HandleTypeDef hdma_adc1;
extern DMA_HandleTypeDef hdma_usart1_rx; extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx; extern DMA_HandleTypeDef hdma_usart1_tx;
@@ -117,9 +120,27 @@ void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* ADC1 DMA Init */
/* ADC1 Init */
hdma_adc1.Instance = DMA1_Channel1;
hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc1.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_adc1.Init.Mode = DMA_CIRCULAR;
hdma_adc1.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_adc1) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hadc,DMA_Handle,hdma_adc1);
/* USER CODE BEGIN ADC1_MspInit 1 */ /* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */ /* USER CODE END ADC1_MspInit 1 */
} }
} }
@@ -150,6 +171,8 @@ void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
HAL_GPIO_DeInit(GPIOC, HVS_15V_Pin|HVS_24V_Pin); HAL_GPIO_DeInit(GPIOC, HVS_15V_Pin|HVS_24V_Pin);
/* ADC1 DMA DeInit */
HAL_DMA_DeInit(hadc->DMA_Handle);
/* USER CODE BEGIN ADC1_MspDeInit 1 */ /* USER CODE BEGIN ADC1_MspDeInit 1 */
/* USER CODE END ADC1_MspDeInit 1 */ /* USER CODE END ADC1_MspDeInit 1 */
@@ -186,6 +209,7 @@ void HAL_DAC_MspInit(DAC_HandleTypeDef* hdac)
/* USER CODE BEGIN DAC_MspInit 1 */ /* USER CODE BEGIN DAC_MspInit 1 */
/* USER CODE END DAC_MspInit 1 */ /* USER CODE END DAC_MspInit 1 */
} }
} }
@@ -219,6 +243,57 @@ void HAL_DAC_MspDeInit(DAC_HandleTypeDef* hdac)
} }
/**
* @brief TIM_Base MSP Initialization
* This function configures the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM6)
{
/* USER CODE BEGIN TIM6_MspInit 0 */
/* USER CODE END TIM6_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM6_CLK_ENABLE();
/* TIM6 interrupt Init */
HAL_NVIC_SetPriority(TIM6_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TIM6_IRQn);
/* USER CODE BEGIN TIM6_MspInit 1 */
/* USER CODE END TIM6_MspInit 1 */
}
}
/**
* @brief TIM_Base MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM6)
{
/* USER CODE BEGIN TIM6_MspDeInit 0 */
/* USER CODE END TIM6_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM6_CLK_DISABLE();
/* TIM6 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM6_IRQn);
/* USER CODE BEGIN TIM6_MspDeInit 1 */
/* USER CODE END TIM6_MspDeInit 1 */
}
}
/** /**
* @brief UART MSP Initialization * @brief UART MSP Initialization
* This function configures the hardware resources used in this example * This function configures the hardware resources used in this example
@@ -292,6 +367,7 @@ void HAL_UART_MspInit(UART_HandleTypeDef* huart)
/* USER CODE BEGIN USART1_MspInit 1 */ /* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */ /* USER CODE END USART1_MspInit 1 */
} }
} }

View File

@@ -55,6 +55,8 @@
/* USER CODE END 0 */ /* USER CODE END 0 */
/* External variables --------------------------------------------------------*/ /* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_adc1;
extern TIM_HandleTypeDef htim6;
extern DMA_HandleTypeDef hdma_usart1_rx; extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx; extern DMA_HandleTypeDef hdma_usart1_tx;
extern UART_HandleTypeDef huart1; extern UART_HandleTypeDef huart1;
@@ -201,6 +203,20 @@ void SysTick_Handler(void)
/* please refer to the startup file (startup_stm32f1xx.s). */ /* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/ /******************************************************************************/
/**
* @brief This function handles DMA1 channel1 global interrupt.
*/
void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
/* USER CODE END DMA1_Channel1_IRQn 1 */
}
/** /**
* @brief This function handles DMA1 channel4 global interrupt. * @brief This function handles DMA1 channel4 global interrupt.
*/ */
@@ -243,6 +259,20 @@ void USART1_IRQHandler(void)
/* USER CODE END USART1_IRQn 1 */ /* USER CODE END USART1_IRQn 1 */
} }
/**
* @brief This function handles TIM6 global interrupt.
*/
void TIM6_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_IRQn 0 */
/* USER CODE END TIM6_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_IRQn 1 */
/* USER CODE END TIM6_IRQn 1 */
}
/* USER CODE BEGIN 1 */ /* USER CODE BEGIN 1 */
/* USER CODE END 1 */ /* USER CODE END 1 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,16 +1,37 @@
#MicroXplorer Configuration settings - do not modify #MicroXplorer Configuration settings - do not modify
ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_6 ADC1.Channel-0\#ChannelRegularConversion=ADC_CHANNEL_6
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,master ADC1.Channel-1\#ChannelRegularConversion=ADC_CHANNEL_7
ADC1.Channel-2\#ChannelRegularConversion=ADC_CHANNEL_14
ADC1.Channel-3\#ChannelRegularConversion=ADC_CHANNEL_15
ADC1.ContinuousConvMode=ENABLE
ADC1.IPParameters=Rank-0\#ChannelRegularConversion,Channel-0\#ChannelRegularConversion,SamplingTime-0\#ChannelRegularConversion,NbrOfConversionFlag,master,Rank-1\#ChannelRegularConversion,Channel-1\#ChannelRegularConversion,SamplingTime-1\#ChannelRegularConversion,Rank-2\#ChannelRegularConversion,Channel-2\#ChannelRegularConversion,SamplingTime-2\#ChannelRegularConversion,Rank-3\#ChannelRegularConversion,Channel-3\#ChannelRegularConversion,SamplingTime-3\#ChannelRegularConversion,NbrOfConversion,ContinuousConvMode
ADC1.NbrOfConversion=4
ADC1.NbrOfConversionFlag=1 ADC1.NbrOfConversionFlag=1
ADC1.Rank-0\#ChannelRegularConversion=1 ADC1.Rank-0\#ChannelRegularConversion=1
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_1CYCLE_5 ADC1.Rank-1\#ChannelRegularConversion=2
ADC1.Rank-2\#ChannelRegularConversion=3
ADC1.Rank-3\#ChannelRegularConversion=4
ADC1.SamplingTime-0\#ChannelRegularConversion=ADC_SAMPLETIME_71CYCLES_5
ADC1.SamplingTime-1\#ChannelRegularConversion=ADC_SAMPLETIME_71CYCLES_5
ADC1.SamplingTime-2\#ChannelRegularConversion=ADC_SAMPLETIME_71CYCLES_5
ADC1.SamplingTime-3\#ChannelRegularConversion=ADC_SAMPLETIME_71CYCLES_5
ADC1.master=1 ADC1.master=1
CAD.formats= CAD.formats=
CAD.pinconfig= CAD.pinconfig=
CAD.provider= CAD.provider=
Dma.ADC1.2.Direction=DMA_PERIPH_TO_MEMORY
Dma.ADC1.2.Instance=DMA1_Channel1
Dma.ADC1.2.MemDataAlignment=DMA_MDATAALIGN_WORD
Dma.ADC1.2.MemInc=DMA_MINC_ENABLE
Dma.ADC1.2.Mode=DMA_CIRCULAR
Dma.ADC1.2.PeriphDataAlignment=DMA_PDATAALIGN_WORD
Dma.ADC1.2.PeriphInc=DMA_PINC_DISABLE
Dma.ADC1.2.Priority=DMA_PRIORITY_LOW
Dma.ADC1.2.RequestParameters=Instance,Direction,PeriphInc,MemInc,PeriphDataAlignment,MemDataAlignment,Mode,Priority
Dma.Request0=USART1_RX Dma.Request0=USART1_RX
Dma.Request1=USART1_TX Dma.Request1=USART1_TX
Dma.RequestsNb=2 Dma.Request2=ADC1
Dma.RequestsNb=3
Dma.USART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY Dma.USART1_RX.0.Direction=DMA_PERIPH_TO_MEMORY
Dma.USART1_RX.0.Instance=DMA1_Channel5 Dma.USART1_RX.0.Instance=DMA1_Channel5
Dma.USART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE Dma.USART1_RX.0.MemDataAlignment=DMA_MDATAALIGN_BYTE
@@ -39,8 +60,9 @@ Mcu.IP2=DMA
Mcu.IP3=NVIC Mcu.IP3=NVIC
Mcu.IP4=RCC Mcu.IP4=RCC
Mcu.IP5=SYS Mcu.IP5=SYS
Mcu.IP6=USART1 Mcu.IP6=TIM6
Mcu.IPNb=7 Mcu.IP7=USART1
Mcu.IPNb=8
Mcu.Name=STM32F103R(C-D-E)Tx Mcu.Name=STM32F103R(C-D-E)Tx
Mcu.Package=LQFP64 Mcu.Package=LQFP64
Mcu.Pin0=PD0-OSC_IN Mcu.Pin0=PD0-OSC_IN
@@ -59,6 +81,7 @@ Mcu.Pin2=PC1
Mcu.Pin20=PB6 Mcu.Pin20=PB6
Mcu.Pin21=PB7 Mcu.Pin21=PB7
Mcu.Pin22=VP_SYS_VS_Systick Mcu.Pin22=VP_SYS_VS_Systick
Mcu.Pin23=VP_TIM6_VS_ClockSourceINT
Mcu.Pin3=PA4 Mcu.Pin3=PA4
Mcu.Pin4=PA5 Mcu.Pin4=PA5
Mcu.Pin5=PA6 Mcu.Pin5=PA6
@@ -66,13 +89,14 @@ Mcu.Pin6=PA7
Mcu.Pin7=PC4 Mcu.Pin7=PC4
Mcu.Pin8=PC5 Mcu.Pin8=PC5
Mcu.Pin9=PC7 Mcu.Pin9=PC7
Mcu.PinsNb=23 Mcu.PinsNb=24
Mcu.ThirdPartyNb=0 Mcu.ThirdPartyNb=0
Mcu.UserConstants= Mcu.UserConstants=
Mcu.UserName=STM32F103RCTx Mcu.UserName=STM32F103RCTx
MxCube.Version=6.11.1 MxCube.Version=6.12.0
MxDb.Version=DB.6.0.111 MxDb.Version=DB.6.0.120
NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.BusFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.DMA1_Channel1_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Channel4_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DMA1_Channel4_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true NVIC.DMA1_Channel5_IRQn=true\:0\:0\:false\:false\:true\:false\:true\:true
NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.DebugMonitor_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
@@ -84,6 +108,7 @@ NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4 NVIC.PriorityGroup=NVIC_PRIORITYGROUP_4
NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.SVCall_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false NVIC.SysTick_IRQn=true\:15\:0\:false\:false\:true\:false\:true\:false
NVIC.TIM6_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true NVIC.USART1_IRQn=true\:0\:0\:false\:false\:true\:true\:true\:true
NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false NVIC.UsageFault_IRQn=true\:0\:0\:false\:false\:true\:false\:false\:false
PA10.GPIOParameters=GPIO_PuPd,GPIO_Label PA10.GPIOParameters=GPIO_PuPd,GPIO_Label
@@ -193,7 +218,7 @@ ProjectManager.ToolChainLocation=
ProjectManager.UAScriptAfterPath= ProjectManager.UAScriptAfterPath=
ProjectManager.UAScriptBeforePath= ProjectManager.UAScriptBeforePath=
ProjectManager.UnderRoot=true ProjectManager.UnderRoot=true
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_DAC_Init-DAC-false-HAL-true,6-MX_ADC1_Init-ADC1-false-HAL-true ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_DMA_Init-DMA-false-HAL-true,4-MX_USART1_UART_Init-USART1-false-HAL-true,5-MX_DAC_Init-DAC-false-HAL-true,6-MX_ADC1_Init-ADC1-false-HAL-true,7-MX_TIM6_Init-TIM6-false-HAL-true
RCC.ADCFreqValue=12000000 RCC.ADCFreqValue=12000000
RCC.ADCPresc=RCC_ADCPCLK2_DIV6 RCC.ADCPresc=RCC_ADCPCLK2_DIV6
RCC.AHBFreq_Value=72000000 RCC.AHBFreq_Value=72000000
@@ -235,10 +260,15 @@ SH.COMP_DAC2_group.0=DAC_OUT2,DAC_OUT2
SH.COMP_DAC2_group.ConfNb=1 SH.COMP_DAC2_group.ConfNb=1
SH.GPXTI11.0=GPIO_EXTI11 SH.GPXTI11.0=GPIO_EXTI11
SH.GPXTI11.ConfNb=1 SH.GPXTI11.ConfNb=1
TIM6.IPParameters=Prescaler,Period
TIM6.Period=1000-1
TIM6.Prescaler=72-1
USART1.BaudRate=9600 USART1.BaudRate=9600
USART1.IPParameters=VirtualMode,BaudRate USART1.IPParameters=VirtualMode,BaudRate
USART1.VirtualMode=VM_ASYNC USART1.VirtualMode=VM_ASYNC
VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_TIM6_VS_ClockSourceINT.Mode=Enable_Timer
VP_TIM6_VS_ClockSourceINT.Signal=TIM6_VS_ClockSourceINT
board=custom board=custom
isbadioc=false isbadioc=false