Commit 27897d63 authored by Bc. Petr Elexa's avatar Bc. Petr Elexa

Add ACS protocol

parent ce31e1dd
......@@ -2,7 +2,7 @@
Main startup sequence
*/
#include <can/can_term_driver.h>
#include "can/can_term_driver.h"
#include "terminal.h"
#include "board.h"
#include "FreeRTOS.h"
......@@ -31,7 +31,8 @@ static void alive_task(void *pvParameters)
while (1)
{
vTaskDelay(5000 / portTICK_PERIOD_MS);
DEBUGSTR("tick\n");
DEBUGSTR(".");
CAN_send_test();
}
}
#endif //DEVEL_BOARD
......
......@@ -5,6 +5,8 @@
#include <static_cache.h>
#ifdef CACHING_ENABLED
typedef struct
{
cache_item_t * const ptr_items;
......@@ -48,7 +50,7 @@ static bool _binary_search(const cache_set_t * ptr_set, const cache_item_t kv, i
// O(1)
static inline cache_set_t * _get_cache_set(const cache_item_t kv)
{
return &_cache_sets[(kv.key & 0xC00000) >> 22];
return &_cache_sets[(kv.key & 0x3)];
}
// O(log (STATIC_CACHE_CAPACITY / STATIC_CACHE_SETS))
......@@ -84,7 +86,7 @@ void static_cache_insert(const cache_item_t kv)
{
if ( 1 + ptr_set->length >= STATIC_CACHE_SET_CAP)
{
//TODO cache set full
// cache set full - replace existing
ptr_set->ptr_items[idx] = kv;
}
else
......@@ -122,3 +124,5 @@ cache_item_t static_cache_convert(uint32_t scalar)
cache_item_t kv = {.scalar = scalar};
return kv;
}
#endif
......@@ -3,6 +3,7 @@
#include <stdint.h>
#include <stdbool.h>
#include "terminal_config.h"
#define STATIC_CACHE_SETS 4
#define STATIC_CACHE_SET_CAP 128
......@@ -15,8 +16,8 @@ typedef union
{
struct
{
uint32_t key : 24;
uint32_t value : 8;
uint32_t key : 31;
uint32_t value : 1;
};
uint32_t scalar;
} cache_item_t;
......
......@@ -11,26 +11,14 @@
#include "FreeRTOS.h"
#include "task.h"
#include "stream_buffer.h"
#include "can/can_term_driver.h"
#include "can/can_term_protocol.h"
#include <stdio.h>
#include <string.h>
typedef union
{
#pragma pack(push,1)
struct
{
uint32_t user_id : 24;
uint32_t panelA : 1;
uint32_t panelB : 1;
uint32_t : 6; // reserved for future
};
#pragma pack(pop)
cache_item_t as_cache_item;
uint32_t as_bitvalue;
}term_cache_item_t; // 4B
typedef cache_item_t term_cache_item_t; // 4B
static uint32_t _learn_enable_user_id = 7632370;
static void terminal_user_authorized(uint8_t panel_id)
{
......@@ -46,33 +34,54 @@ static void terminal_user_not_authorized(uint8_t panel_id)
DEBUGSTR("auth FAIL\n");
}
static void terminal_user_identified(uint32_t user_id, uint8_t panel_id)
// This is called from ISR - do stuff quickly
void terminal_can_proto_handler(uint32_t msg_head, uint8_t * data, uint8_t dlc)
{
if (user_id == _learn_enable_user_id)
if (AUTH_OK)
{
panel_conf[panel_id].learn_mode = !panel_conf[panel_id].learn_mode;
return;
terminal_user_authorized(panel_id);
#ifdef CACHING_ENABLED
static_cache_insert(user);
#endif
}
else if (AUTH_FAIL)
{
terminal_user_not_authorized(panel_id);
}
}
static void terminal_register_user(uint32_t user_id, uint8_t panel_id)
{
// TODO send request on CAN
}
static void terminal_request_auth(uint32_t user_id, uint8_t panel_id)
{
// TODO send request on CAN
}
static void terminal_user_identified(uint32_t user_id, uint8_t panel_id)
{
term_cache_item_t user;
user.user_id = user_id;
user.key = user_id;
if (panel_conf[panel_id].learn_mode)
{
user.as_bitvalue |= _BIT(panel_id) << 24;
static_cache_insert(user.as_cache_item);
}
else if (static_cache_get(&user.as_cache_item))
if (panel_id < DOOR_ACC_PANEL_COUNT)
{
if ((user.panelB << 1 | user.panelA) & _BIT(panel_id))
if (panel_conf[panel_id].learn_mode)
{
user.value = panel_id;
terminal_register_user(user_id, panel_id);
}
else if (static_cache_get(&user) && user.panel == panel_id)
{
terminal_user_authorized(panel_id);
return;
}
}
else
{
terminal_user_not_authorized(panel_id);
else
{
terminal_request_auth(user_id, panel_id);
}
}
}
......@@ -87,12 +96,17 @@ static void terminal_task(void *pvParameters)
if (panel_id < DOOR_ACC_PANEL_COUNT)
{
terminal_user_identified(user_id, panel_id);
DEBUGSTR("user identified\n");
}
}
}
void terminal_init(void)
{
//register handler
CAN_frame_callback = terminal_can_proto_handler;
CAN_receive_all_frames();
for (size_t id = 0; id < DOOR_ACC_PANEL_COUNT; ++id)
{
if (panel_conf[id].acc_panel_on) terminal_reconfigure(NULL, id);
......@@ -101,14 +115,8 @@ void terminal_init(void)
xTaskCreate(terminal_task, "term_tsk", configMINIMAL_STACK_SIZE + 128, NULL, (tskIDLE_PRIORITY + 1UL), NULL);
#ifdef DEVEL_BOARD
static_cache_insert(static_cache_convert(0x7 << 24 | 814204));
static_cache_insert(static_cache_convert(0x7 << 24 | 814199));
static_cache_insert(static_cache_convert(0x7 << 24 | 814185));
static_cache_insert(static_cache_convert(0x7 << 24 | 814190));
static_cache_insert(static_cache_convert(0x7 << 24 | 7577396));
static_cache_insert(static_cache_convert(0x7 << 24 | 7575678));
static_cache_insert(static_cache_convert(0x7 << 24 | 7573990));
static_cache_insert(static_cache_convert(0x7 << 24 | 7627526));
static_cache_insert(static_cache_convert((814204 << 1) | 0));
static_cache_insert(static_cache_convert((814199 << 1) | 1));
#endif
}
......@@ -126,11 +134,13 @@ void terminal_reconfigure(panel_conf_t * panel_cfg, uint8_t panel_id)
if (panel_conf[panel_id].acc_panel_on)
{
panel_init(panel_id);
DEBUGSTR("panel enabled\n");
}
else
{
//disable interface
panel_deinit(panel_id);
DEBUGSTR("panel disabled\n");
}
}
else
......
......@@ -109,6 +109,8 @@ inline static void _100kbaud(uint32_t * can_api_timing_cfg)
*****************************************************************************/
void CAN_init(void)
{
CAN_frame_callback = NULL;
// Power up CAN
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CAN);
......@@ -134,7 +136,7 @@ void CAN_receive_all_frames(void)
{
CCAN_MSG_OBJ_T msg_obj;
/* Configure message object 1 to receive all 29-bit messages 0x0-0x1FFFFFFF */
/* Configure message object 1 to receive all extended frames 0-0x1FFFFFFF */
msg_obj.msgobj = 1;
msg_obj.mode_id = CAN_MSGOBJ_EXT;
msg_obj.mask = 0x0;
......@@ -164,7 +166,7 @@ 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 | 0x3456;
msg_obj.mode_id = CAN_MSGOBJ_EXT | 0x23456;
msg_obj.mask = 0x0;
msg_obj.dlc = 4;
msg_obj.data[0] = 0;
......@@ -209,9 +211,13 @@ void CAN_rx(uint8_t 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)
{
//CAN_frame_callback(msg_obj.mode_id & CAN_EXT_ID_BIT_MASK, msg_obj.data, msg_obj.dlc);
if (CAN_frame_callback != NULL)
{
CAN_frame_callback(msg_obj.mode_id & CAN_EXT_ID_BIT_MASK, msg_obj.data, msg_obj.dlc);
}
}
}
......
......@@ -12,9 +12,10 @@
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_frame_callback(uint32_t id, uint8_t * data, uint8_t size);
void CAN_send_test(void);
void (*CAN_frame_callback)(uint32_t id, uint8_t * data, uint8_t size);
/*
* CCAN_MSG_OBJ_T cheat sheet:
*
......
#ifndef CAN_TERM_PROTOCOL_H_
#define CAN_TERM_PROTOCOL_H_
// Node identification
#define CAN_ID_MASTER_0 0x1
#define CAN_ID_MASTER_1 0x2
#define CAN_ID_MASTER_2 0x3
#define CAN_ID_FIRST_SLAVE 0x4
#define CAN_ID_LAST_SLAVE 0xFFFF
// Function codes
#define CAN_MASTER_COMM 0x00000
#define CAN_AUTH_REQ 0x10000
#define CAN_AUTH_RESP 0x20000
#define CAN_REMOTE_LOCK 0x30000
#define CAN_ANNOUNCE_USER_ID 0x40000
// HEAD partitions sizes
#define ACS_PRIO_BITS 3
#define ACS_FC_BITS 6
#define ACS_ADDR_BITS 10
// Address space
#define ACS_BROADCAST_ADDR ((1 << ACS_ADDR_BITS) - 1)
#define ACS_MSTR_FIRST_ADDR 0
#define ACS_MSTR_LAST_ADDR 1
#define ACS_PNL_FIRST_ADDR 2
#define ACS_PNL_LAST_ADDR (ACS_BROADCAST_ADDR - 1)
// message head offsets
#define ACS_SRC_ADDR_OFFSET 0
#define ACS_DST_ADDR_OFFSET (ACS_SRC_ADDR_OFFSET + ACS_ADDR_BITS)
#define ACS_FC_OFFSET (ACS_DST_ADDR_OFFSET + ACS_ADDR_BITS)
#define ACS_PRIO_OFFSET (ACS_FC_OFFSET + ACS_FC_BITS)
// message head masks
#define ACS_SRC_ADDR_MASK (((1 << ACS_ADDR_BITS) - 1) << ACS_SRC_ADDR_OFFSET)
#define ACS_DST_ADDR_MASK (((1 << ACS_ADDR_BITS) - 1) << ACS_DST_ADDR_OFFSET)
#define ACS_FC_MASK (((1 << ACS_FC_BITS) - 1) << ACS_FC_OFFSET)
#define ACS_PRIO_MASK (((1 << ACS_PRIO_BITS) - 1) << ACS_PRIO_OFFSET)
#define ACC_MAX_PRIO 0
#define ACS_LOW_PRIO ((1 << ACS_PRIO_BITS) - 1)
// ACS protocol function codes
#define FC_RESERVED 0x0
#define FC_USER_AUTH_REQ 0x1
#define FC_USER_AUTH_RESP_FAIL 0x2
#define FC_USER_AUTH_RESP_OK 0x3
#define FC_PANEL_CTRL 0x4
#define FC_NEW_USER 0x5
#define FC_DOOR_STATUS 0x6
// priorities
#define PRIO_RESERVED 0x0
#define PRIO_USER_AUTH_REQ 0x2
#define PRIO_USER_AUTH_RESP_FAIL 0x2
#define PRIO_USER_AUTH_RESP_OK 0x2
#define PRIO_PANEL_CTRL 0x4
#define PRIO_NEW_USER 0x4
#define PRIO_DOOR_STATUS 0x3
#define PANEL_CTRL_DATA_DEF 0x00
#define PANEL_CTRL_DATA_UNLCK 0x01
#define PANEL_CTRL_DATA_LCK 0x02
#define PANEL_CTRL_DATA_LEARN 0x03
#define PANEL_CTRL_DATA_CLR_CACHE 0x04
#define DOOR_STATUS_DATA_CLOSED 0x0
#define DOOR_STATUS_DATA_OPEN 0x1
// data types
#pragma pack(push,1)
typedef struct
{
uint32_t prio : ACS_PRIO_BITS;
uint32_t fc : ACS_FC_BITS;
uint32_t dst : ACS_ADDR_BITS;
uint32_t src : ACS_ADDR_BITS;
} msg_head_t;
typedef struct
{
uint32_t user_id;
uint8_t panel_id : 2;
uint8_t : 6;
} can_auth_req_t;
} msg_data_auth_req_t;
typedef struct
{
uint32_t user_id;
uint8_t status : 2;
uint8_t p0 : 1;
uint8_t p1 : 1;
uint8_t p2 : 1;
uint8_t p3 : 1;
uint8_t : 2;
} can_auth_resp_t;
} masg_data_auth_resp_t;
typedef struct
{
uint32_t user_id;
uint8_t p0 : 1;
uint8_t p1 : 1;
uint8_t p2 : 1;
uint8_t p3 : 1;
uint8_t : 4;
} can_announce_user_id_t;
} msg_data_new_user_t;
typedef struct
{
uint32_t node_id;
uint8_t panel_id : 2;
uint8_t : 6;
} can_remote_lock_t;
uint8_t ctrl_command;
} msg_data_panel_ctrl_t;
#pragma pack(pop)
......
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