ADC debugged and functional now

Added Version interface

Added DisplayDevice to create an independent bridge between display app and specific display driver

git-svn-id: https://svn.vbchaos.nl/svn/hsb/trunk@228 05563f52-14a8-4384-a975-3d1654cca0fa
This commit is contained in:
mmi
2017-10-04 09:06:16 +00:00
parent 802e9c64ca
commit c613e64e8a
24 changed files with 1147 additions and 231 deletions

View File

@@ -11,7 +11,7 @@ ROOTDIR = ../
LIBRARY_NAME = libPlatform.a
CCFLAGS = -c -O2 -Wall -g -fno-common -mcpu=cortex-m3 -mthumb -DOLI_STM32_H107 \
CCFLAGS = -c -O2 -Wall -g -fno-common -mcpu=cortex-m3 -mthumb $(PLATFORM) $(RELEASE_DEFINES) \
-Iinc \
-I$(ROOTDIR)/HAL/inc \
-I$(ROOTDIR)/hsb-mrts/inc \
@@ -25,13 +25,16 @@ ARFLAGS = rs
OBJECTS = \
stm32f10x_it.o \
adc.o \
IODevice.o \
keypadMatrix.o \
led.o \
oli_stm32_h107.o \
PCBA.o \
rtc.o \
spi.o \
spiDevice.o \
uart.o \
oli_stm32_h107.o \
Version.o \
vpath %.o $(OBJDIR)

View File

@@ -0,0 +1,70 @@
// -----------------------------------------------------------------------------
/// @file IODevice.h
/// @brief File description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
/// @defgroup {group_name} {group_description}
/// Description
/// @file IODevice.h
/// @ingroup {group_name}
#ifndef MISC_INC_IODEVICE_H_
#define MISC_INC_IODEVICE_H_
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include <stdio.h>
#include "stm32f10x.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Type definitions.
// -----------------------------------------------------------------------------
struct IODevice;
typedef ErrorStatus (*ReadFunction)(const struct IODevice* self, char* buffer, size_t length, size_t* actualLength);
typedef ErrorStatus (*WriteFunction)(const struct IODevice* self, const char* buffer, size_t length);
struct IODevice
{
ReadFunction _read;
WriteFunction _write;
};
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
extern ErrorStatus IODevice_construct (struct IODevice* self, ReadFunction read, WriteFunction write);
extern ErrorStatus IODevice_write(const struct IODevice* self, const char* buffer, size_t length);
extern ErrorStatus IODevice_read(const struct IODevice* self, char* buffer, size_t length, size_t* actualLength);
#endif /* MISC_INC_IODEVICE_H_ */

View File

@@ -69,18 +69,16 @@ struct Pcba
* PCBA_construct
* Initializes the PCBA information of the hardware.
* PCBA information is defined via placed resistors
* This function can only be called once. Within the first call an internal flag
* is set to prevent any further calling. That is because the PCBA information
* cannot change during run-time
* This function creates a singleton. Calling this function for the first time
* constructs the PCBA information. Calling it afterwards returns the already
* constructed data
*
* @param self The PCBA information
* @return struct Pcba* The PCBA information singelton
*
* @return ErrorStatus SUCCESS if construction was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus PCBA_construct(struct Pcba* self);
extern struct Pcba* PCBA_getInstance(void);
#endif /* PCBA_H_ */

View File

@@ -0,0 +1,77 @@
// -----------------------------------------------------------------------------
/// @file Version.h
/// @brief File description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2015 Micro-Key bv
// -----------------------------------------------------------------------------
/// @defgroup {group_name} {group_description}
/// Description
/// @file Version.h
/// @ingroup {group_name}
#ifndef INC_VERSION_H_
#define INC_VERSION_H_
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "stm32f10x.h"
#include "platform.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Type definitions.
// -----------------------------------------------------------------------------
struct Version
{
int major;
int minor;
int branch;
int patch;
};
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
/** ----------------------------------------------------------------------------
* Version_getInstance
* Initialises the Version information.
* Version information is supplied via macros in makefile
* This function creates a singleton. Calling this function for the first time
* constructs the Version information. Calling it afterwards returns the already
* constructed data
*
* @return struct Version* The Version information singleton
*
*
* @todo
* -----------------------------------------------------------------------------
*/
extern struct Version* Version_getInstance(void);
#endif /* INC_VERSION_H_ */

View File

@@ -31,6 +31,8 @@
// Include files
// -----------------------------------------------------------------------------
#include <stdbool.h>
#include "platform.h"
#include "IODevice.h"
@@ -42,21 +44,55 @@
// -----------------------------------------------------------------------------
#define ADC_NUMBER_OF_CHANNELS (18) // 16 IOs + Temp + Vcc
// -----------------------------------------------------------------------------
// Type definitions.
// -----------------------------------------------------------------------------
struct Adc; // Prototype
struct AdcChannelParameters
{
uint8_t channel;
uint8_t Rank;
uint8_t ADC_SampleTime;
};
struct AdcChannel
{
struct IODevice device;
struct Adc* parent;
uint8_t channel;
uint8_t Rank;
uint8_t ADC_SampleTime;
T_PL_GPIO input;
};
struct AdcParameters
{
uint32_t ADC_Mode;
FunctionalState ADC_ScanConvMode;
FunctionalState ADC_ContinuousConvMode;
uint32_t ADC_ExternalTrigConv;
uint32_t ADC_DataAlign;
uint8_t ADC_NbrOfChannel;
};
struct Adc
{
struct IODevice device;
ADC_InitTypeDef adc_InitStruct;
T_PL_GPIO input;
ADC_TypeDef* ADCx;
ADC_InitTypeDef ADC_InitStruct;
bool useDMA;
bool useRanks;
struct AdcChannel channel[ADC_NUMBER_OF_CHANNELS];
// Only necessary when the RANK parameter determines conversion order or RANK is used anyway
// For single conversions the READ function simply returns the converted value
// Note that the content of this array IS NOT SORTED BY CHANNEL NUMBER but sorted BY RANK NUMBER
// When initialising an ADC channel to a regular group, the RANK parameter determines the
// order of convertions. E.G. channel 5 can be put first while channel 1 can be put last.
// The array index stands for the RANK
uint16_t channelValue[ADC_NUMBER_OF_CHANNELS];
};
// -----------------------------------------------------------------------------
@@ -79,4 +115,118 @@ struct Adc
*/
extern ErrorStatus ADC_construct(struct Adc* self, struct AdcParameters* parameters);
/** ----------------------------------------------------------------------------
* ADC_destruct
* Destructor for an ADC instance
*
* @param self The ADC instance to destruct
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern void ADC_destruct(struct Adc* self);
/** ----------------------------------------------------------------------------
* ADC_performInternalCalibration
* Apply internal ADC calibration to ADC instance
* ADC calibration is RESET and afterwards set.
*
* @param self The ADC instance to calibrate
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus ADC_performInternalCalibration(const struct Adc* self);
/** ----------------------------------------------------------------------------
* ADC_setStatus
* Changes the status of the ADC instance
*
* @param self The ADC instance
* @param command new command for the ADC instance
* - ENABLE
* - DISABLE
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus ADC_setStatus (struct Adc* self, FunctionalState command);
/** ----------------------------------------------------------------------------
* ADC_setDMAStatus
* Changes the status of the ADC instance's DMA
*
* @param self The ADC instance
* @param command new command for the ADC instance
* - ENABLE
* - DISABLE
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus ADC_setDMAStatus (struct Adc* self, FunctionalState command);
/** ----------------------------------------------------------------------------
* ADCChannel_construct
* Constructor for ADC channel instance
*
* @param self The ADC channel instance to initialize
* @param parameters Additional ADC parameters
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus ADCChannel_construct(struct AdcChannel* self, struct AdcChannelParameters* parameters);
/** ----------------------------------------------------------------------------
* ADCChannel_destruct
* Destructor for an ADC channel instance
*
* @param self The ADC channel instance to destruct
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern void ADCChannel_destruct(struct AdcChannel* self);
/** ----------------------------------------------------------------------------
* ADCChannel_read
* Read the current conversion value of the ADC channel in argument self
*
* @param self ADC channel object
* @param value The read value
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus ADCChannel_read(struct AdcChannel* self, uint16_t* value);
#endif /* INC_ADC_H_ */

View File

@@ -0,0 +1,141 @@
// -----------------------------------------------------------------------------
/// @file keypadMatrix.h
/// @brief File description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
/// @defgroup {group_name} {group_description}
/// Description
/// @file keypadMatrix.h
/// @ingroup {group_name}
#ifndef KEYPAD_INC_KEYPADMATRIX_H_
#define KEYPAD_INC_KEYPADMATRIX_H_
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include "platform.h"
#include "IODevice.h"
#include "stm32f10x_exti.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
#define KEYPAD_NUMBER_OF_ROWS (4)
#define KEYPAD_NUMBER_OF_COLUMNS (4)
// -----------------------------------------------------------------------------
// Type definitions.
// -----------------------------------------------------------------------------
struct KeypadQueueItem
{
char byte;
};
typedef enum
{
RELEASED = 0,
PRESSED = (!RELEASED)
}Keypad_KeyState;
struct keypadElement
{
T_PL_GPIO gpio;
EXTI_InitTypeDef EXTI_InitStruct;
};
struct Keypad
{
struct IODevice device;
struct keypadElement row[KEYPAD_NUMBER_OF_ROWS];
struct keypadElement column[KEYPAD_NUMBER_OF_COLUMNS];
Keypad_KeyState lastState[KEYPAD_NUMBER_OF_ROWS][KEYPAD_NUMBER_OF_COLUMNS];
xTaskHandle taskHandle;
SemaphoreHandle_t scanSemaphore;
xQueueHandle rxQueue;
int waitToDebounce_ms;
};
struct KeypadParameters
{
int rxQueueSize;
};
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
/** ----------------------------------------------------------------------------
* Keypad_construct
* contructor for the Keypad driver
*
* @param self Keypad object to initialize
* @param parameters Parameters to use for initialisation
* @param debounceTime debounce time for the keypad to use
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus Keypad_construct(struct Keypad* self, struct KeypadParameters* parameters, int debounceTime);
/** ----------------------------------------------------------------------------
* Keypad_destruct
* destructor for the Keypad driver
*
* @param self Keypad object to destruct
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern void Keypad_destruct (const struct Keypad* self);
/** ----------------------------------------------------------------------------
* Keypad_getDefaultParameters
* Returns default parameters for a keypad
*
* @param parameters Keypad parameters struct that will be
* filled with default values
*
* @return ErrorStatus SUCCESS if initialisation was successful
* ERROR otherwise
*
* @todo
* -----------------------------------------------------------------------------
*/
extern ErrorStatus Keypad_getDefaultParameters(struct KeypadParameters* parameters);
#endif /* KEYPAD_INC_KEYPADMATRIX_H_ */

View File

@@ -61,11 +61,13 @@ typedef struct
} T_PL_GPIO;
// Export of PCBA information
extern struct Pcba* const pcba;
extern struct Pcba* pcba;
// Export of LEDs
extern struct Led* const ledGreen;
extern struct Led* const ledOrange;
// Export of ADCs
extern struct Adc* const adc1;
// Export of the rtc
extern struct Rtc* const rtc;
// Export of UARTs

View File

@@ -0,0 +1,78 @@
// -----------------------------------------------------------------------------
/// @file IODevice.c
/// @brief Description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
/// @file IODevice.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "IODevice.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus IODevice_construct (struct IODevice* self, ReadFunction read, WriteFunction write)
{
ErrorStatus returnValue = SUCCESS;
self->_write = write;
self->_read = read;
return returnValue;
}
ErrorStatus IODevice_write(const struct IODevice* self, const char* buffer, size_t length)
{
ErrorStatus returnValue = SUCCESS;
if (self->_write != NULL)
{
returnValue = self->_write(self, buffer, length);
}
return returnValue;
}

View File

@@ -24,12 +24,9 @@
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include <stdbool.h>
#include "PCBA.h"
#include "Logger.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
@@ -46,7 +43,9 @@
// File-scope variables
// -----------------------------------------------------------------------------
static bool initialized = false;
static struct Pcba* instance = NULL;
static struct Pcba thisPCBA;
static const char nameArray[4][20] =
{
"Cathode/MCP repair ",
@@ -59,30 +58,38 @@ static const char nameArray[4][20] =
// Function declarations
// -----------------------------------------------------------------------------
static ErrorStatus PCBA_construct(struct Pcba* self);
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus PCBA_construct(struct Pcba* self)
struct Pcba* PCBA_getInstance(void)
{
ErrorStatus returnValue = SUCCESS;
if (!initialized)
if (instance == NULL)
{
instance = &thisPCBA;
returnValue = PCBA_construct(instance);
uint8_t A0 = GPIO_ReadInputDataBit(self->A0.GPIO_Typedef, self->A0.GPIO_InitStruct.GPIO_Pin);
uint8_t A1 = GPIO_ReadInputDataBit(self->A1.GPIO_Typedef, self->A1.GPIO_InitStruct.GPIO_Pin);
self->pcba = (A0 & 0x01) | ((A1 << 1) & 0x02);
snprintf(self->name, (sizeof(self->name) / sizeof(self->name[0])), "%s", nameArray[self->pcba]);
initialized = true;
}
else
{
returnValue = ERROR;
if (returnValue != SUCCESS)
{
instance = NULL;
}
}
return instance;
}
static ErrorStatus PCBA_construct(struct Pcba* self)
{
ErrorStatus returnValue = SUCCESS;
uint8_t A0 = GPIO_ReadInputDataBit(self->A0.GPIO_Typedef, self->A0.GPIO_InitStruct.GPIO_Pin);
uint8_t A1 = GPIO_ReadInputDataBit(self->A1.GPIO_Typedef, self->A1.GPIO_InitStruct.GPIO_Pin);
self->pcba = (A0 & 0x01) | ((A1 << 1) & 0x02);
snprintf(self->name, (sizeof(self->name) / sizeof(self->name[0])), "%s", nameArray[self->pcba]);
return returnValue;
}

View File

@@ -0,0 +1,85 @@
// -----------------------------------------------------------------------------
/// @file Version.c
/// @brief Description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
/// @file Version.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include "Version.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
static struct Version* instance = NULL;
static struct Version thisVersion;
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
static ErrorStatus Version_construct(struct Version* self);
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
struct Version* Version_getInstance(void)
{
ErrorStatus returnValue = SUCCESS;
if (instance == NULL)
{
instance = &thisVersion;
returnValue = Version_construct(instance);
if (returnValue != SUCCESS)
{
instance = NULL;
}
}
return instance;
}
static ErrorStatus Version_construct(struct Version* self)
{
ErrorStatus returnValue = SUCCESS;
self->major = RELEASE_MAJOR;
self->minor = RELEASE_MINOR;
self->branch = RELEASE_BRANCH;
self->patch = RELEASE_PATCH;
return returnValue;
}

View File

@@ -60,14 +60,156 @@ ErrorStatus ADC_construct(struct Adc* self, struct AdcParameters* parameters)
{
ErrorStatus returnValue = SUCCESS;
IODevice_construct(&self->device, read, NULL);
self->useDMA = false;
self->ADC_InitStruct.ADC_Mode = parameters->ADC_Mode;
self->ADC_InitStruct.ADC_ScanConvMode = parameters->ADC_ScanConvMode;
self->ADC_InitStruct.ADC_ContinuousConvMode = parameters->ADC_ContinuousConvMode;
self->ADC_InitStruct.ADC_ExternalTrigConv = parameters->ADC_ExternalTrigConv;
self->ADC_InitStruct.ADC_DataAlign = parameters->ADC_DataAlign;
self->ADC_InitStruct.ADC_NbrOfChannel = parameters->ADC_NbrOfChannel;
ADC_DeInit(self->ADCx);
ADC_Init(self->ADCx, &self->ADC_InitStruct);
return returnValue;
}
void ADC_destruct (struct Adc* self)
{
int channelCounter;
for (channelCounter = 0; channelCounter < ADC_NUMBER_OF_CHANNELS; channelCounter++)
{
}
ADC_DeInit(self->ADCx);
self->useDMA = false;
self->useRanks = false;
}
ErrorStatus ADC_performInternalCalibration(const struct Adc* self)
{
ErrorStatus returnValue = SUCCESS;
/* Enable ADC1 reset calibration register */
ADC_ResetCalibration(self->ADCx);
/* Check the end of ADC1 reset calibration register */
while(ADC_GetResetCalibrationStatus(self->ADCx));
/* Start ADC1 calibration */
ADC_StartCalibration(self->ADCx);
/* Check the end of ADC1 calibration */
while(ADC_GetCalibrationStatus(self->ADCx));
return returnValue;
}
ErrorStatus ADC_setStatus (struct Adc* self, FunctionalState command)
{
ErrorStatus returnValue = SUCCESS;
ADC_Cmd(self->ADCx, command);
return returnValue;
}
ErrorStatus ADC_setDMAStatus (struct Adc* self, FunctionalState command)
{
ErrorStatus returnValue = SUCCESS;
ADC_DMACmd(self->ADCx, command);
if (command == ENABLE)
{
self->useDMA = true;
}
else
{
self->useDMA = false;
}
return returnValue;
}
ErrorStatus ADCChannel_construct(struct AdcChannel* self, struct AdcChannelParameters* parameters)
{
ErrorStatus returnValue = SUCCESS;
IODevice_construct(&self->device, read, NULL);
if ((parameters->Rank) > 0 && (parameters->Rank <= 16))
{
self->Rank = parameters->Rank;
}
else
{
returnValue = ERROR;
}
if (parameters->channel < 18)
{
self->channel = parameters->channel;
}
else
{
returnValue = ERROR;
}
if (returnValue == SUCCESS)
{
self->ADC_SampleTime = parameters->ADC_SampleTime;
//TODO MAKE SURE EACH RANK IS USED ONLY ONCE
ADC_RegularChannelConfig(self->parent->ADCx, self->channel, self->Rank, self->ADC_SampleTime);
self->parent->useRanks = true;
}
return returnValue;
}
void ADCChannel_destruct(struct AdcChannel* self)
{
}
ErrorStatus ADCChannel_read(struct AdcChannel* self, uint16_t* value)
{
ErrorStatus returnValue = SUCCESS;
// For reading it is important whether Ranks are enabled or not
if (self->parent->useRanks)
{
// Rank starts with 1 - must be reduced by one in order tu be used as index
*value = self->parent->channelValue[self->Rank - 1];
}
return returnValue;
}
static ErrorStatus read(const struct IODevice* self, char* buffer, size_t length, size_t* actualLength)
{
ErrorStatus returnValue = SUCCESS;
(void)length;
uint16_t adcValue = 0;
returnValue = ADCChannel_read((struct AdcChannel*)self, &adcValue);
buffer[0] = adcValue >> 8;
buffer[1] = adcValue;
*actualLength = 2;
return returnValue;
}

View File

@@ -0,0 +1,226 @@
// -----------------------------------------------------------------------------
/// @file keypadMatrix.c
/// @brief Description
// -----------------------------------------------------------------------------
// Micro-Key bv
// Industrieweg 28, 9804 TG Noordhorn
// Postbus 92, 9800 AB Zuidhorn
// The Netherlands
// Tel: +31 594 503020
// Fax: +31 594 505825
// Email: support@microkey.nl
// Web: www.microkey.nl
// -----------------------------------------------------------------------------
/// $Revision$
/// $Author$
/// $Date$
// (c) 2017 Micro-Key bv
// -----------------------------------------------------------------------------
/// @file keypadMatrix.c
/// @ingroup {group_name}
// -----------------------------------------------------------------------------
// Include files
// -----------------------------------------------------------------------------
#include <stdbool.h>
#include <stdio.h>
#include "FreeRTOSFixes.h"
#include "Logger.h"
#include "keypadMatrix.h"
#include "platform.h"
#include "stm32f10x_it.h"
// -----------------------------------------------------------------------------
// Constant and macro definitions
// -----------------------------------------------------------------------------
#define KEYPAD_STACK_SIZE (512)
#define KEYPAD_TASK_PRIORITY (3)
#define KEYPAD_DEF_QUEUESIZE (32)
// -----------------------------------------------------------------------------
// Type definitions
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// File-scope variables
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Function declarations
// -----------------------------------------------------------------------------
static ErrorStatus read(const struct IODevice* self, char* buffer, size_t length, size_t* actualLength);
static void KeypadTask(void* parameters);
// -----------------------------------------------------------------------------
// Function definitions
// -----------------------------------------------------------------------------
ErrorStatus Keypad_construct(struct Keypad* self, struct KeypadParameters* parameters, int debounceTime)
{
int rowCounter = 0;
int colCounter = 0;
ErrorStatus returnValue = SUCCESS;
if(keypad != NULL)
{
IODevice_construct(&self->device, read, NULL);
if(returnValue == SUCCESS)
{
//! Create semaphore to synchronize with Keypad/EXTI interrupt handler
vSemaphoreCreateBinary(self->scanSemaphore);
}
self->waitToDebounce_ms = debounceTime;
// Initialize memory to keep track of state changes per key
for (rowCounter = 0; rowCounter < KEYPAD_NUMBER_OF_ROWS; rowCounter++)
{
for (colCounter = 0; colCounter < KEYPAD_NUMBER_OF_COLUMNS; colCounter++)
{
self->lastState[rowCounter][colCounter] = RELEASED;
}
}
//! Create a new FREERTOS queue to handle data from Keypad input to app
self->rxQueue = xQueueCreate(parameters->rxQueueSize, sizeof(struct KeypadQueueItem));
if (self->rxQueue == 0)
{
//! Queue identifier is 0 -> error
returnValue = ERROR; //! Set error flag
}
if(returnValue == SUCCESS)
{
xTaskCreate(KeypadTask, (const char*)"keypadTask", KEYPAD_STACK_SIZE, keypad, KEYPAD_TASK_PRIORITY, self->taskHandle);
}
if(returnValue == SUCCESS)
{
//! take txSemaphore
if (xSemaphoreTake(self->scanSemaphore, 0) == pdFALSE)
{
//! An error has occurred
returnValue = ERROR;
}
}
if(returnValue == SUCCESS)
{
LOGGER_INFO("Keypad task started");
}
else
{
LOGGER_ERROR("Keypad task FAILED");
}
}
return returnValue;
}
void Keypad_Destruct (const struct Keypad* self)
{
vTaskDelete(self->taskHandle);
vQueueDelete(self->rxQueue);
}
ErrorStatus Keypad_getDefaultParameters(struct KeypadParameters* parameters)
{
ErrorStatus errorStatus = SUCCESS;
parameters->rxQueueSize = KEYPAD_DEF_QUEUESIZE;
return errorStatus;
}
static ErrorStatus read(const struct IODevice* self, char* buffer, size_t length, size_t* actualLength)
{
ErrorStatus errorStatus = SUCCESS;
*actualLength = 1;
return errorStatus;
}
static void KeypadTask(void* parameters)
{
int rowCounter = 0;
int colCounter = 0;
struct Keypad* self = (struct Keypad*) parameters;
while (1)
{
// Wait for an interrupt to occur on one of the keypad columns
xSemaphoreTake(self->scanSemaphore, portMAX_DELAY);
// Debounce the keypad and wait for debounceTime prior to do anything
vTaskDelay(self->waitToDebounce_ms);
// Set all row outputs
for (rowCounter = 0; rowCounter < KEYPAD_NUMBER_OF_ROWS; rowCounter++)
{
GPIO_SetBits(self->row[rowCounter].gpio.GPIO_Typedef, self->row[rowCounter].gpio.GPIO_InitStruct.GPIO_Pin);
}
// Scan through each row individually by resetting it (output level low) and check all column levels
for (rowCounter = 0; rowCounter < KEYPAD_NUMBER_OF_ROWS; rowCounter++)
{
GPIO_ResetBits(self->row[rowCounter].gpio.GPIO_Typedef, self->row[rowCounter].gpio.GPIO_InitStruct.GPIO_Pin);
for (colCounter = 0; colCounter < KEYPAD_NUMBER_OF_COLUMNS; colCounter++)
{
if (GPIO_ReadInputDataBit(self->column[colCounter].gpio.GPIO_Typedef, self->column[colCounter].gpio.GPIO_InitStruct.GPIO_Pin) == (uint8_t)Bit_SET)
{
if (self->lastState[rowCounter][colCounter] == PRESSED)
{
self->lastState[rowCounter][colCounter] = RELEASED;
// Key has been released
LOGGER_DEBUG("KEY row%d, column%d released", rowCounter, colCounter);
}
else
{
// nothing changed
}
}
else
{
if (self->lastState[rowCounter][colCounter] == RELEASED)
{
self->lastState[rowCounter][colCounter] = PRESSED;
// Key has been pressed
LOGGER_DEBUG("KEY row%d, column%d pressed", rowCounter, colCounter);
}
else
{
// nothing changed
}
}
}
GPIO_SetBits(self->row[rowCounter].gpio.GPIO_Typedef, self->row[rowCounter].gpio.GPIO_InitStruct.GPIO_Pin);
}
// Reset all row outputs and return to IRQ status
for (rowCounter = 0; rowCounter < KEYPAD_NUMBER_OF_ROWS; rowCounter++)
{
GPIO_ResetBits(self->row[rowCounter].gpio.GPIO_Typedef, self->row[rowCounter].gpio.GPIO_InitStruct.GPIO_Pin);
}
IRQ_setKeypadEXTI(self, ENABLE);
}
}

View File

@@ -27,12 +27,15 @@
#include <stdio.h>
#include "stm32f10x_adc.h"
#include "stm32f10x_bkp.h"
#include "stm32f10x_dma.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_pwr.h"
#include "stm32f10x_it.h"
#include "platform.h"
#include "adc.h"
#include "led.h"
#include "PCBA.h"
#include "rtc.h"
@@ -48,6 +51,10 @@
// Constant and macro definitions
// -----------------------------------------------------------------------------
// ADC
#define ADC1_DR_Address ((uint32_t)0x4001244C)
#define ADC1_NUMBER_OF_USED_CHANNELS (3)
// UART1 Settings (Logger/Console)
#define UART_LOG_BAUDRATE (57600)
#define UART_LOG_TX_QUEUE (256)
@@ -78,12 +85,15 @@
// the IO/Peripheral object
// PCBA information
static struct Pcba _pcba;
// LEDs
static struct Led _ledGreen;
static struct Led _ledOrange;
// ADC
static struct Adc _adc1;
static struct AdcParameters _adc1Parameters;
// RTC
static struct Rtc _rtc;
@@ -109,11 +119,14 @@ static struct KeypadParameters _keypadParameters;
// The following pointers are for export (see platform.h) and external use.
// Note that the pointer content is marked "const"
struct Pcba* const pcba = &_pcba;
struct Pcba* pcba;
struct Led* const ledGreen = &_ledGreen;
struct Led* const ledOrange = &_ledOrange;
struct Adc* const adc1 = &_adc1;
struct AdcParameters* adc1Parameters = &_adc1Parameters;
struct Rtc* const rtc = &_rtc;
struct Uart* const uart1 = &_uart1;
@@ -169,7 +182,7 @@ ErrorStatus initPlatform(void)
/* --------------------------------------------------------------------*/
/* PCBA */
/* --------------------------------------------------------------------*/
// PCBA_construct(pcba);
pcba = PCBA_getInstance();
/* --------------------------------------------------------------------*/
/* LEDs */
@@ -177,6 +190,63 @@ ErrorStatus initPlatform(void)
LED_construct(ledGreen);
LED_construct(ledOrange);
/* --------------------------------------------------------------------*/
/* DMA1 - Channel 1 - For use with ADC1 */
/* --------------------------------------------------------------------*/
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel1);
DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adc1->channelValue;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_BufferSize = ADC1_NUMBER_OF_USED_CHANNELS;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
/* Enable DMA1 channel1 */
DMA_Cmd(DMA1_Channel1, ENABLE);
/* --------------------------------------------------------------------*/
/* ADC1 - for module feedback */
/* --------------------------------------------------------------------*/
IRQ_setInterruptProperties(ADC1_2_IRQn, 12, 12, DISABLE);
adc1Parameters->ADC_Mode = ADC_Mode_Independent;
adc1Parameters->ADC_ScanConvMode = ENABLE;
adc1Parameters->ADC_ContinuousConvMode = ENABLE;
adc1Parameters->ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
adc1Parameters->ADC_DataAlign = ADC_DataAlign_Right;
adc1Parameters->ADC_NbrOfChannel = ADC1_NUMBER_OF_USED_CHANNELS;
adc1->ADCx = ADC1;
ADC_construct(adc1, adc1Parameters);
struct AdcChannelParameters acParameters;
acParameters.channel = ADC_Channel_0;
acParameters.Rank = 3;
acParameters.ADC_SampleTime = ADC_SampleTime_55Cycles5;
adc1->channel[acParameters.channel].parent = adc1;
ADCChannel_construct(&adc1->channel[acParameters.channel], &acParameters);
acParameters.channel = ADC_Channel_1;
acParameters.Rank = 2;
acParameters.ADC_SampleTime = ADC_SampleTime_55Cycles5;
adc1->channel[acParameters.channel].parent = adc1;
ADCChannel_construct(&adc1->channel[acParameters.channel], &acParameters);
acParameters.channel = ADC_Channel_2;
acParameters.Rank = 1;
acParameters.ADC_SampleTime = ADC_SampleTime_55Cycles5;
adc1->channel[acParameters.channel].parent = adc1;
ADCChannel_construct(&adc1->channel[acParameters.channel], &acParameters);
ADC_setDMAStatus(adc1, ENABLE);
ADC_setStatus(adc1, ENABLE);
ADC_performInternalCalibration(adc1);
ADC_SoftwareStartConvCmd(adc1->ADCx, ENABLE);
/* --------------------------------------------------------------------*/
/* RTC */
/* --------------------------------------------------------------------*/
@@ -271,8 +341,6 @@ ErrorStatus initPlatform(void)
Keypad_getDefaultParameters(keypadParam);
Keypad_construct(keypad, keypadParam, KEYPAD_DEBOUNCE_TIME_MS);
}
return returnValue;
@@ -308,6 +376,16 @@ static ErrorStatus initClocks (void)
// Enable RTC Clock
RCC_RTCCLKCmd(ENABLE);
RCC_PCLK2Config(RCC_HCLK_Div1);
RCC_ADCCLKConfig(RCC_PCLK2_Div2);
RCC_AHBPeriphResetCmd(RCC_AHBPeriph_DMA1, DISABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
@@ -337,19 +415,23 @@ static ErrorStatus initIO (void)
{
ErrorStatus returnValue = SUCCESS;
T_PL_GPIO gpio;
/*PCBA IO initialisation -------------------------------------------------*/
// A0
pcba->A0.GPIO_Typedef = GPIOC;
pcba->A0.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
pcba->A0.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
pcba->A0.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(pcba->A0.GPIO_Typedef, &pcba->A0.GPIO_InitStruct);
gpio.GPIO_Typedef = GPIOC;
gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(gpio.GPIO_Typedef, &gpio.GPIO_InitStruct);
PCBA_getInstance()->A0 = gpio;
// A1
pcba->A1.GPIO_Typedef = GPIOC;
pcba->A1.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
pcba->A1.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
pcba->A1.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(pcba->A1.GPIO_Typedef, &pcba->A1.GPIO_InitStruct);
gpio.GPIO_Typedef = GPIOC;
gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPD;
gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
gpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(gpio.GPIO_Typedef, &gpio.GPIO_InitStruct);
PCBA_getInstance()->A1 = gpio;
@@ -368,6 +450,27 @@ static ErrorStatus initIO (void)
ledOrange->ledGpio.GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(ledOrange->ledGpio.GPIO_Typedef, &ledOrange->ledGpio.GPIO_InitStruct);
/* ADC1 initialisation ---------------------------------------------------*/
// Channel 0 - PA0
gpio.GPIO_Typedef = GPIOA;
gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(gpio.GPIO_Typedef, &gpio.GPIO_InitStruct);
adc1->channel[ADC_Channel_0].input = gpio;
// Channel 1 - PA1
gpio.GPIO_Typedef = GPIOA;
gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(gpio.GPIO_Typedef, &gpio.GPIO_InitStruct);
adc1->channel[ADC_Channel_1].input = gpio;
// Channel 2 - PA2
gpio.GPIO_Typedef = GPIOA;
gpio.GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN;
gpio.GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(gpio.GPIO_Typedef, &gpio.GPIO_InitStruct);
adc1->channel[ADC_Channel_2].input = gpio;
/* USART1 initialisation -------------------------------------------------*/
// Init TX line
_uart1.USART_TX.GPIO_Typedef = GPIOB;