mirror of
https://github.com/SasaKaranovic/HousePlantMonitoringSystem.git
synced 2026-07-08 17:52:37 +02:00
Modifying I2C logic. Restructuring code for readability. Adding new PlantSystem devices.
This commit is contained in:
@@ -5,8 +5,6 @@ ADC_HandleTypeDef hadc;
|
||||
/* ADC init function */
|
||||
void MX_ADC_Init(void)
|
||||
{
|
||||
ADC_ChannelConfTypeDef sConfig = {0};
|
||||
|
||||
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
|
||||
*/
|
||||
hadc.Instance = ADC1;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "main.h"
|
||||
#include "i2c.h"
|
||||
#include "usart.h"
|
||||
|
||||
@@ -6,91 +7,80 @@
|
||||
#define LOGGER_TAG "I2C"
|
||||
#include "logger.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
#define I2C_BUFF_LEN 30
|
||||
|
||||
#define I2C_ADDRESS (0x1F << 1)
|
||||
#define I2C_TIMING 0x20602938 /* 100 kHz with analog Filter ON, Rise Time 400ns, Fall Time 100ns */
|
||||
#define I2C_BUFF_LEN 30
|
||||
|
||||
|
||||
volatile uint8_t pI2CBuff[I2C_BUFF_LEN] = {0};
|
||||
volatile uint8_t nBuffPos = 0;
|
||||
|
||||
I2C_HandleTypeDef hi2c1;
|
||||
|
||||
|
||||
/* I2C1 init function */
|
||||
void MX_I2C1_Init(void)
|
||||
{
|
||||
/*##-1- Configure the I2C peripheral ######################################*/
|
||||
hi2c1.Instance = I2Cx;
|
||||
hi2c1.Init.Timing = I2C_TIMING;
|
||||
hi2c1.Init.OwnAddress1 = I2C_ADDRESS;
|
||||
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
|
||||
hi2c1.Init.OwnAddress2 = 0xFF;
|
||||
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
|
||||
|
||||
hi2c1.Instance = I2C1;
|
||||
hi2c1.Init.Timing = 0x00707CBB;
|
||||
hi2c1.Init.OwnAddress1 = 0x32;
|
||||
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
|
||||
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
|
||||
hi2c1.Init.OwnAddress2 = 0;
|
||||
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
|
||||
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
|
||||
// hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_ENABLE;
|
||||
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
|
||||
// hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
|
||||
|
||||
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/** Configure Analogue filter
|
||||
*/
|
||||
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/** Configure Digital filter
|
||||
*/
|
||||
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
while(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);
|
||||
HAL_StatusTypeDef status;
|
||||
if( (status=HAL_I2C_Slave_Receive_IT(&hi2c1, pI2CBuff, 4)) != HAL_OK)
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
/* I2C1 interrupt Init */
|
||||
HAL_NVIC_SetPriority(I2C1_IRQn, 0, 0);
|
||||
HAL_NVIC_EnableIRQ(I2C1_IRQn);
|
||||
if(HAL_I2C_Init(&hi2c1) != HAL_OK)
|
||||
{
|
||||
/* Initialization Error */
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
/* Enable the Analog I2C Filter */
|
||||
HAL_I2CEx_ConfigAnalogFilter(&hi2c1,I2C_ANALOGFILTER_ENABLE);
|
||||
|
||||
}
|
||||
|
||||
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
|
||||
void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct;
|
||||
|
||||
/*##-1- Configure the I2C clock source. The clock is derived from the SYSCLK #*/
|
||||
RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_I2Cx;
|
||||
RCC_PeriphCLKInitStruct.I2c1ClockSelection = RCC_I2CxCLKSOURCE_SYSCLK;
|
||||
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct);
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(i2cHandle->Instance==I2C1)
|
||||
{
|
||||
/* USER CODE BEGIN I2C1_MspInit 0 */
|
||||
/*##-2- Enable peripherals and GPIO Clocks #################################*/
|
||||
/* Enable GPIO TX/RX clock */
|
||||
I2Cx_SCL_GPIO_CLK_ENABLE();
|
||||
I2Cx_SDA_GPIO_CLK_ENABLE();
|
||||
/* Enable I2Cx clock */
|
||||
I2Cx_CLK_ENABLE();
|
||||
|
||||
/* USER CODE END I2C1_MspInit 0 */
|
||||
/*##-3- Configure peripheral GPIO ##########################################*/
|
||||
/* I2C TX GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = I2Cx_SCL_PIN;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = I2Cx_SCL_SDA_AF;
|
||||
HAL_GPIO_Init(I2Cx_SCL_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/* I2C RX GPIO pin configuration */
|
||||
GPIO_InitStruct.Pin = I2Cx_SDA_PIN;
|
||||
GPIO_InitStruct.Alternate = I2Cx_SCL_SDA_AF;
|
||||
HAL_GPIO_Init(I2Cx_SDA_GPIO_PORT, &GPIO_InitStruct);
|
||||
|
||||
/*##-4- Configure the NVIC for I2C ########################################*/
|
||||
/* NVIC for I2Cx */
|
||||
HAL_NVIC_SetPriority(I2Cx_IRQn, 0, 1);
|
||||
HAL_NVIC_EnableIRQ(I2Cx_IRQn);
|
||||
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__DSB();
|
||||
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
||||
/**I2C1 GPIO Configuration
|
||||
PA9 ------> I2C1_SCL
|
||||
PA10 ------> I2C1_SDA
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF1_I2C1;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/* I2C1 clock enable */
|
||||
__HAL_RCC_I2C1_CLK_ENABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
|
||||
@@ -98,101 +88,83 @@ void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
|
||||
|
||||
if(i2cHandle->Instance==I2C1)
|
||||
{
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_I2C1_CLK_DISABLE();
|
||||
I2Cx_FORCE_RESET();
|
||||
I2Cx_RELEASE_RESET();
|
||||
|
||||
/**I2C1 GPIO Configuration
|
||||
PA9 ------> I2C1_SCL
|
||||
PA10 ------> I2C1_SDA
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9);
|
||||
|
||||
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_10);
|
||||
/*##-2- Disable peripherals and GPIO Clocks #################################*/
|
||||
/* Configure I2C Tx as alternate function */
|
||||
HAL_GPIO_DeInit(I2Cx_SCL_GPIO_PORT, I2Cx_SCL_PIN);
|
||||
/* Configure I2C Rx as alternate function */
|
||||
HAL_GPIO_DeInit(I2Cx_SDA_GPIO_PORT, I2Cx_SDA_PIN);
|
||||
|
||||
/*##-3- Disable the NVIC for I2C ##########################################*/
|
||||
HAL_NVIC_DisableIRQ(I2Cx_IRQn);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c)
|
||||
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *pI2c_Handle)
|
||||
{
|
||||
uint8_t msg[] = "Tx\r\n";
|
||||
HAL_UART_PutStr(msg, sizeof(msg));
|
||||
/** Error_Handler() function is called when error occurs.
|
||||
* 1- When Slave don't acknowledge it's address, Master restarts communication.
|
||||
* 2- When Master don't acknowledge the last data transferred, Slave don't care in this example.
|
||||
*/
|
||||
if (HAL_I2C_GetError(pI2c_Handle) != HAL_I2C_ERROR_AF)
|
||||
{
|
||||
// Error_Handler();
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c)
|
||||
{
|
||||
uint8_t msg[] = "Rx\r\n";
|
||||
HAL_UART_PutStr(msg, sizeof(msg));
|
||||
nBuffPos = 4;
|
||||
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_TXE); // Transmit data register empty
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ADDR); // Address matched (slave mode)
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_AF); // Acknowledge failure received flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_STOPF); // STOP detection flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_BERR); // Bus error
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ARLO); // Arbitration lost
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_OVR); // Overrun/Underrun
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_PECERR); // PEC error in reception
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_TIMEOUT); // Timeout or Tlow detection flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ALERT); // SMBus alert
|
||||
}
|
||||
|
||||
void I2C_GetBuffer(uint8_t **ret_pBuff, uint8_t *pBufferLen)
|
||||
{
|
||||
if(ret_pBuff == NULL || pBufferLen == NULL)
|
||||
{
|
||||
Logger_ERROR("Invalid argument!");
|
||||
return;
|
||||
}
|
||||
|
||||
*ret_pBuff = (uint8_t *)pI2CBuff;
|
||||
*pBufferLen = nBuffPos;
|
||||
}
|
||||
|
||||
uint8_t I2C_GetBufferLenght(void)
|
||||
{
|
||||
return nBuffPos;
|
||||
*pBufferLen = I2C_BUFF_LEN;
|
||||
}
|
||||
|
||||
void I2C_ClearBuffer(void)
|
||||
{
|
||||
nBuffPos = 0;
|
||||
for(uint8_t i=0; i<I2C_BUFF_LEN; i++)
|
||||
{
|
||||
pI2CBuff[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void I2C_ReloadIT(void)
|
||||
|
||||
void I2C_RestartReceive(void)
|
||||
{
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_TXE); // Transmit data register empty
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ADDR); // Address matched (slave mode)
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_AF); // Acknowledge failure received flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_STOPF); // STOP detection flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_BERR); // Bus error
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ARLO); // Arbitration lost
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_OVR); // Overrun/Underrun
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_PECERR); // PEC error in reception
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_TIMEOUT); // Timeout or Tlow detection flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ALERT); // SMBus alert
|
||||
HAL_I2C_Slave_Receive_IT(&hi2c1, pI2CBuff, 4); //Enable slave interrupt reception
|
||||
// nBuffPos++;
|
||||
// if (nBuffPos >= I2C_BUFF_LEN-1)
|
||||
// {
|
||||
// nBuffPos = 0;
|
||||
// }
|
||||
HAL_I2C_Slave_Receive_IT(&hi2c1, (uint8_t*)pI2CBuff, I2C_BUFF_LEN);
|
||||
}
|
||||
|
||||
void I2C_RestartITReceive(void)
|
||||
bool I2C_DeviceInReadyState(void)
|
||||
{
|
||||
// HAL_I2C_DisableListen_IT(&hi2c1);
|
||||
|
||||
// __HAL_I2C_ENABLE_IT(&hi2c1, I2C_IT_ERRI); // Errors interrupt enable
|
||||
// __HAL_I2C_ENABLE_IT(&hi2c1, I2C_IT_TCI); // Transfer complete interrupt enable
|
||||
// __HAL_I2C_ENABLE_IT(&hi2c1, I2C_IT_STOPI); // STOP detection interrupt enable
|
||||
// __HAL_I2C_ENABLE_IT(&hi2c1, I2C_IT_NACKI); // NACK received interrupt enable
|
||||
// __HAL_I2C_ENABLE_IT(&hi2c1, I2C_IT_ADDRI); // Address match interrupt enable
|
||||
// __HAL_I2C_ENABLE_IT(&hi2c1, I2C_IT_RXI); // RX interrupt enable
|
||||
// __HAL_I2C_ENABLE_IT(&hi2c1, I2C_IT_TXI); // TX interrupt enable
|
||||
|
||||
// HAL_I2C_Slave_Seq_Receive_IT(&hi2c1, (uint8_t *)&pI2CBuff[nBuffPos], 1, I2C_LAST_FRAME_NO_STOP); //Enable slave interrupt reception
|
||||
// I2C_ReloadIT();
|
||||
// HAL_I2C_EnableListen_IT(&hi2c1);
|
||||
return (HAL_I2C_GetState(&hi2c1) == HAL_I2C_STATE_READY);
|
||||
}
|
||||
|
||||
bool I2C_SendBuffer(uint8_t *pTXBuff, uint8_t nTXBufferLen)
|
||||
{
|
||||
if(pTXBuff == NULL)
|
||||
{
|
||||
Logger_ERROR("Invalid pointer!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (nTXBufferLen >= I2C_BUFF_LEN)
|
||||
{
|
||||
Logger_ERROR("nTXBufferLen too big");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(HAL_I2C_Slave_Transmit(&hi2c1, pTXBuff, nTXBufferLen, 0xFFFFF) != HAL_OK)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,13 +6,13 @@
|
||||
extern I2C_HandleTypeDef hi2c1;
|
||||
|
||||
void MX_I2C1_Init(void);
|
||||
void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c);
|
||||
void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c);
|
||||
void I2C_GetBuffer(uint8_t **ret_pBuff, uint8_t *pBufferLen);
|
||||
uint8_t I2C_GetBufferLenght(void);
|
||||
void I2C_ReloadIT(void);
|
||||
void I2C_ClearBuffer(void);
|
||||
void I2C_RestartITReceive(void);
|
||||
void I2C_RestartReceive(void);
|
||||
bool I2C_DeviceInReadyState(void);
|
||||
bool I2C_SendBuffer(uint8_t *pTXBuff, uint8_t nTXBufferLen);
|
||||
void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *I2cHandle);
|
||||
|
||||
|
||||
#endif /*__ i2c_H */
|
||||
|
||||
|
||||
@@ -8,158 +8,167 @@
|
||||
#define LOGGER_TAG "MAIN"
|
||||
#include "logger.h"
|
||||
|
||||
uint32_t nTickTarget_PrintDebug = 0;
|
||||
uint32_t nTickTarget_TakeMeasurement = 0;
|
||||
#define TX_BUFF_SIZE 10
|
||||
static uint8_t pTXBuff[TX_BUFF_SIZE] = {0xFF};
|
||||
static uint8_t nTXBufferLen = 0;
|
||||
uint8_t *pBuff = NULL;
|
||||
uint8_t nBufferLen = 0;
|
||||
uint32_t nTickTarget_PrintDebug = 0;
|
||||
uint32_t nTickTarget_TakeMeasurement = 0;
|
||||
|
||||
#define TX_BUFF_SIZE 10
|
||||
static uint8_t pTXBuff[TX_BUFF_SIZE] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||
static uint8_t nTXBufferLen = 0;
|
||||
static void PlantSystem_ProcessRequest(void);
|
||||
|
||||
int main(void)
|
||||
{
|
||||
BoardInit();
|
||||
BoardInit();
|
||||
HAL_Delay(500);
|
||||
|
||||
Logger_INFO("Hello there!");
|
||||
HAL_Delay(1000);
|
||||
Logger_INFO("PlantSensor v0.1");
|
||||
Logger_INFO("Build date: %s %s", __DATE__, __TIME__);
|
||||
|
||||
__enable_irq();
|
||||
uint8_t *pBuff = NULL;
|
||||
uint8_t nBufferLen = 0;
|
||||
HAL_I2C_StateTypeDef status;
|
||||
I2C_RestartReceive();
|
||||
|
||||
while (1)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
// Check if I2C is ready for processing
|
||||
if(I2C_DeviceInReadyState() == true)
|
||||
{
|
||||
I2C_GetBuffer(&pBuff, &nBufferLen);
|
||||
// Check valid command is received
|
||||
if(pBuff[0] > CMD_FIRST && pBuff[0] < CMD_LAST)
|
||||
{
|
||||
PlantSystem_ProcessRequest();
|
||||
}
|
||||
|
||||
// // Clear RX buffer and reset receive
|
||||
I2C_ClearBuffer();
|
||||
while (I2C_DeviceInReadyState() != true)
|
||||
{
|
||||
}
|
||||
I2C_RestartReceive();
|
||||
}
|
||||
|
||||
// Take soil moisture, temperature and ambient light measurements
|
||||
if(HAL_GetTick() >= nTickTarget_TakeMeasurement)
|
||||
{
|
||||
Sensor_TakeMeasurement();
|
||||
nTickTarget_TakeMeasurement = HAL_GetTick() + 500;
|
||||
}
|
||||
// Take soil moisture, temperature and ambient light measurements
|
||||
if(HAL_GetTick() >= nTickTarget_TakeMeasurement)
|
||||
{
|
||||
Sensor_TakeMeasurement();
|
||||
nTickTarget_TakeMeasurement = HAL_GetTick() + 500;
|
||||
}
|
||||
|
||||
|
||||
// Print Sensor debug over uart every 1 sec
|
||||
if(HAL_GetTick() >= nTickTarget_PrintDebug)
|
||||
{
|
||||
Sensors_PrintDebug();
|
||||
nTickTarget_PrintDebug = HAL_GetTick() + 1000;
|
||||
}
|
||||
// Print Sensor debug over uart every 1 sec
|
||||
if(HAL_GetTick() >= nTickTarget_PrintDebug)
|
||||
{
|
||||
Sensors_PrintDebug();
|
||||
nTickTarget_PrintDebug = HAL_GetTick() + 1000;
|
||||
}
|
||||
|
||||
// Wait for I2C to be IDLE (HAL_I2C_STATE_READY)
|
||||
status = HAL_I2C_GetState(&hi2c1);
|
||||
// if(status == HAL_I2C_STATE_READY)
|
||||
// {
|
||||
|
||||
// Check if we received enough bytes to start processing
|
||||
nBufferLen = I2C_GetBufferLenght();
|
||||
if(nBufferLen >= PLANTSYSTEM_MIN_HEADER_LENGHT)
|
||||
{
|
||||
I2C_GetBuffer(&pBuff, &nBufferLen);
|
||||
|
||||
#if 1
|
||||
uint8_t i=0;
|
||||
for (i=0; i<5; i++)
|
||||
{
|
||||
Logger_INFO("0x%02X", pBuff[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint8_t cmd=0;
|
||||
uint8_t dataType=0;
|
||||
uint8_t dataLength=0;
|
||||
|
||||
if (PlanSystem_ParseBuffer(pBuff, nBufferLen, &cmd, &dataType, &dataLength))
|
||||
{
|
||||
Logger_INFO("Success");
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
// Get device information
|
||||
case CMD_GET_DEVICE_INFO:
|
||||
{
|
||||
nTXBufferLen=0;
|
||||
Logger_INFO("I");
|
||||
}
|
||||
break;
|
||||
|
||||
// Read temperature
|
||||
case CMD_GET_TEMPERATURE:
|
||||
{
|
||||
pTXBuff[0] = CMD_GET_TEMPERATURE;
|
||||
pTXBuff[1] = DATATYPE_SINGLE_VALUE;
|
||||
pTXBuff[2] = 2;
|
||||
Sensors_GetTemperatureReading(&pTXBuff[3], &pTXBuff[4]);
|
||||
nTXBufferLen = 5;
|
||||
Logger_INFO("T");
|
||||
}
|
||||
break;
|
||||
|
||||
// Read soil moisture
|
||||
case CMD_GET_SOILMOISTURE:
|
||||
{
|
||||
pTXBuff[0] = CMD_GET_SOILMOISTURE;
|
||||
pTXBuff[1] = DATATYPE_SINGLE_VALUE;
|
||||
pTXBuff[2] = 4;
|
||||
Sensors_GetSoilMoistureReading(&pTXBuff[3], &pTXBuff[4], &pTXBuff[5], &pTXBuff[6]);
|
||||
nTXBufferLen = 7;
|
||||
Logger_INFO("M");
|
||||
}
|
||||
break;
|
||||
|
||||
// Read ambient light
|
||||
case CMD_GET_AMBIENTLIGHT:
|
||||
{
|
||||
pTXBuff[0] = CMD_GET_AMBIENTLIGHT;
|
||||
pTXBuff[1] = DATATYPE_SINGLE_VALUE;
|
||||
pTXBuff[2] = 4;
|
||||
Sensors_GetAmbientLightReading(&pTXBuff[3], &pTXBuff[4], &pTXBuff[5], &pTXBuff[6]);
|
||||
nTXBufferLen = 7;
|
||||
Logger_INFO("A");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
nTXBufferLen=0;
|
||||
Logger_INFO("D");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// PlanSystem_ParseBuffer returned false
|
||||
else
|
||||
{
|
||||
nTXBufferLen=0;
|
||||
Logger_INFO("FF");
|
||||
}
|
||||
|
||||
// Setup response if necessary
|
||||
// -- Check TX length
|
||||
if(nTXBufferLen>= TX_BUFF_SIZE-1)
|
||||
{
|
||||
nTXBufferLen = TX_BUFF_SIZE;
|
||||
}
|
||||
// -- Send data
|
||||
if(nTXBufferLen > 0)
|
||||
{
|
||||
while(HAL_I2C_GetState(&hi2c1) != HAL_I2C_STATE_READY);
|
||||
if(HAL_I2C_Slave_Transmit(&hi2c1, pTXBuff, nTXBufferLen, 0xFFFF) != HAL_OK)
|
||||
{
|
||||
while(1);
|
||||
}
|
||||
// HAL_I2C_Slave_Transmit_IT(&hi2c1, pTXBuff, nTXBufferLen);
|
||||
}
|
||||
|
||||
|
||||
// Reset I2C state machine
|
||||
I2C_ClearBuffer();
|
||||
I2C_ReloadIT();
|
||||
}
|
||||
|
||||
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void PlantSystem_ProcessRequest(void)
|
||||
{
|
||||
uint8_t cmd=0;
|
||||
uint8_t dataType=0;
|
||||
uint8_t dataLength=0;
|
||||
|
||||
I2C_GetBuffer(&pBuff, &nBufferLen);
|
||||
|
||||
if (PlanSystem_ParseBuffer(pBuff, nBufferLen, &cmd, &dataType, &dataLength))
|
||||
{
|
||||
Logger_INFO("Success");
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
// Get device information
|
||||
case CMD_GET_DEVICE_INFO:
|
||||
{
|
||||
pTXBuff[0] = CMD_GET_DEVICE_INFO;
|
||||
pTXBuff[1] = DATATYPE_SINGLE_VALUE;
|
||||
pTXBuff[2] = 0; // Upper byte of data length
|
||||
pTXBuff[3] = 4; // Lower byte of data length
|
||||
pTXBuff[4] = DEVICETYPE_SENSOR_V1;
|
||||
pTXBuff[5] = 'T'; // Optional bytes to indicate capabilities (temp, humid, light)
|
||||
pTXBuff[6] = 'H'; // Optional bytes to indicate capabilities (temp, humid, light)
|
||||
pTXBuff[7] = 'L'; // Optional bytes to indicate capabilities (temp, humid, light)
|
||||
nTXBufferLen = 8;
|
||||
Logger_INFO("I");
|
||||
}
|
||||
break;
|
||||
|
||||
// Read temperature
|
||||
case CMD_GET_TEMPERATURE:
|
||||
{
|
||||
pTXBuff[0] = CMD_GET_TEMPERATURE;
|
||||
pTXBuff[1] = DATATYPE_SINGLE_VALUE;
|
||||
pTXBuff[2] = 2;
|
||||
Sensors_GetTemperatureReading(&pTXBuff[3], &pTXBuff[4]);
|
||||
nTXBufferLen = 5;
|
||||
Logger_INFO("T");
|
||||
}
|
||||
break;
|
||||
|
||||
// Read soil moisture
|
||||
case CMD_GET_SOILMOISTURE:
|
||||
{
|
||||
pTXBuff[0] = CMD_GET_SOILMOISTURE;
|
||||
pTXBuff[1] = DATATYPE_SINGLE_VALUE;
|
||||
pTXBuff[2] = 4;
|
||||
Sensors_GetSoilMoistureReading(&pTXBuff[3], &pTXBuff[4], &pTXBuff[5], &pTXBuff[6]);
|
||||
nTXBufferLen = 7;
|
||||
Logger_INFO("M");
|
||||
}
|
||||
break;
|
||||
|
||||
// Read ambient light
|
||||
case CMD_GET_AMBIENTLIGHT:
|
||||
{
|
||||
pTXBuff[0] = CMD_GET_AMBIENTLIGHT;
|
||||
pTXBuff[1] = DATATYPE_SINGLE_VALUE;
|
||||
pTXBuff[2] = 4;
|
||||
Sensors_GetAmbientLightReading(&pTXBuff[3], &pTXBuff[4], &pTXBuff[5], &pTXBuff[6]);
|
||||
nTXBufferLen = 7;
|
||||
Logger_INFO("A");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
nTXBufferLen=0;
|
||||
Logger_INFO("D");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// PlanSystem_ParseBuffer returned false
|
||||
else
|
||||
{
|
||||
nTXBufferLen=0;
|
||||
Logger_INFO("FF");
|
||||
}
|
||||
|
||||
// Setup response if necessary
|
||||
// -- Check TX length
|
||||
if(nTXBufferLen>= TX_BUFF_SIZE-1)
|
||||
{
|
||||
nTXBufferLen = TX_BUFF_SIZE;
|
||||
}
|
||||
// -- Send data
|
||||
if(nTXBufferLen > 0)
|
||||
{
|
||||
Logger_DEBUG("TX");
|
||||
|
||||
uint32_t timeout = HAL_GetTick() + 5000;
|
||||
I2C_SendBuffer(pTXBuff, nTXBufferLen);
|
||||
while (I2C_DeviceInReadyState() != true)
|
||||
{
|
||||
if(HAL_GetTick() > timeout)
|
||||
{
|
||||
Logger_ERROR("TX timeout");
|
||||
return;
|
||||
}
|
||||
}
|
||||
Logger_DEBUG("TX end");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,19 +6,41 @@
|
||||
|
||||
void Error_Handler(void);
|
||||
|
||||
#define VCP_TX_Pin GPIO_PIN_2
|
||||
#define VCP_TX_GPIO_Port GPIOA
|
||||
#define TMS_Pin GPIO_PIN_13
|
||||
#define TMS_GPIO_Port GPIOA
|
||||
#define TCK_Pin GPIO_PIN_14
|
||||
#define TCK_GPIO_Port GPIOA
|
||||
#define VCP_RX_Pin GPIO_PIN_15
|
||||
#define VCP_RX_GPIO_Port GPIOA
|
||||
#define LD3_Pin GPIO_PIN_3
|
||||
#define LD3_GPIO_Port GPIOB
|
||||
#define TEMP_ALERT_Pin GPIO_PIN_6
|
||||
#define TEMP_ALERT_GPIO_Port GPIOB
|
||||
#define VCP_TX_Pin GPIO_PIN_2
|
||||
#define VCP_TX_GPIO_Port GPIOA
|
||||
#define TMS_Pin GPIO_PIN_13
|
||||
#define TMS_GPIO_Port GPIOA
|
||||
#define TCK_Pin GPIO_PIN_14
|
||||
#define TCK_GPIO_Port GPIOA
|
||||
#define VCP_RX_Pin GPIO_PIN_15
|
||||
#define VCP_RX_GPIO_Port GPIOA
|
||||
#define LD3_Pin GPIO_PIN_3
|
||||
#define LD3_GPIO_Port GPIOB
|
||||
#define TEMP_ALERT_Pin GPIO_PIN_6
|
||||
#define TEMP_ALERT_GPIO_Port GPIOB
|
||||
|
||||
|
||||
/* Definition for I2Cx */
|
||||
#define I2Cx I2C1
|
||||
#define RCC_PERIPHCLK_I2Cx RCC_PERIPHCLK_I2C1
|
||||
#define RCC_I2CxCLKSOURCE_SYSCLK RCC_I2C1CLKSOURCE_SYSCLK
|
||||
#define I2Cx_CLK_ENABLE() __HAL_RCC_I2C1_CLK_ENABLE()
|
||||
#define I2Cx_SDA_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
#define I2Cx_SCL_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
|
||||
|
||||
#define I2Cx_FORCE_RESET() __HAL_RCC_I2C1_FORCE_RESET()
|
||||
#define I2Cx_RELEASE_RESET() __HAL_RCC_I2C1_RELEASE_RESET()
|
||||
|
||||
/* Definition for I2Cx Pins */
|
||||
#define I2Cx_SCL_PIN GPIO_PIN_9
|
||||
#define I2Cx_SCL_GPIO_PORT GPIOA
|
||||
#define I2Cx_SDA_PIN GPIO_PIN_10
|
||||
#define I2Cx_SDA_GPIO_PORT GPIOA
|
||||
#define I2Cx_SCL_SDA_AF GPIO_AF1_I2C1
|
||||
|
||||
/* Definition for I2Cx's NVIC */
|
||||
#define I2Cx_IRQn I2C1_IRQn
|
||||
#define I2Cx_IRQHandler I2C1_IRQHandler
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
extern I2C_HandleTypeDef hi2c1;
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/* Cortex-M0+ Processor Interruption and Exception Handlers */
|
||||
/******************************************************************************/
|
||||
@@ -60,29 +59,8 @@ void SysTick_Handler(void)
|
||||
*/
|
||||
void I2C1_IRQHandler(void)
|
||||
{
|
||||
if (hi2c1.Instance->ISR & (I2C_FLAG_BERR | I2C_FLAG_ARLO | I2C_FLAG_OVR)) {
|
||||
HAL_I2C_ER_IRQHandler(&hi2c1);
|
||||
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_TXE); // Transmit data register empty
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ADDR); // Address matched (slave mode)
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_AF); // Acknowledge failure received flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_STOPF); // STOP detection flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_BERR); // Bus error
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ARLO); // Arbitration lost
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_OVR); // Overrun/Underrun
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_PECERR); // PEC error in reception
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_TIMEOUT); // Timeout or Tlow detection flag
|
||||
__HAL_I2C_CLEAR_FLAG(&hi2c1, I2C_FLAG_ALERT); // SMBus alert
|
||||
|
||||
}
|
||||
else {
|
||||
HAL_I2C_EV_IRQHandler(&hi2c1);
|
||||
// I2C_ReloadIT();
|
||||
}
|
||||
|
||||
HAL_NVIC_ClearPendingIRQ(I2C1_IRQn);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include "main.h"
|
||||
#include "PlantSystem.h"
|
||||
|
||||
#define MIN_LOG_LEVEL_ERROR
|
||||
#define LOGGER_TAG "PS"
|
||||
#include "logger.h"
|
||||
|
||||
|
||||
bool PlanSystem_ParseBuffer(uint8_t *pBuffer, uint8_t nBufferLen, uint8_t *cmd, uint8_t *dataType, uint8_t *dataLength)
|
||||
@@ -8,12 +11,14 @@ bool PlanSystem_ParseBuffer(uint8_t *pBuffer, uint8_t nBufferLen, uint8_t *cmd,
|
||||
// Check for null pointers
|
||||
if( (pBuffer==NULL) || (cmd==NULL) || (dataType==NULL) || (dataLength==NULL))
|
||||
{
|
||||
Logger_ERROR("Invalid call argument!");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check buffer length
|
||||
if(nBufferLen < PLANTSYSTEM_MIN_HEADER_LENGHT)
|
||||
{
|
||||
Logger_DEBUG("Buffer length too short");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -25,12 +30,14 @@ bool PlanSystem_ParseBuffer(uint8_t *pBuffer, uint8_t nBufferLen, uint8_t *cmd,
|
||||
// Check command
|
||||
if((*cmd<=CMD_FIRST) || (*cmd>=CMD_LAST))
|
||||
{
|
||||
Logger_DEBUG("Unsupported command");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check datatype
|
||||
if((*dataType<=DATATYPE_FIRST) || (*dataType>=DATATYPE_LAST))
|
||||
{
|
||||
Logger_DEBUG("Unsupported data type");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,16 @@ typedef enum
|
||||
DATATYPE_SINGLE_VALUE,
|
||||
DATATYPE_KEY_VALUE_PAIR,
|
||||
DATATYPE_LAST
|
||||
} plant_datatype_t;
|
||||
} plant_dataType_t;
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DEVICETYPE_FIRST = 0x00,
|
||||
DEVICETYPE_SENSOR_V1,
|
||||
DEVICETYPE_SOLENOID_V1,
|
||||
DEVICETYPE_LAST
|
||||
} plant_deviceType_t;
|
||||
|
||||
bool PlanSystem_ParseBuffer(uint8_t *pBuffer, uint8_t nBufferLen, uint8_t *cmd, uint8_t *dataType, uint8_t *dataLength);
|
||||
|
||||
|
||||
@@ -210,6 +210,9 @@ flash:
|
||||
jlink:
|
||||
JLink.exe -if swd flash.jlink
|
||||
|
||||
reset:
|
||||
JLink.exe -if swd reset.jlink
|
||||
|
||||
size:
|
||||
py -3 size.py -p 16KB -r 2KB -f build/$(TARGET).elf
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
device stm32l011k4
|
||||
tif swd
|
||||
speed 4000
|
||||
rnh
|
||||
exit
|
||||
Reference in New Issue
Block a user