Commit e298edc7 authored by Bc. Petr Elexa's avatar Bc. Petr Elexa

Add can bus protocol handler

parent 27897d63
......@@ -73,8 +73,8 @@ int main(void)
xTaskCreate(alive_task, "alv_tsk",configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 1UL), NULL);
#endif
CAN_init();
terminal_init();
WDT_Init();
check_system_stack_size();
......
......@@ -16,8 +16,8 @@ typedef union
{
struct
{
uint32_t key : 31;
uint32_t value : 1;
uint32_t key : 30;
uint32_t value : 2;
};
uint32_t scalar;
} cache_item_t;
......
/*
*
* Access control system panel
* Created on: 24. 8. 2018
* Author: Petr
*/
......@@ -16,39 +16,160 @@
#include <stdio.h>
#include <string.h>
// Cache entry mapping
typedef cache_item_t term_cache_item_t; // 4B
// value 0 - none
// value 1 - door A
// value 2 - door B
// value 3 - all
/* ROM CCAN driver callback functions prototypes */
/*****************************************************************************
**
** Description: CAN receive callback.
** Function is executed by the Callback handler after
** a CAN message has been received
**
** Parameters: msg_obj_num. Contains the number of the message object
** that triggered the CAN receive callback.
** Returned value: None
*****************************************************************************/
void term_can_recv(uint8_t msg_obj_num);
/*****************************************************************************
**
** Description: CAN transmit callback.
** Function is executed by the Callback handler after
** a CAN message has been transmitted
**
** Parameters: msg_obj_num. Contains the number of the message object
** that triggered the CAN transmit callback.
** Returned value: None
*****************************************************************************/
void term_can_send(uint8_t msg_obj_num);
/*****************************************************************************
**
** Description: CAN error callback.
** Function is executed by the Callback handler after
** an error has occured on the CAN bus
**
** Parameters: error_info. Contains the error code
** that triggered the CAN error callback.
** Returned value: None
*****************************************************************************/
void term_can_error(uint32_t error_info);
static void terminal_user_authorized(uint8_t panel_id)
/* CAN Callback Functions of on-chip drivers */
const CCAN_CALLBACKS_T _term_can_callbacks =
{
term_net_recv, /* callback for any message received CAN frame which ID matches with any of the message objects' masks */
term_net_send, /* callback for every transmitted CAN frame */
term_net_error, /* callback for CAN errors */
NULL, /* callback for expedited read access (not used) */
NULL, /* callback for expedited write access (not used) */
NULL, /* callback for segmented read access (not used) */
NULL, /* callback for segmented write access (not used) */
NULL, /* callback for fall-back SDO handler (not used) */
};
inline void terminal_user_authorized(uint8_t panel_id)
{
// TODO
DEBUGSTR("auth OK\n");
panel_unlock(panel_id, BEEP_ON_SUCCESS, OK_LED_ON_SUCCESS);
}
static void terminal_user_not_authorized(uint8_t panel_id)
inline void terminal_user_not_authorized(uint8_t panel_id)
{
//TODO
(void)panel_id;
DEBUGSTR("auth FAIL\n");
}
// This is called from ISR - do stuff quickly
void terminal_can_proto_handler(uint32_t msg_head, uint8_t * data, uint8_t dlc)
// This is called from ISR -> do not block
void term_can_recv(uint32_t msg_head, uint8_t * data, uint8_t dlc)
{
CCAN_MSG_OBJ_T msg_obj;
/* Determine which CAN message has been received */
msg_obj.msgobj = msg_obj_num;
/* Now load up the msg_obj structure with the CAN message */
LPC_CCAN_API->can_receive(&msg_obj);
msg_head_t head = (msg_head_t)msg_obj.mode_id;
uint8_t panel_id;
// get target door if message is for us
if (msg_obj_num == ACS_MSGOBJ_RECV_DOOR_A) //TODO pouzit dva MSG OBJ
{
DEBUGSTR("got CAN msg");
if (head.dst == ACC_PANEL_A_ADDR)
{
panel_id = ACC_PANEL_A;
DEBUGSTR("for door A\n");
}
else if (head.dst == ACC_PANEL_B_ADDR)
{
panel_id = ACC_PANEL_B;
DEBUGSTR("for door B\n");
}
else return;
}
else return;
if (AUTH_OK)
// continue deducing action and execute it
if (head.fc == FC_USER_AUTH_RESP_OK)
{
terminal_user_authorized(panel_id);
#ifdef CACHING_ENABLED
term_cache_item_t user = {0, panel_id+1};
uint8_t len = msg_obj.dlc > sizeof(uint32_t) ? sizeof(uint32_t) : msg_obj.dlc;
memcpy(&user.key, msg_obj.data, len);
static_cache_insert(user);
#endif
}
else if (AUTH_FAIL)
else if (head.fc == FC_USER_AUTH_RESP_FAIL)
{
terminal_user_not_authorized(panel_id);
#ifdef CACHING_ENABLED
term_cache_item_t user = {0, 0};
uint8_t len = msg_obj.dlc > sizeof(uint32_t) ? sizeof(uint32_t) : msg_obj.dlc;
memcpy(&user.key, msg_obj.data, len);
static_cache_insert(user);
#endif
}
else if (head.fc == FC_PANEL_CTRL)
{
switch (msg_obj.data[0])
{
case PANEL_CTRL_DATA_DEF:
DEBUGSTR("mode DEF\n");
panel_conf_t[panel_id].mode = PANEL_MODE_DEF;
break;
case PANEL_CTRL_DATA_UNLCK:
DEBUGSTR("cmd UNLOCK\n");
terminal_user_authorized(panel_id);
break;
case PANEL_CTRL_DATA_LCK:
DEBUGSTR("mode LOCK\n");
panel_conf_t[panel_id].mode = PANEL_MODE_LOCKED;
break;
case PANEL_CTRL_DATA_LEARN:
DEBUGSTR("mode LEARN\n");
panel_conf_t[panel_id].mode = PANEL_MODE_LEARN;
break;
case PANEL_CTRL_DATA_CLR_CACHE:
DEBUGSTR("cmd CLR CACHE\n");
//TODO clear cache
break;
default:
break;
}
}
else return;
}
static void terminal_register_user(uint32_t user_id, uint8_t panel_id)
......@@ -69,15 +190,21 @@ static void terminal_user_identified(uint32_t user_id, uint8_t panel_id)
if (panel_id < DOOR_ACC_PANEL_COUNT)
{
if (panel_conf[panel_id].learn_mode)
if (panel_conf[panel_id].mode == PANEL_MODE_LOCKED)
{
terminal_user_not_authorized(panel_id);
}
else if (panel_conf[panel_id].mode == PANEL_MODE_LEARN)
{
user.value = panel_id;
terminal_register_user(user_id, panel_id);
}
#ifdef CACHING_ENABLED
else if (static_cache_get(&user) && user.panel == panel_id)
{
terminal_user_authorized(panel_id);
}
#endif
else
{
terminal_request_auth(user_id, panel_id);
......@@ -103,13 +230,15 @@ static void terminal_task(void *pvParameters)
void terminal_init(void)
{
//register handler
CAN_frame_callback = terminal_can_proto_handler;
CAN_receive_all_frames();
//init CAN comm
CAN_init(_term_can_callbacks, CAN_BAUD_RATE);
CAN_recv_filter_set_eff(ACS_MSGOBJ_RECV_DOOR_A);
//CAN_recv_filter_set(ACS_MSGOBJ_RECV_DOOR_A, ACC_PANEL_A_ADDR << ACS_DST_ADDR_OFFSET, ACS_DST_ADDR_MASK);
//CAN_recv_filter_set(ACS_MSGOBJ_RECV_DOOR_B, ACC_PANEL_B_ADDR << ACS_DST_ADDR_OFFSET, ACS_DST_ADDR_MASK);
for (size_t id = 0; id < DOOR_ACC_PANEL_COUNT; ++id)
{
if (panel_conf[id].acc_panel_on) terminal_reconfigure(NULL, id);
if (panel_conf[id].enabled) terminal_reconfigure(NULL, id);
}
xTaskCreate(terminal_task, "term_tsk", configMINIMAL_STACK_SIZE + 128, NULL, (tskIDLE_PRIORITY + 1UL), NULL);
......@@ -131,7 +260,7 @@ void terminal_reconfigure(panel_conf_t * panel_cfg, uint8_t panel_id)
memcpy(&panel_conf[panel_id], panel_cfg, sizeof(panel_conf_t));
//reconfigure interface to card reader
if (panel_conf[panel_id].acc_panel_on)
if (panel_conf[panel_id].enabled)
{
panel_init(panel_id);
DEBUGSTR("panel enabled\n");
......
......@@ -8,9 +8,14 @@
#ifndef BSP_BOARD_CONFIG_H_
#define BSP_BOARD_CONFIG_H_
#define DEVEL_BOARD
//-------------------------------------------------------------
// General settings
#define DEVEL_BOARD
#define CACHING_ENABLED
#define CAN_BAUD_RATE 125000
//-------------------------------------------------------------
// global UID from vendor (from chip)
#define IAP_READ_UID 58
......@@ -18,7 +23,7 @@ extern unsigned int TERMINAL_UID[5]; // 0 - status code, 1 - least significant w
// Panel address in ACS (from ROM)
// TODO place on specific address in FLASH
extern uint16_t ACC_PANEL_A_ADDR;
extern uint16_t ACC_PANEL_A_ADDR; //base address
extern uint16_t ACC_PANEL_B_ADDR;
#define ACC_PANEL_A 0
......
......@@ -15,34 +15,14 @@ __BSS(RESERVED) char CAN_driver_memory[184]; /* reserve 184 bytes for CAN drive
#define CCAN_BCR_TSEG1(x) (((x) & 0x0F) << 8)
#define CCAN_BCR_TSEG2(x) (((x) & 0x07) << 12)
#define CAN_EXT_ID_BIT_MASK 0x1FFFFFFFUL
#define CAN_DLC_MAX 8
/*****************************************************************************
* Private types/enumerations/variables
****************************************************************************/
/* ROM CCAN driver callback functions prototypes */
void CAN_rx(uint8_t msg_obj_num);
void CAN_tx(uint8_t msg_obj_num);
void CAN_error(uint32_t error_info);
/* IRQ handler prototype */
void CAN_IRQHandler(void);
/* Publish CAN Callback Functions of on-chip drivers */
CCAN_CALLBACKS_T _callbacks =
{
CAN_rx, /* callback for any message received CAN frame which ID matches with any of the message objects' masks */
CAN_tx, /* callback for every transmitted CAN frame */
CAN_error, /* callback for CAN errors */
NULL, /* callback for expedited read access (not used) */
NULL, /* callback for expedited write access (not used) */
NULL, /* callback for segmented read access (not used) */
NULL, /* callback for segmented write access (not used) */
NULL, /* callback for fall-back SDO handler (not used) */
};
/*****************************************************************************
* Public types/enumerations/variables
****************************************************************************/
......@@ -107,10 +87,8 @@ inline static void _100kbaud(uint32_t * can_api_timing_cfg)
** Parameters: None
** Returned value: None
*****************************************************************************/
void CAN_init(void)
void CAN_init(CCAN_CALLBACKS_T * ptr_callbacks, uint32_t baud_rate)
{
CAN_frame_callback = NULL;
// Power up CAN
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CAN);
......@@ -120,43 +98,52 @@ void CAN_init(void)
/* Initialize CAN Controller structure*/
uint32_t ClkInitTable[2];
//_100kbaud(&ClkInitTable[0]);
_timing_calculate(125000, &ClkInitTable[0]);
_timing_calculate(baud_rate, &ClkInitTable[0]);
/* Initialize the CAN controller */
LPC_CCAN_API->init_can(&ClkInitTable[0], TRUE);
/* Configure the CAN callback functions */
LPC_CCAN_API->config_calb(&_callbacks);
LPC_CCAN_API->config_calb(ptr_callbacks);
/* Enable the CAN Interrupt */
NVIC_EnableIRQ(CAN_IRQn);
}
void CAN_receive_all_frames(void)
void CAN_recv_filter_set(uint8_t msgobj_num, uint32_t id, uint32_t mask)
{
CCAN_MSG_OBJ_T msg_obj;
CCAN_MSG_OBJ_T msg_obj = {0, };
/* Configure message object 1 to receive all extended frames 0-0x1FFFFFFF */
msg_obj.msgobj = 1;
/* Configure Message object 1 to receive all extended frames 0-0x1FFFFFFF */
msg_obj.msgobj = msgobj_num;
msg_obj.mode_id = id;
msg_obj.mask = mask;
LPC_CCAN_API->config_rxmsgobj(&msg_obj);
}
void CAN_recv_filter_set_eff(uint8_t msgobj_num)
{
CCAN_MSG_OBJ_T msg_obj = {0, };
/* Configure Message object 1 to receive all extended frames 0-0x1FFFFFFF */
msg_obj.msgobj = msgobj_num;
msg_obj.mode_id = CAN_MSGOBJ_EXT;
msg_obj.mask = 0x0;
LPC_CCAN_API->config_rxmsgobj(&msg_obj);
}
void CAN_send_frame_once(uint32_t id, uint8_t * data, uint8_t size)
void CAN_send_once(uint8_t msgobj_num, uint32_t id, uint8_t * data, uint8_t size)
{
if (size > CAN_DLC_MAX) size = CAN_DLC_MAX;
CCAN_MSG_OBJ_T msg_obj;
msg_obj.msgobj = 0;
msg_obj.msgobj = msgobj_num;
msg_obj.mode_id = CAN_MSGOBJ_EXT | (id & CAN_EXT_ID_BIT_MASK);
msg_obj.mask = 0x0;
msg_obj.dlc = size;
for (int i = 0; i < size; ++i)
{
msg_obj.data[i] = data[i];
}
memcpy(msg_obj.data, data, size);
LPC_CCAN_API->can_transmit(&msg_obj);
}
......@@ -165,8 +152,8 @@ void CAN_send_test(void)
{
CCAN_MSG_OBJ_T msg_obj;
/* Send a simple one time CAN message */
msg_obj.msgobj = 0;
msg_obj.mode_id = CAN_MSGOBJ_EXT | 0x23456;
msg_obj.msgobj = CCAN_MSG_OBJ_LAST;
msg_obj.mode_id = CAN_MSGOBJ_EXT | 0x123456;
msg_obj.mask = 0x0;
msg_obj.dlc = 4;
msg_obj.data[0] = 0;
......@@ -191,64 +178,3 @@ void CAN_IRQHandler(void)
LPC_CCAN_API->isr();
}
/*****************************************************************************
** Function name: CAN_RX
**
** Description: CAN receive callback.
** Function is executed by the Callback handler after
** a CAN message has been received
**
** Parameters: msg_obj_num. Contains the number of the message object
** that triggered the CAN receive callback.
** Returned value: None
*****************************************************************************/
void CAN_rx(uint8_t msg_obj_num)
{
CCAN_MSG_OBJ_T msg_obj;
/* Determine which CAN message has been received */
msg_obj.msgobj = msg_obj_num;
/* Now load up the msg_obj structure with the CAN message */
LPC_CCAN_API->can_receive(&msg_obj);
if (msg_obj_num == 1)
{
if (CAN_frame_callback != NULL)
{
CAN_frame_callback(msg_obj.mode_id & CAN_EXT_ID_BIT_MASK, msg_obj.data, msg_obj.dlc);
}
}
}
/*****************************************************************************
** Function name: CAN_TX
**
** Description: CAN transmit callback.
** Function is executed by the Callback handler after
** a CAN message has been transmitted
**
** Parameters: msg_obj_num. Contains the number of the message object
** that triggered the CAN transmit callback.
** Returned value: None
*****************************************************************************/
void CAN_tx(uint8_t msg_obj_num)
{
return;
}
/*****************************************************************************
** Function name: CAN_Error
**
** Description: CAN error callback.
** Function is executed by the Callback handler after
** an error has occured on the CAN bus
**
** Parameters: error_info. Contains the error code
** that triggered the CAN error callback.
** Returned value: None
*****************************************************************************/
void CAN_error(uint32_t error_info)
{
return;
}
/***********************************************************************
* CAN interface driver
* for only one user
*
**********************************************************************/
......@@ -9,12 +10,16 @@
#include "board.h"
#include <stdint.h>
void CAN_init(void);
void CAN_receive_all_frames(void);
void CAN_send_frame_once(uint32_t id, uint8_t * data, uint8_t size);
void CAN_send_test(void);
#define CCAN_MSG_OBJ_FIRST 0
#define CCAN_MSG_OBJ_LAST 31
#define CAN_EXT_ID_BIT_MASK 0x1FFFFFFFUL
#define CAN_DLC_MAX 8
void (*CAN_frame_callback)(uint32_t id, uint8_t * data, uint8_t size);
void CAN_init(CCAN_CALLBACKS_T * ptr_callbacks, uint32_t baud_rate);
void CAN_recv_filter_set(uint8_t msgobj_num, uint32_t id, uint32_t mask);
void CAN_recv_filter_set_eff(uint8_t msgobj_num);
void CAN_send_once(uint8_t msgobj_num, uint32_t id, uint8_t * data, uint8_t size);
void CAN_send_test(void);
/*
* CCAN_MSG_OBJ_T cheat sheet:
......
#ifndef CAN_TERM_PROTOCOL_H_
#define CAN_TERM_PROTOCOL_H_
#define ACS_MSGOBJ_SEND_DOOR_A 0
#define ACS_MSGOBJ_SEND_DOOR_B 1
#define ACS_MSGOBJ_RECV_DOOR_A 2
#define ACS_MSGOBJ_RECV_DOOR_B 3
// HEAD partitions sizes
#define ACS_PRIO_BITS 3
......@@ -50,7 +54,7 @@
#define PANEL_CTRL_DATA_DEF 0x00
#define PANEL_CTRL_DATA_UNLCK 0x01
#define PANEL_CTRL_DATA_LCK 0x02
#define PANEL_CTRL_DATA_LOCK 0x02
#define PANEL_CTRL_DATA_LEARN 0x03
#define PANEL_CTRL_DATA_CLR_CACHE 0x04
......@@ -63,6 +67,7 @@
typedef struct
{
uint32_t flags : 3;
uint32_t prio : ACS_PRIO_BITS;
uint32_t fc : ACS_FC_BITS;
uint32_t dst : ACS_ADDR_BITS;
......@@ -77,7 +82,7 @@ typedef struct
typedef struct
{
uint32_t user_id;
} masg_data_auth_resp_t;
} msg_data_auth_resp_t;
typedef struct
{
......
......@@ -42,18 +42,18 @@ panel_conf_t panel_conf[DOOR_ACC_PANEL_COUNT] =
{
.timer_ok = NULL,
.timer_open = NULL,
.acc_panel_on = DOOR_1_ACC_PANEL_ON,
.open_time_sec = DOOR_1_OPEN_TIME_MS,
.gled_time_sec = DOOR_1_OK_GLED_TIME_MS,
.learn_mode = false,
.mode = PANEL_MODE_DEF,
.enabled = DOOR_1_ACC_PANEL_ON,
},
{
.timer_ok = NULL,
.timer_open = NULL,
.acc_panel_on = DOOR_2_ACC_PANEL_ON,
.open_time_sec = DOOR_2_OPEN_TIME_MS,
.gled_time_sec = DOOR_2_OK_GLED_TIME_MS,
.learn_mode = false,
.mode = PANEL_MODE_DEF,
.enabled = DOOR_2_ACC_PANEL_ON,
}
};
......
......@@ -12,15 +12,22 @@
#include "timers.h"
#include "weigand.h"
typedef enum
{
PANEL_MODE_DEF = 0,
PANEL_MODE_LOCKED,
PANEL_MODE_LEARN
} panel_mode_t;
typedef struct
{
TimerHandle_t timer_open;
TimerHandle_t timer_ok;
uint16_t open_time_sec;
uint16_t gled_time_sec;
uint8_t acc_panel_on : 1;
uint8_t learn_mode : 1;
} panel_conf_t; //TOTAL SIZE 12B
panel_mode_t mode;
uint8_t enabled;
} panel_conf_t;
typedef struct
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment