diff --git a/Firmware/carteHRI.uvoptx b/Firmware/carteHRI.uvoptx
index cc6d1ed..ccc8985 100644
--- a/Firmware/carteHRI.uvoptx
+++ b/Firmware/carteHRI.uvoptx
@@ -1,801 +1,775 @@
1.0
### uVision Project, (C) Keil Software
*.c
*.s*; *.src; *.a*
*.obj
*.lib
*.txt; *.h; *.inc
*.plm
*.cpp
0
0
0
Target 1
0x4
ARM-ADS
168000000
1
1
0
1
0
1
65535
0
0
0
79
66
8
.\lst\
1
1
1
0
1
1
0
1
0
0
0
0
1
1
1
1
1
1
1
0
0
1
0
1
18
0
User Manual (MCBSTM32F400)
C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK\Boards\Keil\MCBSTM32F400\Documentation\mcbstm32f200.chm
1
Schematics (MCBSTM32F400)
C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK\Boards\Keil\MCBSTM32F400\Documentation\mcbstm32f400-schematics.pdf
2
Getting Started (STM32F4-Discovery)
C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK\Boards\ST\STM32F4-Discovery\Documentation\DM00037368.pdf
3
User Manual (STM32F4-Discovery)
C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK\Boards\ST\STM32F4-Discovery\Documentation\DM00039084.pdf
4
Bill of Materials (STM32F4-Discovery)
C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK\Boards\ST\STM32F4-Discovery\Documentation\stm32f4discovery_bom.zip
5
Gerber Files (STM32F4-Discovery)
C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK\Boards\ST\STM32F4-Discovery\Documentation\stm32f4discovery_gerber.zip
6
Schematics (STM32F4-Discovery)
C:\Keil_v5\ARM\PACK\Keil\STM32F4xx_DFP\2.5.0\MDK\Boards\ST\STM32F4-Discovery\Documentation\stm32f4discovery_sch.zip
7
MCBSTM32F400 Evaluation Board Web Page (MCBSTM32F400)
http://www.keil.com/mcbstm32f400/
8
STM32F4-Discovery Web Page (STM32F4-Discovery)
http://www.st.com/web/catalog/tools/FM116/SC959/SS1532/LN1199/PF252419
0
1
1
1
1
1
1
1
1
1
0
1
1
1
0
1
1
1
1
0
0
11
STLink\ST-LINKIII-KEIL_SWO.dll
0
ARMRTXEVENTFLAGS
-L50 -Z18 -C0 -M0 -T0
0
DLGDARM
(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)
0
DLGTARM
(1010=-1,-1,-1,-1,0)(1007=-1,-1,-1,-1,0)(1008=-1,-1,-1,-1,0)(1009=-1,-1,-1,-1,0)(1012=-1,-1,-1,-1,0)
0
ARMDBGFLAGS
-T0
0
DLGUARM
(105=-1,-1,-1,-1,0)
0
ST-LINKIII-KEIL_SWO
-U303030303030303030303031 -O8398 -S1 -C0 -A0 -N00("ARM CoreSight SW-DP") -D00(2BA01477) -L00(0) -TO19 -TC168000000 -TP21 -TDS8053 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO15 -FD20000000 -FC800 -FN1 -FF0STM32F4xx_1024.FLM -FS08000000 -FL0100000 -FP0($$Device:STM32F407VG$CMSIS\Flash\STM32F4xx_1024.FLM)
0
UL2CM3
UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024 -FS08000000 -FL0100000 -FP0($$Device:STM32F407VG$Flash\STM32F4xx_1024.FLM))
0
1
uart_txBuffer[0]
1
1
uart_txBuffer[1]
2
1
demoSineOutput
3
1
ctrl_motorPosHall
4
1
ctrl_timestamp
0
2
motorCurrentDebug
1
2
motorTargetCurrentDebug
2
2
ctrl_motorTorque_mNm_c
3
2
motorTorque_mNm_dbg
4
2
motorTorque_mNm
5
2
nCycles
6
2
motorPosCod,0x0A
7
2
CurrentSensOffset,0x0A
8
2
motorCurrent_mA_mean
9
2
motorCurrent_mA
10
2
ADCValuesBuffer,0x0A
11
2
motorCurrent_mA
12
2
motorCurrentSum
13
2
debugVar01,0x0A
14
2
adcValues1,0x0A
15
2
motorCurrent_mA
0
0
1
1
0
0
0
0
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
STM32_files
1
0
0
0
1
1
1
0
0
0
0
.\src\system_stm32f4xx.c
system_stm32f4xx.c
0
0
1
2
2
0
0
0
0
.\startup_stm32f4xx.s
startup_stm32f4xx.s
0
0
SRC
1
0
0
0
2
3
1
0
0
0
0
.\src\main.c
main.c
0
0
2
4
1
0
0
0
0
.\src\communication.c
communication.c
0
0
2
5
1
0
0
0
0
.\src\controller.c
controller.c
0
0
STM32_libs
1
0
0
0
3
6
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c
stm32f4xx_gpio.c
0
0
3
7
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c
stm32f4xx_rcc.c
0
0
3
8
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_tim.c
stm32f4xx_tim.c
0
0
3
9
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\misc.c
misc.c
0
0
3
10
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_exti.c
stm32f4xx_exti.c
0
0
3
11
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_syscfg.c
stm32f4xx_syscfg.c
0
0
3
12
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_adc.c
stm32f4xx_adc.c
0
0
3
13
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_dac.c
stm32f4xx_dac.c
0
0
3
14
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_dma.c
stm32f4xx_dma.c
0
0
3
15
1
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_usart.c
stm32f4xx_usart.c
0
0
3
16
4
0
0
0
0
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\CMSIS\Lib\ARM\arm_cortexM4lf_math.lib
arm_cortexM4lf_math.lib
0
0
SRC_drivers
1
0
0
0
4
17
1
0
0
0
0
.\src\drivers\adc.c
adc.c
0
0
4
18
1
0
0
0
0
.\src\drivers\callback_timers.c
callback_timers.c
0
0
4
19
1
0
0
0
0
.\src\drivers\dac.c
dac.c
0
0
4
20
1
0
0
0
0
.\src\drivers\h_bridge.c
h_bridge.c
0
0
4
21
1
0
0
0
0
.\src\drivers\incr_encoder.c
incr_encoder.c
0
0
4
22
1
0
0
0
0
.\src\drivers\uart.c
uart.c
0
0
4
23
1
0
0
0
0
.\src\drivers\hall.c
hall.c
0
0
4
24
1
0
0
0
0
- .\src\drivers\strain_gauge.c
- strain_gauge.c
- 0
- 0
-
-
- 4
- 25
- 1
- 0
- 0
- 0
- 0
- .\src\drivers\tachometer.c
- tachometer.c
- 0
- 0
-
-
- 4
- 26
- 1
- 0
- 0
- 0
- 0
.\src\drivers\led.c
led.c
0
0
4
- 27
+ 25
1
0
0
0
0
.\src\drivers\debug_gpio.c
debug_gpio.c
0
0
4
- 28
+ 26
1
0
0
0
0
.\src\drivers\button.c
button.c
0
0
SRC_lib
1
0
0
0
5
- 29
+ 27
1
0
0
0
0
.\src\lib\basic_filter.c
basic_filter.c
0
0
5
- 30
+ 28
1
0
0
0
0
.\src\lib\pid.c
pid.c
0
0
5
- 31
+ 29
1
0
0
0
0
.\src\lib\utils.c
utils.c
0
0
5
- 32
+ 30
1
0
0
0
0
.\src\lib\circular_buffer.c
circular_buffer.c
0
0
diff --git a/Firmware/carteHRI.uvprojx b/Firmware/carteHRI.uvprojx
index 4684c8a..2a6b74b 100644
--- a/Firmware/carteHRI.uvprojx
+++ b/Firmware/carteHRI.uvprojx
@@ -1,601 +1,591 @@
2.1
### uVision Project, (C) Keil Software
Target 1
0x4
ARM-ADS
STM32F407VG
STMicroelectronics
Keil.STM32F4xx_DFP.2.5.0
http://www.keil.com/pack
IROM(0x08000000,0x100000) IRAM(0x20000000,0x20000) IRAM2(0x10000000,0x10000) CPUTYPE("Cortex-M4") FPU2 CLOCK(168000000) ELITTLE
UL2CM3(-S0 -C0 -P0 -FD20000000 -FC1000 -FN1 -FF0STM32F4xx_1024 -FS08000000 -FL0100000 -FP0($$Device:STM32F407VG$Flash\STM32F4xx_1024.FLM))
6103
$$Device:STM32F407VG$Device\Include\stm32f4xx.h
$$Device:STM32F407VG$SVD\STM32F40x.svd
0
0
0
0
0
0
1
.\output\
motorControl
1
0
1
1
1
.\lst\
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
3
1
SARMCM3.DLL
-REMAP -MPU
DCM.DLL
-pCM4
SARMCM3.DLL
-REMAP -MPU
TCM.DLL
-pCM4
1
0
0
0
16
0
1
1
1
1
1
1
1
0
1
1
1
0
1
1
1
0
1
1
1
0
11
STLink\ST-LINKIII-KEIL_SWO.dll
1
0
0
1
1
4096
1
BIN\UL2CM3.DLL
"" ()
0
0
1
1
1
1
1
1
1
0
1
1
0
1
1
0
0
1
1
1
1
1
1
1
1
1
0
0
"Cortex-M4"
0
0
0
1
1
0
0
2
1
0
8
0
0
0
3
3
0
0
0
0
0
0
0
0
0
0
1
0
0
0
0
1
0
0
0x0
0x0
0
0x0
0x0
0
0x0
0x0
0
0x0
0x0
0
0x0
0x0
0
0x0
0x0
0
0x20000000
0x20000
1
0x8000000
0x100000
0
0x0
0x0
1
0x0
0x0
1
0x0
0x0
1
0x0
0x0
1
0x8000000
0x100000
1
0x0
0x0
0
0x0
0x0
0
0x0
0x0
0
0x0
0x0
0
0x20000000
0x20000
0
0x10000000
0x10000
1
4
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
USE_STDPERIPH_DRIVER STM32F4XX ARM_MATH_CM4
..\CodeUC;.\inc;.\src;C:\STM32F4-Discovery_FW_V1.1.0\Libraries\CMSIS\ST\STM32F4xx\Include;C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\inc;C:\STM32F4-Discovery_FW_V1.1.0\Utilities\STM32F4-Discovery;C:\STM32F4-Discovery_FW_V1.1.0\Libraries\CMSIS\Include
1
0
0
0
0
0
0
0
0
0
0
0
0
1
0
0x08000000
0x20000000
STM32_files
system_stm32f4xx.c
1
.\src\system_stm32f4xx.c
startup_stm32f4xx.s
2
.\startup_stm32f4xx.s
SRC
main.c
1
.\src\main.c
communication.c
1
.\src\communication.c
controller.c
1
.\src\controller.c
STM32_libs
stm32f4xx_gpio.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_gpio.c
stm32f4xx_rcc.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_rcc.c
stm32f4xx_tim.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_tim.c
misc.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\misc.c
stm32f4xx_exti.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_exti.c
stm32f4xx_syscfg.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_syscfg.c
stm32f4xx_adc.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_adc.c
stm32f4xx_dac.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_dac.c
stm32f4xx_dma.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_dma.c
stm32f4xx_usart.c
1
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\STM32F4xx_StdPeriph_Driver\src\stm32f4xx_usart.c
arm_cortexM4lf_math.lib
4
C:\STM32F4-Discovery_FW_V1.1.0\Libraries\CMSIS\Lib\ARM\arm_cortexM4lf_math.lib
SRC_drivers
adc.c
1
.\src\drivers\adc.c
callback_timers.c
1
.\src\drivers\callback_timers.c
dac.c
1
.\src\drivers\dac.c
h_bridge.c
1
.\src\drivers\h_bridge.c
incr_encoder.c
1
.\src\drivers\incr_encoder.c
uart.c
1
.\src\drivers\uart.c
hall.c
1
.\src\drivers\hall.c
-
- strain_gauge.c
- 1
- .\src\drivers\strain_gauge.c
-
-
- tachometer.c
- 1
- .\src\drivers\tachometer.c
-
led.c
1
.\src\drivers\led.c
debug_gpio.c
1
.\src\drivers\debug_gpio.c
button.c
1
.\src\drivers\button.c
SRC_lib
basic_filter.c
1
.\src\lib\basic_filter.c
pid.c
1
.\src\lib\pid.c
utils.c
1
.\src\lib\utils.c
circular_buffer.c
1
.\src\lib\circular_buffer.c
diff --git a/Firmware/src/communication.c b/Firmware/src/communication.c
index ea93fc1..c2d1c5a 100644
--- a/Firmware/src/communication.c
+++ b/Firmware/src/communication.c
@@ -1,964 +1,962 @@
#include "communication.h"
#include "controller.h"
#include "drivers/callback_timers.h"
#include "drivers/adc.h"
#include "drivers/dac.h"
#include "drivers/incr_encoder.h"
#include "drivers/hall.h"
-#include "drivers/strain_gauge.h"
-#include "drivers/tachometer.h"
#include "drivers/uart.h"
#include "lib/basic_filter.h"
#include "lib/pid.h"
#include "lib/utils.h"
#include
uint32_t selectedVariablesToStream; // Bitfield that indicates for each variable if it should be streamed or not.
uint8_t txBuffer[1024];
#define COMM_BUFFER_SIZE 4096
#define DEBUG_MESSAGE_BUFFER_SIZE 1024
uint8_t comm_packetTxBuffer[COMM_BUFFER_SIZE];
char comm_debugMessageBuffer[DEBUG_MESSAGE_BUFFER_SIZE];
cb_CircularBuffer *comm_rxQueue;
uint8_t rxCurrentMessageType = PC_MESSAGE_DO_NOTHING; // Current message type for RX bytes.
uint32_t rxBytesCount; // Number of received bytes for the current message.
uint8_t firstHalfByte; // First half of the data byte to receive.
uint8_t rxDataBytesBuffer[32]; // Data bytes received (ready to use, bytes already merged).
// SyncVar-related vars.
#define N_SYNCVARS_MAX 25
comm_SyncVar comm_syncVars[N_SYNCVARS_MAX];
uint8_t comm_nSyncVars;
volatile bool comm_varListLocked;
uint8_t comm_streamId;
uint8_t comm_nVarsToStream;
comm_SyncVar const* comm_streamedVars[N_SYNCVARS_MAX];
extern volatile uint32_t ctrl_timestamp; // [us].
// Private functions.
void comm_SendPacket(uint8_t messageType, uint8_t *data, uint16_t dataLength);
void comm_HandleByte(uint8_t rxData);
void comm_Stream(void);
void comm_GetVar(comm_SyncVar const *syncVar, uint8_t *varValueData);
void comm_SetVar(comm_SyncVar *syncVar, uint8_t *varValueData);
void comm_SendVarsList(void);
/**
* @brief Init the communication manager.
*/
void comm_Init(void)
{
comm_nSyncVars = 0;
comm_varListLocked = false;
comm_streamId = 0;
comm_nVarsToStream = 0;
// Setup the UART peripheral, and specify the function that will be called
// each time a byte is received.
uart_Init();
comm_rxQueue = uart_GetRxQueue();
rxCurrentMessageType = PC_MESSAGE_DO_NOTHING;
// Make the streaming function periodically called by the timer 7.
cbt_SetCommLoopTimer(comm_Stream, TE_DATA_LOOP_DEFAULT_VAL);
}
/**
* @brief Updates the communication manager.
* Send the bytes waiting in the TX buffer, and process the bytes received.
*/
void comm_Step(void)
{
// Send the bytes in the TX queue, even if it is not full, to avoid latency.
uart_FlushTx();
// Interpret the bytes in the RX queue.
uart_Step();
while(!cb_IsEmpty(comm_rxQueue))
comm_HandleByte(cb_Pull(comm_rxQueue));
}
/**
* @brief Sends a packet to notify the PC that the board just (re)started.
* This informs the PC software that the board is ready, and that the variables
* list can be retrieved.
*/
void comm_NotifyReady(void)
{
comm_SendPacket(STM_MESSAGE_START_INFO, NULL, 0);
}
/**
* @brief Generates and sends a data streaming packet.
*/
void comm_Stream()
{
// If the data streaming is enabled, send a stream packet to the PC.
if(comm_nVarsToStream > 0)
{
uint8_t i;
int nDataBytesToSend = 0;
// Stream ID.
txBuffer[nDataBytesToSend] = comm_streamId;
nDataBytesToSend++;
// Timestamp.
memcpy(&txBuffer[nDataBytesToSend], (uint32_t*)&ctrl_timestamp,
sizeof(ctrl_timestamp));
nDataBytesToSend += sizeof(ctrl_timestamp);
// SyncVars values.
for(i=0; isize;
}
comm_SendPacket(STM_MESSAGE_STREAMING_PACKET, txBuffer, nDataBytesToSend);
}
}
/**
* @brief Gets the value of a SyncVar.
* @param syncVar: address of the SyncVar to get the value from.
* @param varValueData: start address of an array to copy the raw bytes of the
* value of the SyncVar.
*/
void comm_GetVar(comm_SyncVar const *syncVar, uint8_t *varValueData)
{
comm_SyncVar const *v = syncVar;
if(v->usesVarAddress)
memcpy(varValueData, v->address, v->size);
else
{
switch(v->type)
{
case BOOL:
{
bool tmpBool = ((bool (*)(void))v->getFunc)();
memcpy(varValueData, &tmpBool, v->size);
}
break;
case UINT8:
{
uint8_t tmpUint8 = ((uint8_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpUint8, v->size);
}
break;
case INT8:
{
int8_t tmpInt8 = ((int8_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpInt8, v->size);
}
break;
case UINT16:
{
uint16_t tmpUint16 = ((uint16_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpUint16, v->size);
}
break;
case INT16:
{
int16_t tmpInt16 = ((int16_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpInt16, v->size);
}
break;
case UINT32:
{
uint32_t tmpUint32 = ((uint32_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpUint32, v->size);
}
break;
case INT32:
{
int32_t tmpInt32 = ((int32_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpInt32, v->size);
}
break;
case UINT64:
{
uint32_t tmpUint64 = ((uint64_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpUint64, v->size);
}
break;
case INT64:
{
int32_t tmpInt64 = ((int64_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpInt64, v->size);
}
break;
case FLOAT32:
{
float32_t tmpFloat = ((float32_t (*)(void))v->getFunc)();
memcpy(varValueData, &tmpFloat, v->size);
}
break;
case FLOAT64:
{
double tmpDouble = ((double (*)(void))v->getFunc)();
memcpy(varValueData, &tmpDouble, v->size);
}
break;
}
}
}
/**
* @brief Sets the value of a SyncVar.
* @param syncVar: address of the SyncVar to set the value.
* @param varValueData: start address of an array to copy the raw bytes to the
* SyncVar value.
*/
void comm_SetVar(comm_SyncVar *syncVar, uint8_t *varValueData)
{
comm_SyncVar *v = syncVar;
if(v->usesVarAddress)
{
if(v->access != READONLY)
memcpy(v->address, varValueData, v->size);
}
else
{
if(v->setFunc == NULL)
return;
switch(v->type)
{
case BOOL:
{
bool tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(bool))v->setFunc)(tmp);
}
break;
case UINT8:
{
uint8_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(uint8_t))v->setFunc)(tmp);
}
break;
case INT8:
{
int8_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(int8_t))v->setFunc)(tmp);
}
break;
case UINT16:
{
uint16_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(uint16_t))v->setFunc)(tmp);
}
break;
case INT16:
{
int16_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(int16_t))v->setFunc)(tmp);
}
break;
case UINT32:
{
uint32_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(uint32_t))v->setFunc)(tmp);
}
break;
case INT32:
{
int32_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(int32_t))v->setFunc)(tmp);
}
break;
case UINT64:
{
uint64_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(uint64_t))v->setFunc)(tmp);
}
break;
case INT64:
{
int64_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(int64_t))v->setFunc)(tmp);
}
break;
case FLOAT32:
{
float32_t tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(float32_t))v->setFunc)(tmp);
}
break;
case FLOAT64:
{
double tmp;
memcpy(&tmp, varValueData, v->size);
((void (*)(double))v->setFunc)(tmp);
}
break;
}
}
}
/**
* @brief Sends Packet with a header and data bytes.
* @param type: message type ("header" of the message).
* @param data: array of data bytes to be sent ("content" of the message).
* @param dataLength: number of data bytes to be sent.
*/
void comm_SendPacket(uint8_t type, uint8_t *data, uint16_t dataLength)
{
int i=0;
uint8_t *p = comm_packetTxBuffer;
*p = ((1<<7) | type);
p++;
for(i=0; i> 4); // Most significant bits.
p++;
*p = ((data[i]&0x0f)); // Least significant bits.
p++;
}
uart_SendBytesAsync(comm_packetTxBuffer, dataLength*2+1);
}
/**
* @brief Processes the received byte to interpret the messages.
* @param rxData: the byte to be processed and interpreted.
*/
void comm_HandleByte(uint8_t rxData)
{
if(rxData & (1<<7)) // The start byte has the most significant bit high.
{
rxCurrentMessageType = (rxData & ~(1<<7)); // Remove the start bit.
rxBytesCount = 0;
}
else
rxBytesCount++;
if(rxBytesCount % 2 == 1) // First half of the data byte has been received.
firstHalfByte = rxData; // Store it until the second half arrives.
else // Second half of the data byte has been received (or no data bytes yet).
{
int dataBytesReady = rxBytesCount/2;
rxDataBytesBuffer[dataBytesReady-1] = (firstHalfByte<<4) + (rxData & 0xf);
switch(rxCurrentMessageType)
{
case PC_MESSAGE_DO_NOTHING:
if(dataBytesReady == 0)
; // Do nothing.
break;
case PC_MESSAGE_PING:
if(dataBytesReady == 0)
comm_SendPacket(STM_MESSAGE_PINGBACK, NULL, 0);
break;
case PC_MESSAGE_GET_VARS_LIST:
if(dataBytesReady == 0 && comm_varListLocked)
{
int16_t i, length;
uint8_t *p = &txBuffer[0];
*p = (uint8_t)comm_nSyncVars;
p++;
for(i=0; i= comm_nSyncVars)
return;
v = &comm_syncVars[variableIndex];
// If the variable is not readable, ignore the request.
if((v->usesVarAddress && v->access == WRITEONLY) ||
(!v->usesVarAddress && v->getFunc == NULL))
{
break;
}
// Prepare the message to be sent to the PC.
// First byte: variable index.
txBuffer[0] = variableIndex;
// Following bytes: actual value of the variable.
comm_GetVar(v, &txBuffer[1]);
// Send the message to the PC.
comm_SendPacket(STM_MESSAGE_VAR, txBuffer, 1 + v->size);
}
break;
case PC_MESSAGE_SET_VAR:
if(dataBytesReady >= 1)
{
comm_SyncVar *v;
uint8_t variableIndex;
// Extract the index (that indicates which variable will change),
// and the new value of the variable.
variableIndex = rxDataBytesBuffer[0];
// If the variable index is out of range, ignore the request.
if(variableIndex >= comm_nSyncVars)
return;
v = &comm_syncVars[variableIndex];
// Set the selected variable with the new value.
if(dataBytesReady == 1 + v->size)
comm_SetVar(v, &rxDataBytesBuffer[1]);
}
break;
case PC_MESSAGE_SET_STREAMED_VAR:
if(dataBytesReady >= 1)
{
int i;
comm_nVarsToStream = rxDataBytesBuffer[0];
if(dataBytesReady != 1 + 1 + comm_nVarsToStream)
return;
comm_streamId = rxDataBytesBuffer[1];
for(i=0; i= N_SYNCVARS_MAX)
{
comm_SendDebugMessage("Warning: can't add the \"%s\" SyncVar, because "
"the list is full.", name);
return;
}
// Trim the name if it is too long.
if(strlen(name) > SYNCVAR_NAME_SIZE - 1)
{
memcpy(v.name, name, SYNCVAR_NAME_SIZE - 1);
v.name[SYNCVAR_NAME_SIZE - 1] = '\0';
}
else
strcpy(v.name, name);
// Build the SyncVar.
v.address = address;
v.type = type;
v.size = size;
v.access = access;
v.usesVarAddress = true;
// Add the SyncVar to the list.
comm_syncVars[comm_nSyncVars] = v;
comm_nSyncVars++;
}
/**
* @brief Adds a monitored variable to the list, with getter/setter functions.
* If the getter and setter are set to an actual function address (not NULL),
* the variable will be READWRITE. If the getter is NULL but setter is not NULL,
* the variable will be WRITEONLY. If the getter is not NULL the setter is NULL,
* the variable will be READONLY. If the getter and setter are both NULL, the
* variable will not be added to the variables list.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param type: the type of the variable.
* @param size: the size of the variable [bytes].
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorVarFunc(const char name[], comm_VarType type, uint8_t size,
void (*getFunc)(void), void (*setFunc)(void))
{
comm_SyncVar v;
// Adding a variable to the list is not allowed if it has been locked.
if(comm_varListLocked)
{
comm_SendDebugMessage("Warning: can't add the \"%s\" SyncVar, because "
"the list has already been locked.", name);
return;
}
// Adding a variable to the list is not allowed if it is full.
if(comm_nSyncVars >= N_SYNCVARS_MAX)
{
comm_SendDebugMessage("Warning: can't add the \"%s\" SyncVar, because "
"the list is full.", name);
return;
}
// Trim the name if it is too long.
if(strlen(name) > SYNCVAR_NAME_SIZE - 1)
{
memcpy(&v.name, &name, SYNCVAR_NAME_SIZE - 1);
v.name[SYNCVAR_NAME_SIZE - 1] = '\0';
}
else
strcpy(v.name, name);
// Build the SyncVar.
v.getFunc = getFunc;
v.setFunc = setFunc;
v.type = type;
v.size = size;
v.usesVarAddress = false;
// Determine the variable access.
if(getFunc != NULL && setFunc == NULL)
v.access = READONLY;
else if(getFunc == NULL && setFunc != NULL)
v.access = WRITEONLY;
else if(getFunc != NULL && setFunc != NULL)
v.access = READWRITE;
else
return; // No function provided at all, ignoring var.
// Add the SyncVar to the list.
comm_syncVars[comm_nSyncVars] = v;
comm_nSyncVars++;
}
/**
* @brief Adds a monitored bool variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorBool(const char name[], bool *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, BOOL, 1, access);
}
/**
* @brief Adds a monitored uint8_t variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorUint8(const char name[], uint8_t *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, UINT8, 1, access);
}
/**
* @brief Adds a monitored int8_t variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorInt8(const char name[], int8_t *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, INT8, 1, access);
}
/**
* @brief Adds a monitored uint16_t variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorUint16(const char name[], uint16_t *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, UINT16, 2, access);
}
/**
* @brief Adds a monitored int16_t variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorInt16(const char name[], int16_t *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, INT16, 2, access);
}
/**
* @brief Adds a monitored uint32_t variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorUint32(const char name[], uint32_t *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, UINT32, 4, access);
}
/**
* @brief Adds a monitored int32_t variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorInt32(const char name[], int32_t *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, INT32, 4, access);
}
/**
* @brief Adds a monitored uint64_t variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorUint64(const char name[], uint64_t *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, UINT64, 8, access);
}
/**
* @brief Adds a monitored int64_t variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorInt64(const char name[], int64_t *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, INT64, 8, access);
}
/**
* @brief Adds a monitored float variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorFloat(const char name[], float *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, FLOAT32, 4, access);
}
/**
* @brief Adds a monitored double variable to the list, with its address.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param address a pointer to the variable to monitor.
* @param access: the access rights to this variable (READONLY, WRITEONLY, or
* READWRITE).
*/
void comm_monitorDouble(const char name[], double *address,
comm_VarAccess access)
{
comm_monitorVar(name, address, FLOAT64, 8, access);
}
/**
* @brief Adds a monitored bool variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorBoolFunc(const char name[],
bool (*getFunc)(void), void (*setFunc)(bool))
{
comm_monitorVarFunc(name, BOOL, 1, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored uint8_t variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorUint8Func(const char name[],
uint8_t (*getFunc)(void), void (*setFunc)(uint8_t))
{
comm_monitorVarFunc(name, UINT8, 1, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored int8_t variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorInt8Func(const char name[],
int8_t (*getFunc)(void), void (*setFunc)(int8_t))
{
comm_monitorVarFunc(name, INT8, 1, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored uint16_t variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorUint16Func(const char name[],
uint16_t (*getFunc)(void),
void (*setFunc)(uint16_t))
{
comm_monitorVarFunc(name, UINT16, 2, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored int16_t variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorInt16Func(const char name[],
int16_t (*getFunc)(void), void (*setFunc)(int16_t))
{
comm_monitorVarFunc(name, INT16, 2, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored uint32_t variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorUint32Func(const char name[],
uint32_t (*getFunc)(void),
void (*setFunc)(uint32_t))
{
comm_monitorVarFunc(name, UINT32, 4, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored int32_t variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorInt32Func(const char name[],
int32_t (*getFunc)(void), void (*setFunc)(int32_t))
{
comm_monitorVarFunc(name, INT32, 4, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored uint64_t variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorUint64Func(const char name[],
uint64_t (*getFunc)(void),
void (*setFunc)(uint64_t))
{
comm_monitorVarFunc(name, UINT64, 8, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored int64_t variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorInt64Func(const char name[],
int64_t (*getFunc)(void), void (*setFunc)(int64_t))
{
comm_monitorVarFunc(name, INT64, 8, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored float variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorFloatFunc(const char name[],
float (*getFunc)(void), void (*setFunc)(float))
{
comm_monitorVarFunc(name, FLOAT32, 4, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Adds a monitored double variable to the list, with getter/setter.
* @param name: the description of the variable, as it should be displayed to
* the user. It should also include the unit, if relevant.
* @param getFunc: function pointer on the getter function.
* @param setFunc: function pointer on the setter function.
*/
void comm_monitorDoubleFunc(const char name[],
double (*getFunc)(void), void (*setFunc)(double))
{
comm_monitorVarFunc(name, FLOAT64, 8, (void (*)(void))getFunc, (void (*)(void))setFunc);
}
/**
* @brief Locks the monitored variables, so it can be used.
* After the call to this function, adding variables will not be possible
* anymore. The PC will not be able to get the variables list until this
* function is called.
*/
void comm_LockSyncVarsList(void)
{
comm_varListLocked = true;
}
/**
* @brief Generates and sends a packet describing the monitored variables.
*/
void comm_SendVarsList(void)
{
int i;
uint8_t *p;
uint16_t buffLength = 1 + comm_nSyncVars * (SYNCVAR_NAME_SIZE + 1 + 1);
p = &txBuffer[0];
*p = comm_nSyncVars;
p++;
for(i=0; iDR;
DMA_Init(DMA2_Stream1, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream1, ENABLE);
}
/**
* @brief Compute the current sense offset.
* @note Run before enabling current regulation.
*/
void adc_CalibrateCurrentSens(void)
{
float32_t offset;
int32_t i=0;
for(i=0; iCR2 |= (uint32_t)ADC_CR2_SWSTART;
+ ADC_Cmd(ADC1, DISABLE);
+ ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_56Cycles);
+ ADC_Cmd(ADC1, ENABLE);
+ utils_DelayUs(1);
+ ADC_SoftwareStartConv(ADC1);
}
/**
- * @brief Get the ADC conversion status of the selected channel.
+ * @brief Gets the ADC conversion status of the selected channel.
* @retval 1 if the conversion is finished, 0 otherwise.
*/
-uint8_t adc_ConversionIsFinished(AdcChannel channel)
+bool adc_ConversionIsFinished(void)
{
- if(channel == ANIN1)
- return (ADC1->SR & ADC_SR_EOC) != 0;
- else
- return 0;
+ return (ADC1->SR & ADC_SR_EOC) != 0;
}
/**
- * @brief Get the voltage measured by the selected ADC channel.
- * @param channel: the channel of the ADC.
- * @return the measured voltage, in [V], or 0.0f if the channel is invalid.
- * @note make sure that the conversion is finished before calling.
+ * @brief Gets the voltage measured by the selected ADC channel.
+ * @return the measured voltage [V].
+ * @note make sure that the conversion is finished before calling.
*/
-float32_t adc_GetConversionResult(AdcChannel channel)
+float32_t adc_GetConversionResult(void)
{
float32_t adcRawVal, voltage;
- if(channel == ANIN1)
- adcRawVal = (float32_t)ADC1->DR;
- else
- adcRawVal = 0.0f;
+ adcRawVal = (float32_t)ADC1->DR;
voltage = (adcRawVal / ADC_MAX) * ADC_REF_VOLTAGE;
return voltage;
}
/**
- * @brief Get the voltage measured by the selected ADC channel.
- * @param channel: the channel of the ADC.
- * @return the measured voltage, in [V], or 0.0f if the channel is invalid.
- * @note make sure that the conversion is finished before calling.
+ * @brief Gets the voltage measured by the selected ADC channel.
+ * @param channel: the channel of the ADC.
+ * @return the measured voltage [V].
*/
float32_t adc_GetChannelVoltage(AdcChannel channel)
{
int32_t conversionTime = 0;
adc_StartConversion(channel);
- while(!adc_ConversionIsFinished(channel))
+ while(!adc_ConversionIsFinished())
{
if(conversionTime < ADC_MAX_CONVERSION_TIME)
conversionTime++;
else
break;
}
- return adc_GetConversionResult(channel);
+ return adc_GetConversionResult();
}
diff --git a/Firmware/src/drivers/adc.h b/Firmware/src/drivers/adc.h
index 90dc97e..0d33570 100644
--- a/Firmware/src/drivers/adc.h
+++ b/Firmware/src/drivers/adc.h
@@ -1,67 +1,82 @@
#ifndef __ADC_H
#define __ADC_H
#include "../main.h"
#define ADC_HALL_PIN GPIO_Pin_1
#define ADC_HALL_PORT GPIOB
#define ADC_HALL_CHANNEL ADC_Channel_9
+#define ADC_ANIN1_PIN GPIO_Pin_6
+#define ADC_ANIN1_PORT GPIOA
+#define ADC_ANIN1_CHANNEL ADC_Channel_6
+
+#define ADC_ANIN2_PIN GPIO_Pin_7
+#define ADC_ANIN2_PORT GPIOA
+#define ADC_ANIN2_CHANNEL ADC_Channel_7
+
+#define ADC_ANIN3_PIN GPIO_Pin_4
+#define ADC_ANIN3_PORT GPIOC
+#define ADC_ANIN3_CHANNEL ADC_Channel_14
+
+#define ADC_ANIN4_PIN GPIO_Pin_5
+#define ADC_ANIN4_PORT GPIOC
+#define ADC_ANIN4_CHANNEL ADC_Channel_15
+
#define ADC_CURRENT_SENSE_PIN GPIO_Pin_3
#define ADC_CURRENT_SENSE_PORT GPIOA
#define ADC_CURRENT_SENSE_CHANNEL ADC_Channel_3
#define ADC_MAX 4095.0f // Maximum value of the ADC register (2^12 - 1).
#define ADC_MAX_CONVERSION_TIME 100 // To avoid locking if the conversion was not started properly.
#define ADC_BUFFER_SIZE 33 // Fadc =~300kHz -> TE_ADC = 3.33us -> Average over 32 sample => usable bandwidth <10kHz
#define ADC_CURRENT_SCALE (ADC_REF_VOLTAGE / (CURRENT_SHUNT_RESISTANCE * CURRENT_SHUNT_AMPLIFIER_GAIN * ADC_MAX)) // Scale between ADC increment and current [A/incr].
#define ADC_CALIB_N_SAMPLES 1000
#define ADC_REF_VOLTAGE 2.5f // [V].
/** @defgroup ADC Driver / ADC
* @brief Driver for the analog-to-digital peripheral of the STM32.
*
* An analog-to-digital converter (ADC) is used to measure the voltage of one
- * or several microcontroller pins. In the HRI board, there are two pins that
- * can be used. An intermediate electronic stage allows to modify the input
- * range from +-33mV to +-10V, in order to get the best sensitivity and range
- * for a wide range of analog sensors. Note that the input connector
- * (J2-ANALOG IN) provides differential inputs, so one pair of pins per
- * channel.
+ * or several microcontroller analog pins.
*
* In addition, there is an additional channel to measure the current going
* through the motor (useful for current regulation).
*
* Call adc_Init() first, in the initialization code. Then, call
* adc_GetChannelVoltage() every time you need the voltage.
*
* To measure accurately the motor current, a calibration has to be performed
* first. Call dc_CalibrateCurrentSens() in the main(), when the current
* regulation is disabled (see H-bridge documentation). Then, call
* adc_GetCurrent() every time it is needed. This function returns the last
* value transfered by the DMA, so there is no conversion delay when calling
* this function.
*
* @addtogroup ADC
* @{
*/
/**
* @brief Enum that corresponds to the two ADC input channels of the board.
*/
typedef enum
{
- ANIN1=1 ///< Channel 1, pins ANIN1+ (3) and ANIN1- (4) of the connector J2.
+ ADC_CHANNEL_9 = 9, ///< Pin HALL_INPUT (5) of the connector J9 (Hall position sensor).
+ ADC_CHANNEL_6 = 6, ///< Pin AN_IN1 (29 & 30) of the connector J12 (analog extension).
+ ADC_CHANNEL_7 = 7, ///< Pin AN_IN2 (33 & 34) of the connector J12 (analog extension).
+ ADC_CHANNEL_14 = 14, ///< Pin AN_IN3 (37 & 38) of the connector J12 (analog extension).
+ ADC_CHANNEL_15 = 15, ///< Pin AN_IN4 (41 & 42) of the connector J12 (analog extension).
} AdcChannel;
void adc_Init(void);
void adc_CalibrateCurrentSens(void);
float32_t adc_GetCurrent(void); // [mA].
float32_t adc_GetChannelVoltage(AdcChannel channel);
/**
* @}
*/
#endif
diff --git a/Firmware/src/drivers/strain_gauge.c b/Firmware/src/drivers/strain_gauge.c
deleted file mode 100644
index f718a85..0000000
--- a/Firmware/src/drivers/strain_gauge.c
+++ /dev/null
@@ -1,33 +0,0 @@
-#include "strain_gauge.h"
-#include "dac.h"
-#include "../lib/basic_filter.h"
-
-AdcChannel sg_channel;
-bfilt_BasicFilter sg_filt;
-
-/**
- * @brief Initialize the strain gauge driver.
- * @param channel: the ADC channel the strain gauge is wired to (0 or 1).
- */
-void sg_Init(AdcChannel channel)
-{
- sg_channel = channel;
-
- dac_SetVoltage2(2.4f);
-
- bfilt_Init(&sg_filt, 0.1f, 0.0f);
-}
-
-/**
- * @brief Return the measured force on the paddle.
- * @retval The force applied to the top of the paddle [N].
- * @warning this function is not implemented yet, and returns actually the raw
- * voltage from the sensor, instead of the ready-to-use force.
- */
-float32_t sg_Get(void)
-{
- float32_t voltage = adc_GetChannelVoltage(sg_channel);
-
- // TODO: the voltage to torque conversion is not implemented yet.
- return bfilt_Step(&sg_filt, voltage);
-}
diff --git a/Firmware/src/drivers/strain_gauge.h b/Firmware/src/drivers/strain_gauge.h
deleted file mode 100644
index 0a50b83..0000000
--- a/Firmware/src/drivers/strain_gauge.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __STRAIN_GAUGE_H
-#define __STRAIN_GAUGE_H
-
-#include "../main.h"
-#include "adc.h"
-
-/** @defgroup StrainGauge Driver / Strain gauge
- * @brief Driver for a strain gauge.
- *
- * This driver uses an ADC input, ANIN1 or ANIN2 (see ADC).
- * To use this, connect wire the sensor as this:
- * * sensor + -> +5V (pin 1 or 5 of J2).
- * * sensor - -> GND (pin 2 or 6 of J2).
- * * sensor sense -> ANINX+ (pin 3 or 7 of J2).
- * * 2.5V (with a voltage divider between 5V and GND) -> ANINX- (pin 4 or 8 of
- * J2).
- *
- * Set the sensitivity switches to +-33mV.
- *
- * Call sg_Init() first in the initialization code. Then, call sg_Get() to
- * get the force.
- *
- * @addtogroup StrainGauge
- * @{
- */
-
-void sg_Init(AdcChannel channel);
-float32_t sg_Get(void);
-
-/**
- * @}
- */
-
-#endif
diff --git a/Firmware/src/drivers/tachometer.c b/Firmware/src/drivers/tachometer.c
deleted file mode 100644
index 6ddc80d..0000000
--- a/Firmware/src/drivers/tachometer.c
+++ /dev/null
@@ -1,24 +0,0 @@
-#include "tachometer.h"
-
-AdcChannel tac_channel;
-
-/**
- * @brief Initialize the tachometer driver.
- * @param channel: the ADC channel the tachometer is wired to (0 or 1).
- */
-void tac_Init(AdcChannel channel)
-{
- tac_channel = channel;
-}
-
-/**
- * @brief Return the measured paddle angular speed.
- * @retval The paddle angular speed [deg/s].
- */
-float32_t tac_Get(void)
-{
- float32_t voltage = adc_GetChannelVoltage(tac_channel);
-
- // Conversion from voltage to angular speed.
- return voltage * TAC_VOLTAGE_TO_RPM;
-}
diff --git a/Firmware/src/drivers/tachometer.h b/Firmware/src/drivers/tachometer.h
deleted file mode 100644
index 6fe9c98..0000000
--- a/Firmware/src/drivers/tachometer.h
+++ /dev/null
@@ -1,34 +0,0 @@
-#ifndef __TACHOMETER_H
-#define __TACHOMETER_H
-
-#include "../main.h"
-#include "adc.h"
-
-#define TAC_RPM_TO_VOLTAGE 0.00052f // According to the Maxon DC Tacho DCT 22 datasheet [V/RPM].
-#define TAC_VOLTAGE_TO_RPM (1/TAC_RPM_TO_VOLTAGE) // [RPM/V].
-
-/** @defgroup Tachometer Driver / Tachometer
- * @brief Driver for a tachometer.
- *
- * This driver uses an ADC input, ANIN1 or ANIN2 (see ADC).
- * To use this, connect wire the sensor as this:
- * * tacho 1 -> ANINX+ (pin 3 or 7 of J2).
- * * tacho 2 -> ANINX- (pin 4 or 8 of J2).
- *
- * Set the sensitivity switches to +-2V.
- *
- * Call tac_Init() first in the initialization code. Then, call tac_Get() to
- * get the motor speed.
- *
- * @addtogroup Tachometer
- * @{
- */
-
-void tac_Init(AdcChannel channel);
-float32_t tac_Get(void);
-
-/**
- * @}
- */
-
-#endif
diff --git a/Firmware/src/main.c b/Firmware/src/main.c
index 57c4556..93b244d 100644
--- a/Firmware/src/main.c
+++ b/Firmware/src/main.c
@@ -1,77 +1,73 @@
#include "main.h"
#include "communication.h"
#include "controller.h"
#include "drivers/adc.h"
#include "drivers/callback_timers.h"
#include "drivers/dac.h"
#include "drivers/debug_gpio.h"
#include "drivers/h_bridge.h"
#include "drivers/hall.h"
#include "drivers/incr_encoder.h"
#include "drivers/led.h"
-#include "drivers/strain_gauge.h"
-#include "drivers/tachometer.h"
#include "lib/utils.h"
extern volatile uint32_t ctrl_timestamp;
volatile uint32_t statusReg = 0x00000000; // Main state register.
/**
* @brief Main function, setups all the drivers and controllers.
*/
int main(void)
{
// Setup the GPIOs and the interrupts.
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB |
RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD |
RCC_AHB1Periph_GPIOE, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
//
cbt_Init(); // Setup the timers that will call the loops functions.
adc_Init(); // Setup the ADC.
comm_Init(); // Setup the communication module.
ctrl_Init(); // Setup the controllers.
enc_Init(); // Setup the incremental encoders.
hb_Init(); // Setup the H-bridge.
hb_Enable(); //
dac_Init(); // Setup the DAC.
led_Init(); // Setup the LEDs.
dio_Init();
// Delay to let the power electronics stabilize before calibrating the
// current sensor.
utils_DelayMs(200);
adc_CalibrateCurrentSens();
// Start the current loop.
ctrl_StartCurrentLoop();
- // Init the external sensors drivers, connected to the ADC.
- hall_Init(ANIN1);
- //sg_Init(ANIN2);
- //tac_Init(ANIN2);
+ // Init the Hall position sensor.
+ hall_Init(ADC_CHANNEL_9);
// End of the initialization. Lock the SyncVar list, and notify the PC that
// the board has (re)started.
comm_LockSyncVarsList();
comm_NotifyReady();
// Endless loop. The low priority functions are called here.
while(1)
{
// Update the communication.
comm_Step();
}
}