Commit 644c8c90 authored by Bc. Petr Elexa's avatar Bc. Petr Elexa

Use stream buffer for weigand frames

parent 04350d9b
......@@ -8,10 +8,9 @@
===============================================================================
*/
#include <terminal.h>
#include "board.h"
//#include "canopen_driver.h"
#include "card_reader.h"
/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
......@@ -33,21 +32,29 @@
static void setup_hardware(void)
{
extern unsigned long _vStackTop[], _pvHeapStart[];
unsigned long ulInterruptStackSize;
// Read clock settings and update SystemCoreClock variable
SystemCoreClockUpdate();
// Set up and initialize all required blocks and
// functions related to the board hardware
Board_Init();
#ifdef DEVEL_BOARD
Board_LED_Set(0, false);
Board_LED_Set(1, false);
Board_LED_Set(2, false);
#endif
// Enable INTs for all GPIO ports
NVIC_EnableIRQ(EINT0_IRQn);
NVIC_EnableIRQ(EINT1_IRQn);
NVIC_EnableIRQ(EINT2_IRQn);
NVIC_EnableIRQ(EINT3_IRQn);
// Initialize card reading ability
card_reader_init();
extern unsigned long _vStackTop[], _pvHeapStart[];
unsigned long ulInterruptStackSize;
/* The size of the stack used by main and interrupts is not defined in
the linker, but just uses whatever RAM is left. Calculate the amount of
RAM available for the main/interrupt/system stack, and check it against
......@@ -79,11 +86,12 @@ static void alive_task(void *pvParameters)
int main(void)
{
__disable_irq();
setup_hardware();
xTaskCreate(alive_task, "alive_task",configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 1UL), NULL);
xTaskCreate(alive_task, "alv_tsk",configMINIMAL_STACK_SIZE, NULL, (tskIDLE_PRIORITY + 1UL), NULL);
NVIC_EnableIRQ(EINT3_IRQn);
__enable_irq();
/* Start the kernel. From here on, only tasks and interrupts will run. */
......
......@@ -49,10 +49,10 @@ extern uint32_t SystemCoreClock;
#define configUSE_TICK_HOOK 1
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES ( 8 )
#define configMAX_PRIORITIES ( 6 )
#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 64 )
#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048 ) )
#define configMAX_TASK_NAME_LEN ( 10 )
#define configMAX_TASK_NAME_LEN ( 8 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
......@@ -62,15 +62,16 @@ extern uint32_t SystemCoreClock;
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_MALLOC_FAILED_HOOK 1
#define configUSE_APPLICATION_TASK_TAG 0
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_COUNTING_SEMAPHORES 0
#define configGENERATE_RUN_TIME_STATS 0
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configUSE_TIMERS 0
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 2
#define configTIMER_TASK_STACK_DEPTH ( 80 )
......@@ -79,7 +80,7 @@ extern uint32_t SystemCoreClock;
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskDelete 0
#define INCLUDE_vTaskCleanUpResources 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
......
......@@ -10,16 +10,41 @@
#include "chip.h"
#define WEIGAND_TRANS_BITS 26
#define DEVEL_BOARD
#define CARD_READER1
#define CARD_READER1_PORT 3
#define TERMINAL_ID 1
#define CARD_READER1 0
#define CARD_READER1_ID 1
#define CARD_READER1_PORT 1
#define CARD_READER1_D0_PIN 1
#define CARD_READER1_D1_PIN 2
#define CARD_READER1_RELAY_PORT 0
#define CARD_READER1_RELAY_PIN 0
#define CARD_READER2 0
#define CARD_READER2_ID 2
#define CARD_READER2_PORT 2
#define CARD_READER2_D0_PIN 0
#define CARD_READER2_D1_PIN 0
#define CARD_READER2_RELAY_PORT 0
#define CARD_READER2_RELAY_PIN 0
#define CARD_READER3 1
#define CARD_READER3_ID 3
#define CARD_READER3_PORT 3
#define CARD_READER3_D0_PIN 1
#define CARD_READER3_D1_PIN 2
#define CARD_READER3_RELAY_PORT 0
#define CARD_READER3_RELAY_PIN 0
#define CARD_READER_BEEPER_PORT 0
#define CARD_READER_BEEPER_PIN 0
#define CARD_READER_LED_PORT 0
#define CARD_READER_LED_PIN 0
#define CARD_READERS_MAX_COUNT 4
//#define CARD_READERS_COUNT (CARD_READER1 + CARD_READER2 + CARD_READER3)
#endif /* BSP_BOARD_CONFIG_H_ */
/*
*
* Created on: 24. 8. 2018
* Author: Petr
*/
#include "card_reader.h"
#include "FreeRTOS.h"
#include "task.h"
static weigand26_frame_t _pending_frame = {.value = 0};
void weigand_callback(uint8_t port, weigand26_frame_t frame)
{
_pending_frame.value = frame.value;
}
static void card_reader_task(void *pvParameters)
{
weigand26_frame_t frame;
uint8_t port;
printf("started\n");
while(1)
{
vTaskDelay(150 / portTICK_PERIOD_MS);
if (_pending_frame.value == 0) continue;
portENTER_CRITICAL();
frame.value = _pending_frame.value;
_pending_frame.value = 0;
portEXIT_CRITICAL();
//printf("Frame: 0x%X\n", ((frame & 0x1FFFFFE) >> 1));
printf("Facility: %u Card: %u Parity: %u\n", frame.facility_code, frame.card_number, weigand_parity_ok(frame));
}
}
void card_reader_init(void)
{
weigand_init(CARD_READER1_PORT, CARD_READER1_D0_PIN, CARD_READER1_D1_PIN);
xTaskCreate(card_reader_task, "card_task", configMINIMAL_STACK_SIZE + 64, NULL, (tskIDLE_PRIORITY + 1UL), NULL);
}
/*
*
* Created on: 24. 8. 2018
* Author: Petr
*/
#include "terminal.h"
#include "weigand.h"
#include "board_config.h"
#include "FreeRTOS.h"
#include "task.h"
#include "stream_buffer.h"
static StreamBufferHandle_t cr_stream[CARD_READERS_MAX_COUNT];
static void terminal_process_card(uint16_t card_number, uint8_t facility_code, uint8_t reader_id)
{
printf("Facility: %u Card: %u Parity: %u\n", facility_code, card_number);
}
static void card_reader_task(void *pvParameters)
{
weigand26_frame_t card_data;
size_t bytes_got;
printf("card_task\n");
while(true)
{
#if CARD_READER1
bytes_got = xStreamBufferReceive(cr_stream[CARD_READER1_ID], &card_data, sizeof card_data, pdMS_TO_TICKS(0));
if (bytes_got == sizeof card_data && weigand_is_parity_ok(card_data))
{
terminal_process_card(card_data.facility_code, card_data.card_number, CARD_READER1_ID);
}
#endif
#if CARD_READER2
bytes_got = xStreamBufferReceive(cr_stream[CARD_READER2_ID], &card_data, sizeof card_data, pdMS_TO_TICKS(0));
if (bytes_got == sizeof card_data && weigand_is_parity_ok(card_data))
{
terminal_process_card(card_data.facility_code, card_data.card_number, CARD_READER2_ID);
}
#endif
#if CARD_READER3
bytes_got = xStreamBufferReceive(cr_stream[CARD_READER3_ID], &card_data, sizeof card_data, pdMS_TO_TICKS(0));
if (bytes_got == sizeof card_data && weigand_is_parity_ok(card_data))
{
terminal_process_card(card_data.facility_code, card_data.card_number, CARD_READER3_ID);
}
#endif
}
}
void card_reader_init(void)
{
#if CARD_READER1
cr_stream[CARD_READER1_ID] = weigand_init(CARD_READER1_PORT, CARD_READER1_D0_PIN, CARD_READER1_D1_PIN);
#endif
#if CARD_READER2
cr_stream[CARD_READER2_ID] = weigand_init(CARD_READER2_PORT, CARD_READER2_D0_PIN, CARD_READER2_D1_PIN);
#endif
#if CARD_READER3
cr_stream[CARD_READER3_ID] = weigand_init(CARD_READER3_PORT, CARD_READER3_D0_PIN, CARD_READER3_D1_PIN);
#endif
xTaskCreate(card_reader_task, "crd_tsk", configMINIMAL_STACK_SIZE + 64, NULL, (tskIDLE_PRIORITY + 1UL), NULL);
}
......@@ -5,11 +5,9 @@
* Author: Petr
*/
#ifndef BSP_CARD_READER_H_
#define BSP_CARD_READER_H_
#include "weigand.h"
#ifndef BSP_TERMINAL_H_
#define BSP_TERMINAL_H_
void card_reader_init(void);
#endif /* BSP_CARD_READER_H_ */
#endif /* BSP_TERMINAL_H_ */
......@@ -8,11 +8,13 @@
#ifndef BSP_WEIGAND_H_
#define BSP_WEIGAND_H_
#include "stdbool.h"
#include "stdint.h"
#include "limits.h"
#include "chip.h"
#include "board_config.h"
#include <stdbool.h>
#include <stdint.h>
#include "FreeRTOS.h"
#include "task.h"
#include "stream_buffer.h"
#define WEIGAND26_FRAME_SIZE 26
typedef union{
struct{
......@@ -20,7 +22,7 @@ typedef union{
uint32_t card_number : 16;
uint32_t facility_code : 8;
uint32_t even_parity: 1;
uint32_t : 6;
uint32_t : 6; //padding
};
uint32_t value;
}weigand26_frame_t;
......@@ -31,21 +33,20 @@ typedef struct {
uint8_t port;
uint8_t pin_d0;
uint8_t pin_d1;
}weigand_t;
StreamBufferHandle_t consumer_buffer;
}weigand26_t;
weigand_t * weigand_init(uint8_t dx_port, uint8_t d0_pin, uint8_t d1_pin);
StreamBufferHandle_t weigand_init(uint8_t dx_port, uint8_t d0_pin, uint8_t d1_pin);
bool weigand_pending_frame(weigand_t * instance);
bool weigand_pending_frame(weigand26_t * instance);
weigand26_frame_t weigand_get_frame(weigand_t * instance);
weigand26_frame_t weigand_get_frame(weigand26_t * instance);
uint32_t weigand_get_facility(weigand26_frame_t frame);
uint32_t weigand_get_card(weigand26_frame_t frame);
bool weigand_parity_ok(weigand26_frame_t frame);
void weigand_callback(uint8_t port, weigand26_frame_t frame);
bool weigand_is_parity_ok(weigand26_frame_t frame);
#endif /* BSP_WEIGAND_H_ */
......@@ -11,46 +11,60 @@
*/
#include "weigand.h"
#include "chip.h"
#include "board_config.h"
#include <limits.h>
#include <assert.h>
static weigand_t instance[4];
static weigand26_t device[CARD_READERS_MAX_COUNT];
weigand_t * weigand_init(uint8_t dx_port, uint8_t d0_pin, uint8_t d1_pin)
StreamBufferHandle_t weigand_init(uint8_t dx_port, uint8_t d0_pin, uint8_t d1_pin)
{
if (dx_port > 3) return NULL;
instance[dx_port].port = dx_port;
instance[dx_port].pin_d0 = d0_pin;
instance[dx_port].pin_d1 = d1_pin;
instance[dx_port].frame_buffer.value = 0;
instance[dx_port].frame_buffer_ptr = WEIGAND_TRANS_BITS;
//Save device information
device[dx_port].port = dx_port;
device[dx_port].pin_d0 = d0_pin;
device[dx_port].pin_d1 = d1_pin;
device[dx_port].frame_buffer.value = 0;
device[dx_port].frame_buffer_ptr = WEIGAND26_FRAME_SIZE;
//Enable pullups
Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO3_1, IOCON_MODE_PULLUP);
Chip_IOCON_PinMuxSet(LPC_IOCON, IOCON_PIO3_2, IOCON_MODE_PULLUP);
//Input mode
Chip_GPIO_SetPinDIRInput(LPC_GPIO, dx_port, d0_pin);
Chip_GPIO_SetPinDIRInput(LPC_GPIO, dx_port, d1_pin);
//Trigger on falling edge
Chip_GPIO_SetupPinInt(LPC_GPIO, dx_port, d0_pin, GPIO_INT_FALLING_EDGE);
Chip_GPIO_SetupPinInt(LPC_GPIO, dx_port, d1_pin, GPIO_INT_FALLING_EDGE);
//Clear INTs
Chip_GPIO_ClearInts(LPC_GPIO, dx_port, (1 << d0_pin));
Chip_GPIO_ClearInts(LPC_GPIO, dx_port, (1 << d1_pin));
Chip_GPIO_EnableInt(LPC_GPIO, dx_port, (1 << d0_pin) | (1 << d1_pin));
//Create stream
device[dx_port].consumer_buffer = xStreamBufferCreate(sizeof(weigand26_frame_t), sizeof(weigand26_frame_t));
assert(device[dx_port].consumer_buffer);
return &instance[dx_port];
//Enable INT for both pins
Chip_GPIO_EnableInt(LPC_GPIO, dx_port, (1 << d0_pin) | (1 << d1_pin));
return device[dx_port].consumer_buffer;
}
bool weigand_pending_frame(weigand_t * instance)
bool weigand_pending_frame(weigand26_t * device)
{
return instance->frame_buffer_ptr == 0;
return device->frame_buffer_ptr == 0;
}
weigand26_frame_t weigand_get_frame(weigand_t * instance)
weigand26_frame_t weigand_get_frame(weigand26_t * device)
{
return instance->frame_buffer;
return device->frame_buffer;
}
uint32_t weigand_get_facility(weigand26_frame_t frame)
......@@ -63,64 +77,88 @@ uint32_t weigand_get_card(weigand26_frame_t frame)
return (frame.value & 0x1FFFE) >> 1;
}
bool weigand_parity_ok(weigand26_frame_t frame)
bool weigand_is_parity_ok(weigand26_frame_t frame)
{
uint8_t even_parity = __builtin_parity(frame.value & 0x1FFE000);
uint8_t odd_parity = __builtin_parity(frame.value & 0x1FFE) ^ 1;
return even_parity == ((frame.value >> 25) & 0x1) && odd_parity == (frame.value & 0x1);
}
void weigand_int_handler(weigand_t * instance)
void weigand_int_handler(weigand26_t * device)
{
uint32_t int_states = Chip_GPIO_GetMaskedInts(LPC_GPIO, instance->port);
Chip_GPIO_ClearInts(LPC_GPIO, instance->port, (1 << instance->pin_d1));
Chip_GPIO_ClearInts(LPC_GPIO, instance->port, (1 << instance->pin_d0));
uint32_t int_states = Chip_GPIO_GetMaskedInts(LPC_GPIO, device->port);
//Clear int flag on each pin
Chip_GPIO_ClearInts(LPC_GPIO, device->port, (1 << device->pin_d1));
Chip_GPIO_ClearInts(LPC_GPIO, device->port, (1 << device->pin_d0));
if (int_states & (1 << instance->pin_d1))
//Resolve bit value
if (int_states & (1 << device->pin_d1))
{
if (Chip_GPIO_ReadPortBit(LPC_GPIO, instance->port, instance->pin_d1) == 0)
if (Chip_GPIO_ReadPortBit(LPC_GPIO, device->port, device->pin_d1) == 0)
{
instance->frame_buffer_ptr--;
instance->frame_buffer.value |= (1 << instance->frame_buffer_ptr);
device->frame_buffer_ptr--;
device->frame_buffer.value |= (1 << device->frame_buffer_ptr);
}
}
else if (int_states & (1 << instance->pin_d0))
else if (int_states & (1 << device->pin_d0))
{
if (Chip_GPIO_ReadPortBit(LPC_GPIO, instance->port, instance->pin_d0) == 0)
if (Chip_GPIO_ReadPortBit(LPC_GPIO, device->port, device->pin_d0) == 0)
{
instance->frame_buffer_ptr--;
instance->frame_buffer.value &= ~(1 << instance->frame_buffer_ptr);
device->frame_buffer_ptr--;
device->frame_buffer.value &= ~(1 << device->frame_buffer_ptr);
}
}
else
{
Chip_GPIO_ClearInts(LPC_GPIO, instance->port, 0xFFFFFFFF);
Chip_GPIO_ClearInts(LPC_GPIO, device->port, 0xFFFFFFFF);
}
if (instance->frame_buffer_ptr == 0)
//Whole frame received
if (device->frame_buffer_ptr == 0)
{
//TODO move from int handler
//TODO check parity (not here)
weigand_callback(instance->port, instance->frame_buffer);
instance->frame_buffer_ptr = WEIGAND_TRANS_BITS;
instance->frame_buffer.value = 0;
xStreamBufferReset(device->consumer_buffer);
BaseType_t pxHigherPriorityTaskWoken = pdFALSE;
size_t bytes_sent = xStreamBufferSendFromISR(
device->consumer_buffer,
&device->frame_buffer,
sizeof(weigand26_frame_t),
&pxHigherPriorityTaskWoken);
//Stream buffer should be empty because we reset it
assert(bytes_sent == sizeof(weigand26_frame_t));
device->frame_buffer_ptr = WEIGAND26_FRAME_SIZE;
device->frame_buffer.value = 0;
portYIELD_FROM_ISR(pxHigherPriorityTaskWoken);
}
}
//GPIO port 1 handler
void PIOINT0_IRQHandler(void)
{
NVIC_ClearPendingIRQ(EINT1_IRQn);
weigand_int_handler(&device[0]);
}
//GPIO port 1 handler
void PIOINT1_IRQHandler(void)
{
NVIC_ClearPendingIRQ(EINT1_IRQn);
weigand_int_handler(&instance[1]);
weigand_int_handler(&device[1]);
}
//GPIO port 2 handler
void PIOINT2_IRQHandler(void)
{
NVIC_ClearPendingIRQ(EINT2_IRQn);
weigand_int_handler(&instance[2]);
weigand_int_handler(&device[2]);
}
//GPIO port 3 handler
void PIOINT3_IRQHandler(void)
{
NVIC_ClearPendingIRQ(EINT3_IRQn);
weigand_int_handler(&instance[3]);
weigand_int_handler(&device[3]);
}
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