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

panel: Add external storage support part 2

parent fb221971
......@@ -11,6 +11,7 @@
#include "timers.h"
#include "watchdog.h"
#include "brownout.h"
#include "storage.h"
/*****************************************************************************
* Private types/enumerations/variables
......@@ -61,6 +62,8 @@ int main(void)
Board_Print_Reset_Reason();
storage_init();
terminal_init();
WDT_Init(PANEL_WATCHDOG_TIMEOUT);
......
......@@ -16,9 +16,10 @@
#include <stdio.h>
#include <string.h>
// Cache entry mapping
// Cache entry type mapping our type
typedef cache_item_t term_cache_item_t; // 4B
// Used cache values
enum term_cache_panel
{
cache_panel_none = 0,
......@@ -27,12 +28,17 @@ enum term_cache_panel
cache_panel_all = 3
};
// Address for currently active master
static uint16_t _act_master = ACS_RESERVED_ADDR;
uint16_t _act_master = ACS_RESERVED_ADDR;
bool _master_timeout = true;
// Flag for master alive broadcast timeout
static bool _master_timeout = true;
TimerHandle_t _act_timer = NULL;
const uint32_t _act_timer_id = TERMINAL_TIMER_ID;
// Timer for master timeout
// Timer handle
static TimerHandle_t _act_timer = NULL;
// Timer ID
static const uint32_t _act_timer_id = TERMINAL_TIMER_ID;
static inline uint8_t map_panel_id_to_cache(uint8_t panel_id)
......@@ -244,12 +250,12 @@ static void terminal_register_user(uint32_t user_id, uint8_t panel_id)
if (panel_id == ACC_PANEL_A)
{
head.src = ACC_PANEL_A_ADDR;
head.src = get_acs_panel_a_addr();
CAN_send_once(ACS_MSGOBJ_SEND_DOOR_A, head.scalar, (void *)&user_id, sizeof(user_id));
}
else if (panel_id == ACC_PANEL_B)
{
head.src = ACC_PANEL_B_ADDR;
head.src = get_acs_panel_b_addr();
CAN_send_once(ACS_MSGOBJ_SEND_DOOR_B, head.scalar, (void *)&user_id, sizeof(user_id));
}
}
......@@ -259,7 +265,7 @@ static void terminal_request_auth(uint32_t user_id, uint8_t panel_id)
//check if master online
if (_act_master == ACS_RESERVED_ADDR)
{
DEBUGSTR("master offline\n");
DEBUGSTR("master off-line\n");
return;
}
......@@ -272,12 +278,12 @@ static void terminal_request_auth(uint32_t user_id, uint8_t panel_id)
if (panel_id == ACC_PANEL_A)
{
head.src = ACC_PANEL_A_ADDR;
head.src = get_acs_panel_a_addr();
CAN_send_once(ACS_MSGOBJ_SEND_DOOR_A, head.scalar, (void *)&user_id, sizeof(user_id));
}
else if (panel_id == ACC_PANEL_B)
{
head.src = ACC_PANEL_B_ADDR;
head.src = get_acs_panel_b_addr();
CAN_send_once(ACS_MSGOBJ_SEND_DOOR_B, head.scalar, (void *)&user_id, sizeof(user_id));
}
}
......@@ -335,9 +341,10 @@ static void terminal_task(void *pvParameters)
void terminal_init(void)
{
// init CAN driver
// init config for terminal
configASSERT(terminal_config_init());
/* assign CAN callback functions of on-chip drivers */
// assign CAN callback functions of on-chip drivers
CCAN_CALLBACKS_T term_can_callbacks =
{
term_can_recv, /* callback for any message received CAN frame which ID matches with any of the message objects' masks */
......@@ -350,15 +357,16 @@ void terminal_init(void)
NULL, /* callback for fall-back SDO handler (not used) */
};
// init CAN driver
CAN_init(&term_can_callbacks, CAN_BAUD_RATE);
// CAN msg filter for door A
CAN_recv_filter(ACS_MSGOBJ_RECV_DOOR_A,
ACC_PANEL_A_ADDR << ACS_DST_ADDR_OFFSET,
get_acs_panel_a_addr() << ACS_DST_ADDR_OFFSET,
ACS_DST_ADDR_MASK, true);
// CAN msg filter for door B
CAN_recv_filter(ACS_MSGOBJ_RECV_DOOR_B,
ACC_PANEL_B_ADDR << ACS_DST_ADDR_OFFSET,
get_acs_panel_b_addr() << ACS_DST_ADDR_OFFSET,
ACS_DST_ADDR_MASK, true);
// CAN msg filter for broadcast
CAN_recv_filter(ACS_MSGOBJ_RECV_BCAST,
......
......@@ -5,7 +5,74 @@
*/
#include "terminal_config.h"
#include "storage.h"
#include "can/can_term_protocol.h"
// door reader addresses in RAM
const uint16_t ACC_PANEL_A_ADDR = 4;
const uint16_t ACC_PANEL_B_ADDR = 5;
#define ACS_ADDR_BIT_MASK ((1 << ACS_ADDR_BITS) - 1)
// door addresses in ACS
uint16_t _ACS_PANEL_A_ADDR = 0x4; // even
uint16_t _ACS_PANEL_B_ADDR = 0x5; // odd
inline uint16_t get_acs_panel_a_addr(void)
{
return _ACS_PANEL_A_ADDR;
}
inline uint16_t get_acs_panel_b_addr(void)
{
return _ACS_PANEL_B_ADDR;
}
static bool _load_acs_addrs_from_ext_stor(void)
{
bool ret_val = true;
uint16_t first_addr = 0;
ret_val &= storage_read_word_le(PTR_ACS_PANEL_FIRST_ADDR, &first_addr);
if (ret_val)
{
set_acs_panel_addr(first_addr);
}
return ret_val;
}
static bool _save_acs_addrs_from_ext_stor(void)
{
bool ret_val = true;
ret_val &= storage_write_word_le(PTR_ACS_PANEL_FIRST_ADDR, _ACS_PANEL_A_ADDR);
return ret_val;
}
void set_acs_panel_addr(uint16_t first_acs_addr)
{
first_acs_addr &= ACS_ADDR_BIT_MASK;
if (first_acs_addr & 0x1) // even address
{
_ACS_PANEL_B_ADDR = first_acs_addr;
_ACS_PANEL_A_ADDR = first_acs_addr - 1;
}
else // odd address
{
_ACS_PANEL_A_ADDR = first_acs_addr;
_ACS_PANEL_B_ADDR = first_acs_addr + 1;
}
}
bool terminal_config_init(void)
{
bool ret_val = true;
//ret_val &= _save_acs_addrs_from_ext_stor();
//Read ACS ID from external storage
ret_val &= _load_acs_addrs_from_ext_stor();
return ret_val;
}
......@@ -9,6 +9,7 @@
#define BSP_BOARD_CONFIG_H_
#include <stdint.h>
#include <stdbool.h>
//-------------------------------------------------------------
// General settings
......@@ -23,25 +24,40 @@
#define CAN_BAUD_RATE 125000
//-------------------------------------------------------------
// global UID from vendor (from chip)
#define IAP_READ_UID 58
extern unsigned int TERMINAL_UID[5]; // 0 - status code, 1 - least significant word
//-------------------------------------------------------------
// Door addresses in ACS system
// Initialized from external storage
//
// Expected organization
// 0x00: A_ADDR[7:0]
// 0x01: A_ADDR[15:8]
// 0x02: B_ADDR[7:0]
// 0x03; B_ADDR[15:8]
// TODO place in EEPROM at 0x00 a 0x01
extern uint16_t ACC_PANEL_A_ADDR; // even
extern uint16_t ACC_PANEL_B_ADDR; // odd
#define PTR_ACC_PANEL_A_ADDR 0x0 // pointer to external memory
#define PTR_ACC_PANEL_B_ADDR 0x2 // pointer to external memory
// Read from external storage on startup
// Designed to be even (address A) and odd (address B)
// Always true: ADDR_B = ADDR_A + 1
// Address getters
extern uint16_t get_acs_panel_a_addr(void);
extern uint16_t get_acs_panel_b_addr(void);
// Address setter
void set_acs_panel_addr(const uint16_t first_acs_addr);
// Expected organization in external address space:
// | 0x00 | A_ADDR [7:0]
// | 0x01 | A_ADDR [9:8]
// PADDING [15:10]
// The address actually uses less then 16 bits. See address bit width in ACS protocol.
#define PTR_ACS_PANEL_FIRST_ADDR 0x0 // pointer to external memory
// Setting for I2C external storage for door adresses
// (EEPROM, IO EXPANDER or device with same access)
#define STORE_I2C_DEV I2C0
#define STORE_I2C_BUS_FREQ 100000 // 400kHz MAX
#define STORE_I2C_SLAVE_ADDR 0x50 // 7bit address
//-------------------------------------------------------------
// internal number of card readers
#define ACC_PANEL_A 0
......@@ -57,11 +73,6 @@ extern uint16_t ACC_PANEL_B_ADDR; // odd
#define ACS_PANEL_STATUS_LED_PORT 0
#define ACS_PANEL_STATUS_LED_PIN 6
//I2C storage for door IDs (EEPROM, IO EXPANDER or device with same access)
#define STORE_I2C_DEV I2C0
#define STORE_I2C_BUS_FREQ 400000
#define STORE_I2C_SLAVE_ADDR 0x50 // 7bit address
//---------------------------------------------------------------------------------------------------------------------
// Settings for panel A
//---------------------------------------------------------------------------------------------------------------------
......@@ -107,10 +118,11 @@ extern uint16_t ACC_PANEL_B_ADDR; // odd
#define DOOR_2_OPEN_TIME_MS 8000
#define DOOR_2_OK_GLED_TIME_MS 3000
//---------------------------------------------------------------------------------------------------------------------
// Internal setting
// if following is changed it will need code modification
#define WEIGAND_DEVICE_LIMIT 4
#define SERIAL_DEVICE_LIMIT 0
#define DOOR_ACC_PANEL_MAXCOUNT 2
......@@ -130,4 +142,13 @@ extern uint16_t ACC_PANEL_B_ADDR; // odd
#define LOG_HIGH 1
#define LOG_LOW 0
//---------------------------------------------------------------------------------------------------------------------
// Initialize configuration
// @return true if succeeded
bool terminal_config_init(void);
//---------------------------------------------------------------------------------------------------------------------
#endif /* BSP_BOARD_CONFIG_H_ */
......@@ -5,6 +5,8 @@
* Author: Petr
*/
#include "storage.h"
#include "FreeRTOS.h"
#include "task.h"
static void Init_I2C_PinMux(void)
{
......@@ -14,26 +16,27 @@ static void Init_I2C_PinMux(void)
Chip_IOCON_PinMuxSet(LPC_IOCON, 0, 5, IOCON_FUNC1 | I2C_FASTPLUS_BIT);
#elif (defined(BOARD_NXP_XPRESSO_11C24) || defined(BOARD_MCORE48_1125))
Chip_SYSCTL_PeriphReset(RESET_I2C0);
Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO0_4, IOCON_FUNC1 | I2C_FASTPLUS_BIT);
Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO0_5, IOCON_FUNC1 | I2C_FASTPLUS_BIT);
Chip_IOCON_PinMux(LPC_IOCON, IOCON_PIO0_4, IOCON_MODE_INACT, IOCON_FUNC1);
Chip_IOCON_PinMux(LPC_IOCON, IOCON_PIO0_5, IOCON_MODE_INACT, IOCON_FUNC1);
#else
#error "Unsupported board for I2C operation."
#endif
}
void storage_init(I2C_ID_T dev_id, uint32_t freq)
void storage_init(void)
{
configASSERT(freq > 1000);
configASSERT(freq <= 400000);
uint32_t freq = STORE_I2C_BUS_FREQ;
configASSERT(freq > 1000 && freq <= 400000);
Init_I2C_PinMux();
/* Initialize I2C */
Chip_I2C_Init(dev_id);
Chip_I2C_SetClockRate(dev_id, freq);
Chip_I2C_Init(STORE_I2C_DEV);
Chip_I2C_SetClockRate(STORE_I2C_DEV, freq);
/* Set mode to interrupt */
Chip_I2C_SetMasterEventHandler(dev_id, Chip_I2C_EventHandler);
Chip_I2C_SetMasterEventHandler(STORE_I2C_DEV, Chip_I2C_EventHandler);
NVIC_EnableIRQ(I2C0_IRQn);
}
......@@ -41,7 +44,7 @@ bool storage_read_word_le(const uint8_t addr, uint16_t * data)
{
const uint8_t len = sizeof(*data);
uint8_t n_got = Chip_I2C_MasterCmdRead(STORE_I2C_DEV, STORE_I2C_SLAVE_ADDR, addr, data, len);
uint8_t n_got = Chip_I2C_MasterCmdRead(STORE_I2C_DEV, STORE_I2C_SLAVE_ADDR, addr, (uint8_t *)data, len);
return (n_got == len);
}
......
......@@ -12,14 +12,19 @@
#include <stdint.h>
#include <stdbool.h>
void storage_init(I2C_ID_T dev_id, uint32_t freq);
// Initialize I2C bus for storage
void storage_init(void);
// Read a word from address (little-endian)
bool storage_read_word_le(const uint8_t addr, uint16_t * data);
// Write a word to address (little-endian)
bool storage_write_word_le(const uint8_t addr, const uint16_t data);
// Read a byte from address
bool storage_read_byte(const uint8_t addr, uint8_t * data);
// Write a byte to address
bool storage_write_byte(const uint8_t addr, const uint8_t data);
#endif /* BSP_STORAGE_H_ */
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