Compare commits
13 Commits
d4136f0761
...
button
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59e1003262 | ||
|
|
3480cba21c | ||
|
|
03dcfd6bbe | ||
|
|
8214617e3a | ||
|
|
f980e62407 | ||
|
|
9550b1b61d | ||
|
|
5b66b044b7 | ||
|
|
05465086c4 | ||
|
|
cfda94afc1 | ||
|
|
cb232ea55e | ||
|
|
8ce717033a | ||
|
|
75132eb040 | ||
|
|
7b32859c88 |
@@ -38,6 +38,8 @@ set(PROJECT_INCLUDE_DIRECTORIES
|
|||||||
SHAL/Include/Peripheral/UART/Reg
|
SHAL/Include/Peripheral/UART/Reg
|
||||||
SHAL/Include/Peripheral/I2C
|
SHAL/Include/Peripheral/I2C
|
||||||
SHAL/Include/Peripheral/I2C/Reg
|
SHAL/Include/Peripheral/I2C/Reg
|
||||||
|
SHAL/Include/Peripheral/ADC
|
||||||
|
SHAL/Include/Peripheral/ADC/Reg
|
||||||
SHAL/Include/Peripheral/EXT/
|
SHAL/Include/Peripheral/EXT/
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include
|
${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -22,6 +22,22 @@ void SHAL_init();
|
|||||||
|
|
||||||
//Universal structs and defines ---------------------------
|
//Universal structs and defines ---------------------------
|
||||||
|
|
||||||
|
enum class SHAL_Result{
|
||||||
|
OKAY,
|
||||||
|
ERROR
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
typedef bool (*condition_fn_t)(void);
|
||||||
|
|
||||||
|
#define SHAL_WAIT_FOR_CONDITION_US(cond, timeout_us) \
|
||||||
|
SHAL_wait_for_condition_us([&](){ return (cond); }, (timeout_us))
|
||||||
|
|
||||||
|
#define SHAL_WAIT_FOR_CONDITION_MS(cond, timeout_ms) \
|
||||||
|
SHAL_wait_for_condition_ms([&](){ return (cond); }, (timeout_ms))
|
||||||
|
|
||||||
|
|
||||||
//Currently configures systick to count down in microseconds
|
//Currently configures systick to count down in microseconds
|
||||||
void systick_init();
|
void systick_init();
|
||||||
|
|
||||||
@@ -30,6 +46,28 @@ void SHAL_delay_us(uint32_t us);
|
|||||||
|
|
||||||
void SHAL_delay_ms(uint32_t ms);
|
void SHAL_delay_ms(uint32_t ms);
|
||||||
|
|
||||||
|
template<typename Condition>
|
||||||
|
bool SHAL_wait_for_condition_us(Condition cond, uint32_t timeout_us) {
|
||||||
|
while (timeout_us--) {
|
||||||
|
if (cond()) {
|
||||||
|
return true; // success
|
||||||
|
}
|
||||||
|
SHAL_delay_us(1);
|
||||||
|
}
|
||||||
|
return false; // timeout
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Condition>
|
||||||
|
bool SHAL_wait_for_condition_ms(Condition cond, uint32_t timeout_ms) {
|
||||||
|
while (timeout_ms--) {
|
||||||
|
if (cond()) {
|
||||||
|
return true; // success
|
||||||
|
}
|
||||||
|
SHAL_delay_ms(1);
|
||||||
|
}
|
||||||
|
return false; // timeout
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
31
SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_F072xB.h
Normal file
31
SHAL/Include/Peripheral/ADC/Reg/SHAL_ADC_REG_F072xB.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
//
|
||||||
|
// Created by Luca on 9/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SHMINGO_HAL_SHAL_ADC_REG_F072XB_H
|
||||||
|
#define SHMINGO_HAL_SHAL_ADC_REG_F072XB_H
|
||||||
|
|
||||||
|
#include "SHAL_CORE.h"
|
||||||
|
#include "SHAL_ADC_TYPES.h"
|
||||||
|
|
||||||
|
#define SHAL_ADC1 SHAL_ADC(1)
|
||||||
|
|
||||||
|
enum class ADC_Key : uint8_t{
|
||||||
|
S_ADC1,
|
||||||
|
NUM_ADC,
|
||||||
|
INVALID
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr ADC_TypeDef* getADCRegister(ADC_Key key){
|
||||||
|
switch(key){
|
||||||
|
case ADC_Key::S_ADC1:
|
||||||
|
return ADC1;
|
||||||
|
|
||||||
|
case ADC_Key::NUM_ADC:
|
||||||
|
case ADC_Key::INVALID:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //SHMINGO_HAL_SHAL_ADC_REG_F072XB_H
|
||||||
66
SHAL/Include/Peripheral/ADC/SHAL_ADC.h
Normal file
66
SHAL/Include/Peripheral/ADC/SHAL_ADC.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
//
|
||||||
|
// Created by Luca on 9/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SHMINGO_HAL_SHAL_ADC_H
|
||||||
|
#define SHMINGO_HAL_SHAL_ADC_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "SHAL_CORE.h"
|
||||||
|
#include "SHAL_ADC_REG.h"
|
||||||
|
|
||||||
|
class SHAL_ADC {
|
||||||
|
|
||||||
|
friend class ADCManager;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
SHAL_Result init();
|
||||||
|
|
||||||
|
SHAL_Result calibrate();
|
||||||
|
|
||||||
|
/// Performs analog to digital conversion on a single channel, one time
|
||||||
|
/// \param channel Channel to be converted
|
||||||
|
/// \param time ADC_SampleTime - amount of clock cycles per conversion
|
||||||
|
/// \return resulting value
|
||||||
|
uint16_t singleConvertSingle(ADC_Channel channel, ADC_SampleTime time = ADC_SampleTime::C239);
|
||||||
|
|
||||||
|
/// Performs analog to digital conversion on multiple channels, one time
|
||||||
|
/// \param channels Pointer to an array of channels to convert
|
||||||
|
/// \param numChannels Number of channels to convert
|
||||||
|
/// \param result Pointer to store converted channel results in
|
||||||
|
/// \param time ADC_SampleTime - amount of clock cycles per conversion
|
||||||
|
void multiConvertSingle(ADC_Channel* channels, const int numChannels, uint16_t* result, ADC_SampleTime time = ADC_SampleTime::C239);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
SHAL_ADC() = default;
|
||||||
|
|
||||||
|
ADC_Key m_ADCKey = ADC_Key::INVALID;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define SHAL_ADC(x) ADCManager::getByIndex(x-1)
|
||||||
|
|
||||||
|
class ADCManager{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static SHAL_ADC& get(ADC_Key key);
|
||||||
|
|
||||||
|
static SHAL_ADC& getByIndex(int index);
|
||||||
|
|
||||||
|
|
||||||
|
ADCManager() = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
inline static SHAL_ADC m_ADCs[static_cast<uint8_t>(ADC_Key::NUM_ADC)] = {};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //SHMINGO_HAL_SHAL_ADC_H
|
||||||
44
SHAL/Include/Peripheral/ADC/SHAL_ADC_REG.h
Normal file
44
SHAL/Include/Peripheral/ADC/SHAL_ADC_REG.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
//
|
||||||
|
// Created by Luca on 9/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SHMINGO_HAL_SHAL_ADC_REG_H
|
||||||
|
#define SHMINGO_HAL_SHAL_ADC_REG_H
|
||||||
|
|
||||||
|
#if defined(STM32F030x6)
|
||||||
|
#include "stm32f030x6.h"
|
||||||
|
#elif defined(STM32F030x8)
|
||||||
|
#include "stm32f030x8.h"
|
||||||
|
#elif defined(STM32F031x6)
|
||||||
|
#include "stm32f031x6.h"
|
||||||
|
#elif defined(STM32F038xx)
|
||||||
|
#include "stm32f038xx.h"
|
||||||
|
#elif defined(STM32F042x6)
|
||||||
|
#include "stm32f042x6.h"
|
||||||
|
#elif defined(STM32F048xx)
|
||||||
|
#include "stm32f048xx.h"
|
||||||
|
#elif defined(STM32F051x8)
|
||||||
|
#include "stm32f051x8.h"
|
||||||
|
#elif defined(STM32F058xx)
|
||||||
|
#include "stm32f058xx.h"
|
||||||
|
#elif defined(STM32F070x6)
|
||||||
|
#include "stm32f070x6.h"
|
||||||
|
#elif defined(STM32F070xB)
|
||||||
|
#include "stm32f070xb.h"
|
||||||
|
#elif defined(STM32F071xB)
|
||||||
|
#include "stm32f071xb.h"
|
||||||
|
#elif defined(STM32F072xB)
|
||||||
|
#include "SHAL_ADC_REG_F072xB.h"
|
||||||
|
#elif defined(STM32F078xx)
|
||||||
|
#include "stm32f078xx.h"
|
||||||
|
#elif defined(STM32F091xC)
|
||||||
|
#include "stm32f091xc.h"
|
||||||
|
#elif defined(STM32F098xx)
|
||||||
|
#include "stm32f098xx.h"
|
||||||
|
#elif defined(STM32F030xC)
|
||||||
|
#include "stm32f030xc.h"
|
||||||
|
#else
|
||||||
|
#error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //SHMINGO_HAL_SHAL_ADC_REG_H
|
||||||
41
SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h
Normal file
41
SHAL/Include/Peripheral/ADC/SHAL_ADC_TYPES.h
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// Created by Luca on 9/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SHMINGO_HAL_SHAL_ADC_TYPES_H
|
||||||
|
#define SHMINGO_HAL_SHAL_ADC_TYPES_H
|
||||||
|
|
||||||
|
enum class ADC_Channel : uint32_t {
|
||||||
|
CH0 = ADC_CHSELR_CHSEL0,
|
||||||
|
CH1 = ADC_CHSELR_CHSEL1,
|
||||||
|
CH2 = ADC_CHSELR_CHSEL2,
|
||||||
|
CH3 = ADC_CHSELR_CHSEL3,
|
||||||
|
CH4 = ADC_CHSELR_CHSEL4,
|
||||||
|
CH5 = ADC_CHSELR_CHSEL5,
|
||||||
|
CH6 = ADC_CHSELR_CHSEL6,
|
||||||
|
CH7 = ADC_CHSELR_CHSEL7,
|
||||||
|
CH8 = ADC_CHSELR_CHSEL8,
|
||||||
|
CH9 = ADC_CHSELR_CHSEL9,
|
||||||
|
CH10 = ADC_CHSELR_CHSEL10,
|
||||||
|
CH11 = ADC_CHSELR_CHSEL11,
|
||||||
|
CH12 = ADC_CHSELR_CHSEL12,
|
||||||
|
CH13 = ADC_CHSELR_CHSEL13,
|
||||||
|
CH14 = ADC_CHSELR_CHSEL14,
|
||||||
|
CH15 = ADC_CHSELR_CHSEL15,
|
||||||
|
CHTemp = ADC_CHSELR_CHSEL16,
|
||||||
|
CHRef = ADC_CHSELR_CHSEL17,
|
||||||
|
CHBat = ADC_CHSELR_CHSEL18
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ADC_SampleTime : uint32_t {
|
||||||
|
C2 = 0x00, //1.5 cycles per sample
|
||||||
|
C7 = 0x01, //7.5 cycles
|
||||||
|
C13 = 0x02, //13.5 cycles
|
||||||
|
C28 = 0x03, //28.5 cycles
|
||||||
|
C41 = 0x04, //41.5 cycles
|
||||||
|
C55 = 0x05, //55.5 cycles
|
||||||
|
C71 = 0x06, //71.5 cycles
|
||||||
|
C239 = 0x07 //239.5 cycles
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //SHMINGO_HAL_SHAL_ADC_TYPES_H
|
||||||
@@ -270,6 +270,79 @@ constexpr uint32_t getGPIOPortNumber(const GPIO_Key g){
|
|||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
constexpr SHAL_GPIO_Port_Info getGPIOPortInfo(GPIO_Key key){
|
||||||
|
switch(key){
|
||||||
|
case GPIO_Key::A0:
|
||||||
|
case GPIO_Key::B0:
|
||||||
|
case GPIO_Key::C0:
|
||||||
|
return {0,ADC_Channel::CH0};
|
||||||
|
case GPIO_Key::A1:
|
||||||
|
case GPIO_Key::B1:
|
||||||
|
case GPIO_Key::C1:
|
||||||
|
return {1,ADC_Channel::CH1};
|
||||||
|
case GPIO_Key::A2:
|
||||||
|
case GPIO_Key::B2:
|
||||||
|
case GPIO_Key::C2:
|
||||||
|
return {2,ADC_Channel::CH2};
|
||||||
|
case GPIO_Key::A3:
|
||||||
|
case GPIO_Key::B3:
|
||||||
|
case GPIO_Key::C3:
|
||||||
|
return {3,ADC_Channel::CH3};
|
||||||
|
case GPIO_Key::A4:
|
||||||
|
case GPIO_Key::B4:
|
||||||
|
case GPIO_Key::C4:
|
||||||
|
return {4,ADC_Channel::CH4};
|
||||||
|
case GPIO_Key::A5:
|
||||||
|
case GPIO_Key::B5:
|
||||||
|
case GPIO_Key::C5:
|
||||||
|
return {5,ADC_Channel::CH5};
|
||||||
|
case GPIO_Key::A6:
|
||||||
|
case GPIO_Key::B6:
|
||||||
|
case GPIO_Key::C6:
|
||||||
|
return {6,ADC_Channel::CH6};
|
||||||
|
case GPIO_Key::A7:
|
||||||
|
case GPIO_Key::B7:
|
||||||
|
case GPIO_Key::C7:
|
||||||
|
return {7,ADC_Channel::CH7};
|
||||||
|
case GPIO_Key::A8:
|
||||||
|
case GPIO_Key::B8:
|
||||||
|
case GPIO_Key::C8:
|
||||||
|
return {8,ADC_Channel::CH8};
|
||||||
|
case GPIO_Key::A9:
|
||||||
|
case GPIO_Key::B9:
|
||||||
|
case GPIO_Key::C9:
|
||||||
|
return {9,ADC_Channel::CH9};
|
||||||
|
case GPIO_Key::A10:
|
||||||
|
case GPIO_Key::B10:
|
||||||
|
case GPIO_Key::C10:
|
||||||
|
return {10,ADC_Channel::CH10};
|
||||||
|
case GPIO_Key::A11:
|
||||||
|
case GPIO_Key::B11:
|
||||||
|
case GPIO_Key::C11:
|
||||||
|
return {11,ADC_Channel::CH11};
|
||||||
|
case GPIO_Key::A12:
|
||||||
|
case GPIO_Key::B12:
|
||||||
|
case GPIO_Key::C12:
|
||||||
|
return {12,ADC_Channel::CH12};
|
||||||
|
case GPIO_Key::A13:
|
||||||
|
case GPIO_Key::B13:
|
||||||
|
case GPIO_Key::C13:
|
||||||
|
return {13,ADC_Channel::CH13};
|
||||||
|
case GPIO_Key::A14:
|
||||||
|
case GPIO_Key::B14:
|
||||||
|
case GPIO_Key::C14:
|
||||||
|
return {14,ADC_Channel::CH14};
|
||||||
|
case GPIO_Key::A15:
|
||||||
|
case GPIO_Key::B15:
|
||||||
|
case GPIO_Key::C15:
|
||||||
|
return {15,ADC_Channel::CH15};
|
||||||
|
case GPIO_Key::NUM_GPIO:
|
||||||
|
case GPIO_Key::INVALID:
|
||||||
|
return {0,ADC_Channel::CH0};
|
||||||
|
}
|
||||||
|
__builtin_unreachable();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
#endif //SHMINGO_HAL_SHAL_GPIO_REG_F072XB_H
|
||||||
|
|||||||
@@ -10,9 +10,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
#include "SHAL_EXTI_CALLBACK.h"
|
#include "SHAL_EXTI_CALLBACK.h"
|
||||||
|
#include "SHAL_ADC.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Abstraction of SHAL_GPIO registers
|
//Abstraction of SHAL_GPIO registers
|
||||||
@@ -26,6 +24,11 @@ public:
|
|||||||
void setHigh();
|
void setHigh();
|
||||||
void setLow();
|
void setLow();
|
||||||
|
|
||||||
|
/// Uses the ADC to read an analog voltage value
|
||||||
|
/// \param sampleTime The amount of clock cycles to use for the ADC
|
||||||
|
/// \return ADC result
|
||||||
|
uint16_t analogRead(ADC_SampleTime sampleTime = ADC_SampleTime::C239);
|
||||||
|
|
||||||
void setPinMode(PinMode mode) volatile;
|
void setPinMode(PinMode mode) volatile;
|
||||||
|
|
||||||
void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
|
void setAlternateFunction(GPIO_Alternate_Function AF) volatile;
|
||||||
@@ -39,6 +42,8 @@ public:
|
|||||||
|
|
||||||
void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback);
|
void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
friend class GPIOManager;
|
friend class GPIOManager;
|
||||||
@@ -60,7 +65,7 @@ private:
|
|||||||
|
|
||||||
#define GET_GPIO(key) GPIOManager::get(key)
|
#define GET_GPIO(key) GPIOManager::get(key)
|
||||||
|
|
||||||
#define GPIO_A
|
#define SET_ANALOGREAD_ADC(x) GPIOManager::setGPIOADC(x)
|
||||||
|
|
||||||
//Manages instances of SHAL_GPIO objects
|
//Manages instances of SHAL_GPIO objects
|
||||||
class GPIOManager{
|
class GPIOManager{
|
||||||
@@ -69,12 +74,17 @@ public:
|
|||||||
|
|
||||||
static SHAL_GPIO& get(GPIO_Key);
|
static SHAL_GPIO& get(GPIO_Key);
|
||||||
|
|
||||||
|
static SHAL_ADC getGPIOADC(){ return m_GPIO_ADC;}
|
||||||
|
|
||||||
|
static void setGPIOADC(SHAL_ADC adc){m_GPIO_ADC = adc;}
|
||||||
|
|
||||||
GPIOManager() = delete;
|
GPIOManager() = delete;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
inline static SHAL_GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}};
|
inline static SHAL_GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}};
|
||||||
|
|
||||||
|
inline static SHAL_ADC m_GPIO_ADC = SHAL_ADC(1);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#define SHAL_GPIO_TYPES_H
|
#define SHAL_GPIO_TYPES_H
|
||||||
|
|
||||||
#include "SHAL_CORE.h"
|
#include "SHAL_CORE.h"
|
||||||
|
#include "SHAL_ADC.h"
|
||||||
|
|
||||||
struct SHAL_EXTIO_Register{
|
struct SHAL_EXTIO_Register{
|
||||||
volatile uint32_t* EXT_ICR;
|
volatile uint32_t* EXT_ICR;
|
||||||
@@ -23,6 +24,11 @@ struct SHAL_Peripheral_Register {
|
|||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SHAL_GPIO_Port_Info{
|
||||||
|
uint8_t number;
|
||||||
|
ADC_Channel ADCChannel;
|
||||||
|
};
|
||||||
|
|
||||||
enum class PinMode : uint8_t{
|
enum class PinMode : uint8_t{
|
||||||
INPUT_MODE = 0x00,
|
INPUT_MODE = 0x00,
|
||||||
OUTPUT_MODE = 0x01,
|
OUTPUT_MODE = 0x01,
|
||||||
@@ -67,5 +73,4 @@ enum class TriggerMode : uint8_t{
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif //SHMINGO_HAL_SHAL_GPIO_TYPES_H
|
#endif //SHMINGO_HAL_SHAL_GPIO_TYPES_H
|
||||||
@@ -27,6 +27,8 @@ public:
|
|||||||
/// \param readLen number of bytes to be read
|
/// \param readLen number of bytes to be read
|
||||||
void masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t writeLen, uint8_t* readData, size_t readLen);
|
void masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t writeLen, uint8_t* readData, size_t readLen);
|
||||||
|
|
||||||
|
uint8_t masterWriteReadByte(uint8_t addr, const uint8_t* writeData, size_t writeLen);
|
||||||
|
|
||||||
/// Function to write an array of commands to an I2C device
|
/// Function to write an array of commands to an I2C device
|
||||||
/// \param addr Address of slave device
|
/// \param addr Address of slave device
|
||||||
/// \param writeData Pointer to array of commands
|
/// \param writeData Pointer to array of commands
|
||||||
|
|||||||
@@ -12,5 +12,8 @@
|
|||||||
#include "SHAL_GPIO.h"
|
#include "SHAL_GPIO.h"
|
||||||
#include "SHAL_UART.h"
|
#include "SHAL_UART.h"
|
||||||
#include "SHAL_I2C.h"
|
#include "SHAL_I2C.h"
|
||||||
|
#include "SHAL_ADC.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,18 +10,29 @@ void SHAL_init(){
|
|||||||
|
|
||||||
|
|
||||||
void systick_init(){
|
void systick_init(){
|
||||||
SysTick->CTRL = 0; //disable first
|
SysTick->CTRL = 0; //Disable first
|
||||||
SysTick->LOAD = 0xFFFFFF; //max 24-bit
|
SysTick->LOAD = 0xFFFFFF; //Max 24-bit
|
||||||
SysTick->VAL = 0; //clear
|
SysTick->VAL = 0; //Clear
|
||||||
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
|
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_delay_us(uint32_t us){
|
|
||||||
uint32_t start = SysTick->VAL;
|
|
||||||
uint32_t ticks = us * (SystemCoreClock / 1000000U);
|
|
||||||
|
|
||||||
//handle wraparound with 24-bit mask
|
void SHAL_delay_us(uint32_t us){
|
||||||
while (((start - SysTick->VAL) & 0x00FFFFFF) < ticks) { }
|
uint32_t ticks = us * (SystemCoreClock / 1000000U);
|
||||||
|
uint32_t start = SysTick->VAL;
|
||||||
|
|
||||||
|
//Calculate target value (may wrap around)
|
||||||
|
uint32_t target = (start >= ticks) ? (start - ticks) : (start + 0x01000000 - ticks);
|
||||||
|
target &= 0x00FFFFFF;
|
||||||
|
|
||||||
|
//Wait until we reach the target
|
||||||
|
if (start >= ticks) {
|
||||||
|
//No wraparound case
|
||||||
|
while (SysTick->VAL > target) {}
|
||||||
|
} else {
|
||||||
|
while (SysTick->VAL <= start) {} //Wait for wraparound
|
||||||
|
while (SysTick->VAL > target) {} //Wait for target
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_delay_ms(uint32_t ms){
|
void SHAL_delay_ms(uint32_t ms){
|
||||||
|
|||||||
115
SHAL/Src/Peripheral/ADC/SHAL_ADC.cpp
Normal file
115
SHAL/Src/Peripheral/ADC/SHAL_ADC.cpp
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
//
|
||||||
|
// Created by Luca on 9/21/2025.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "SHAL_ADC.h"
|
||||||
|
|
||||||
|
//Can hard code registers on F0 because all F0 devices have only one ADC, and use only one clock
|
||||||
|
SHAL_Result SHAL_ADC::init() {
|
||||||
|
|
||||||
|
if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){
|
||||||
|
return SHAL_Result::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
|
||||||
|
|
||||||
|
|
||||||
|
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN; //Enable clock
|
||||||
|
RCC->CR2 |= RCC_CR2_HSI14ON; //Start peripheral oscillator
|
||||||
|
|
||||||
|
if(!SHAL_WAIT_FOR_CONDITION_US(((RCC->CR2 & RCC_CR2_HSI14RDY) != 0),50)){ //Wait for clock OKAY
|
||||||
|
return SHAL_Result::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((ADC_reg->ISR & ADC_ISR_ADRDY) != 0){ //Set ADRDY to 0
|
||||||
|
ADC_reg->ISR |= ADC_ISR_ADRDY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADC_reg->CR |= ADC_CR_ADEN; //Enable
|
||||||
|
|
||||||
|
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_ADRDY) != 0),50)){ //Wait for disable
|
||||||
|
return SHAL_Result::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(calibrate() != SHAL_Result::OKAY){ //Calibrate
|
||||||
|
return SHAL_Result::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SHAL_Result::OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAL_Result SHAL_ADC::calibrate() {
|
||||||
|
|
||||||
|
if(m_ADCKey == ADC_Key::INVALID || m_ADCKey == ADC_Key::NUM_ADC){
|
||||||
|
return SHAL_Result::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
|
||||||
|
|
||||||
|
if((ADC_reg->CR & ADC_CR_ADEN) != 0){ //Clear ADEN (enable)
|
||||||
|
ADC_reg->CR |= ADC_CR_ADDIS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->CR & ADC_CR_ADEN) == 0),50)){ //Wait for disable
|
||||||
|
return SHAL_Result::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ADC_reg->CFGR1 &= ~ADC_CFGR1_DMAEN; //Clear DMAEN
|
||||||
|
ADC_reg->CR |= ADC_CR_ADCAL; //Launch calibration by setting ADCAL
|
||||||
|
|
||||||
|
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->CR & ADC_CR_ADCAL) == 0),50)){ //Wait for calibration
|
||||||
|
return SHAL_Result::ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
return SHAL_Result::OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SHAL_ADC::singleConvertSingle(ADC_Channel channel, ADC_SampleTime time) {
|
||||||
|
|
||||||
|
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
|
||||||
|
|
||||||
|
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_TSEN; //Enable VREFINT and Temp sensor in global ADC struct
|
||||||
|
|
||||||
|
ADC_reg->CHSELR = static_cast<uint32_t>(channel); //Enable channel for conversion
|
||||||
|
ADC_reg->SMPR |= static_cast<uint32_t>(time); //Set sampling time
|
||||||
|
|
||||||
|
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_EOC) != 0),500)){ //Wait for conversion
|
||||||
|
return 0; //Failed
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t result = ADC_reg->DR;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHAL_ADC::multiConvertSingle(ADC_Channel* channels, const int numChannels, uint16_t* result, ADC_SampleTime time) {
|
||||||
|
ADC_TypeDef* ADC_reg = getADCRegister(m_ADCKey);
|
||||||
|
|
||||||
|
ADC->CCR |= ADC_CCR_VREFEN | ADC_CCR_TSEN; //Enable VREFINT and Temp sensor in global ADC struct
|
||||||
|
|
||||||
|
for(int i = 0; i < numChannels; i++){ //Enable all channels
|
||||||
|
ADC_reg->CHSELR = static_cast<uint32_t>(channels[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
ADC_reg->SMPR |= static_cast<uint32_t>(time); //Set sampling time
|
||||||
|
|
||||||
|
|
||||||
|
for(int i = 0; i < numChannels; i++){
|
||||||
|
if(!SHAL_WAIT_FOR_CONDITION_US(((ADC_reg->ISR & ADC_ISR_EOC) != 0),500)){ //Wait for conversion
|
||||||
|
continue; //Failed
|
||||||
|
}
|
||||||
|
|
||||||
|
result[i] = ADC_reg->DR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAL_ADC &ADCManager::get(ADC_Key key) {
|
||||||
|
return m_ADCs[static_cast<uint8_t>(key)];
|
||||||
|
}
|
||||||
|
|
||||||
|
SHAL_ADC& ADCManager::getByIndex(int index) {
|
||||||
|
|
||||||
|
if(index < static_cast<int>(ADC_Key::NUM_ADC)){
|
||||||
|
return m_ADCs[index];
|
||||||
|
}
|
||||||
|
return m_ADCs[0];
|
||||||
|
}
|
||||||
@@ -107,6 +107,13 @@ void SHAL_GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback)
|
|||||||
__enable_irq(); //Enable IRQ just in case
|
__enable_irq(); //Enable IRQ just in case
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t SHAL_GPIO::analogRead(ADC_SampleTime sampleTime) {
|
||||||
|
|
||||||
|
ADC_Channel channel = getGPIOPortInfo(m_GPIO_KEY).ADCChannel;
|
||||||
|
|
||||||
|
return GPIOManager::getGPIOADC().singleConvertSingle(channel,sampleTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SHAL_GPIO& GPIOManager::get(GPIO_Key key) {
|
SHAL_GPIO& GPIOManager::get(GPIO_Key key) {
|
||||||
|
|
||||||
|
|||||||
@@ -5,15 +5,21 @@
|
|||||||
#include "SHAL_I2C.h"
|
#include "SHAL_I2C.h"
|
||||||
#include "SHAL_GPIO.h"
|
#include "SHAL_GPIO.h"
|
||||||
|
|
||||||
|
#include "SHAL_UART.h"
|
||||||
|
|
||||||
void SHAL_I2C::init(I2C_Pair pair) volatile {
|
void SHAL_I2C::init(I2C_Pair pair) volatile {
|
||||||
m_I2CPair = pair;
|
m_I2CPair = pair;
|
||||||
|
|
||||||
SHAL_I2C_Pair I2CPair = getI2CPair(pair); //Get the UART_PAIR information to be initialized
|
SHAL_I2C_Pair I2CPair = getI2CPair(pair); //Get the I2C_PAIR information to be initialized
|
||||||
|
|
||||||
//Get the SHAL_GPIO pins for this SHAL_I2C setup
|
//Get the SHAL_GPIO pins for this SHAL_I2C setup
|
||||||
GPIO_Key SCL_Key = I2CPair.SCL_Key; //SCL pin
|
GPIO_Key SCL_Key = I2CPair.SCL_Key; //SCL pin
|
||||||
GPIO_Key SDA_Key = I2CPair.SDA_Key; //SDA pin
|
GPIO_Key SDA_Key = I2CPair.SDA_Key; //SDA pin
|
||||||
|
|
||||||
|
SHAL_I2C_Enable_Reg pairI2CEnable = getI2CEnableReg(pair); //Register and mask to enable the I2C peripheral
|
||||||
|
|
||||||
|
*pairI2CEnable.reg &= ~pairI2CEnable.mask; //Enable I2C peripheral clock
|
||||||
|
|
||||||
GET_GPIO(SCL_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); //Implicitly initializes and enables GPIO bus
|
GET_GPIO(SCL_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); //Implicitly initializes and enables GPIO bus
|
||||||
GET_GPIO(SDA_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE);
|
GET_GPIO(SDA_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE);
|
||||||
|
|
||||||
@@ -30,13 +36,12 @@ void SHAL_I2C::init(I2C_Pair pair) volatile {
|
|||||||
GET_GPIO(SCL_Key).setInternalResistor(InternalResistorType::PULLUP);
|
GET_GPIO(SCL_Key).setInternalResistor(InternalResistorType::PULLUP);
|
||||||
GET_GPIO(SDA_Key).setInternalResistor(InternalResistorType::PULLUP);
|
GET_GPIO(SDA_Key).setInternalResistor(InternalResistorType::PULLUP);
|
||||||
|
|
||||||
SHAL_I2C_Enable_Reg pairI2CEnable = getI2CEnableReg(pair); //Register and mask to enable the I2C peripheral
|
|
||||||
SHAL_I2C_Reset_Reg pairI2CReset = getI2CResetReg(pair);
|
SHAL_I2C_Reset_Reg pairI2CReset = getI2CResetReg(pair);
|
||||||
|
|
||||||
*pairI2CReset.reg |= pairI2CReset.mask; //Reset peripheral
|
|
||||||
*pairI2CEnable.reg |= pairI2CEnable.mask; //Enable I2C peripheral clock
|
*pairI2CEnable.reg |= pairI2CEnable.mask; //Enable I2C peripheral clock
|
||||||
|
|
||||||
I2CPair.I2CReg->CR1 |= I2C_CR1_PE; //Enable I2C peripheral
|
*pairI2CReset.reg |= pairI2CReset.mask; //Reset peripheral
|
||||||
|
*pairI2CReset.reg &= ~pairI2CReset.mask; //Reset peripheral
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_I2C::setClockConfig(uint8_t prescaler, uint8_t dataSetupTime, uint8_t dataHoldTime, uint8_t SCLHighPeriod, uint8_t SCLLowPeriod) {
|
void SHAL_I2C::setClockConfig(uint8_t prescaler, uint8_t dataSetupTime, uint8_t dataHoldTime, uint8_t SCLHighPeriod, uint8_t SCLLowPeriod) {
|
||||||
@@ -48,46 +53,68 @@ void SHAL_I2C::setClockConfig(uint8_t prescaler, uint8_t dataSetupTime, uint8_t
|
|||||||
*clockReg.reg |= (dataHoldTime << clockReg.dataHoldTime_offset);
|
*clockReg.reg |= (dataHoldTime << clockReg.dataHoldTime_offset);
|
||||||
*clockReg.reg |= (SCLHighPeriod << clockReg.SCLHighPeriod_offset);
|
*clockReg.reg |= (SCLHighPeriod << clockReg.SCLHighPeriod_offset);
|
||||||
*clockReg.reg |= (SCLLowPeriod << clockReg.SCLLowPeriod_offset);
|
*clockReg.reg |= (SCLLowPeriod << clockReg.SCLLowPeriod_offset);
|
||||||
|
|
||||||
|
getI2CPair(m_I2CPair).I2CReg->CR1 |= I2C_CR1_PE; //Enable I2C peripheral
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_I2C::setClockConfig(uint32_t configuration) {
|
void SHAL_I2C::setClockConfig(uint32_t configuration) {
|
||||||
*getI2CTimerReg(m_I2CPair).reg = configuration;
|
*getI2CTimerReg(m_I2CPair).reg = configuration;
|
||||||
|
|
||||||
|
getI2CPair(m_I2CPair).I2CReg->CR1 |= I2C_CR1_PE; //Enable I2C peripheral
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_I2C::masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t writeLen, uint8_t* readData, size_t readLen) {
|
void SHAL_I2C::masterWriteRead(uint8_t addr,const uint8_t* writeData, size_t writeLen, uint8_t* readData, size_t readLen) {
|
||||||
|
|
||||||
volatile I2C_TypeDef* I2CPeripheral = getI2CPair(m_I2CPair).I2CReg;
|
volatile I2C_TypeDef* I2CPeripheral = getI2CPair(m_I2CPair).I2CReg;
|
||||||
|
|
||||||
//Wait for I2C bus
|
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_BUSY) == 0, 100)){
|
||||||
while (I2CPeripheral->ISR & I2C_ISR_BUSY);
|
SHAL_UART2.sendString("I2C timed out waiting for not busy\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Write phase
|
//Write phase
|
||||||
if (writeLen > 0) {
|
if (writeLen > 0) {
|
||||||
//Configure: NBYTES = wlen, write mode, START
|
//Configure: NBYTES = wlen, write mode, START
|
||||||
I2CPeripheral->CR2 = (addr << 1) |
|
I2CPeripheral->CR2 = (addr << 1) | (writeLen << I2C_CR2_NBYTES_Pos) | I2C_CR2_START;
|
||||||
(writeLen << I2C_CR2_NBYTES_Pos) |
|
|
||||||
I2C_CR2_START;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < writeLen; i++) {
|
for (size_t i = 0; i < writeLen; i++) {
|
||||||
while (!(I2CPeripheral->ISR & I2C_ISR_TXIS)); // TX ready
|
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_TXIS) != 0, 100)){
|
||||||
|
SHAL_UART2.sendString("I2C timed out waiting for TX\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
I2CPeripheral->TXDR = writeData[i];
|
I2CPeripheral->TXDR = writeData[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
//Wait until transfer complete
|
//Wait until transfer complete
|
||||||
while (!(I2CPeripheral->ISR & I2C_ISR_TC));
|
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_TC) != 0, 100)){
|
||||||
|
SHAL_UART2.sendString("I2C timed out waiting for TC\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//Read phase
|
//Read phase
|
||||||
if (readLen > 0) {
|
if (readLen > 0) {
|
||||||
I2CPeripheral->CR2 = (addr << 1) |
|
|
||||||
|
SHAL_UART2.sendString("Read initiated\r\n");
|
||||||
|
|
||||||
|
I2CPeripheral->CR2 &= ~(I2C_CR2_NBYTES | I2C_CR2_SADD | I2C_CR2_RD_WRN);
|
||||||
|
I2CPeripheral->CR2 |= (addr << 1) |
|
||||||
I2C_CR2_RD_WRN |
|
I2C_CR2_RD_WRN |
|
||||||
(readLen << I2C_CR2_NBYTES_Pos) |
|
(readLen << I2C_CR2_NBYTES_Pos) |
|
||||||
I2C_CR2_START | I2C_CR2_AUTOEND;
|
I2C_CR2_START | I2C_CR2_AUTOEND;
|
||||||
|
|
||||||
for (size_t i = 0; i < readLen; i++) {
|
for (size_t i = 0; i < readLen; i++) {
|
||||||
while (!(I2CPeripheral->ISR & I2C_ISR_RXNE)); //RX ready
|
if(!SHAL_WAIT_FOR_CONDITION_MS((I2CPeripheral->ISR & I2C_ISR_RXNE) != 0 , 100)){
|
||||||
|
SHAL_UART2.sendString("I2C timed out waiting for RXNE\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SHAL_UART2.sendString("Read byte");
|
||||||
readData[i] = static_cast<uint8_t>(I2CPeripheral->RXDR);
|
readData[i] = static_cast<uint8_t>(I2CPeripheral->RXDR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
I2CPeripheral->CR2 |= I2C_CR2_STOP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHAL_I2C::masterWrite(uint8_t addr, const uint8_t *writeData, uint8_t writeLen) {
|
void SHAL_I2C::masterWrite(uint8_t addr, const uint8_t *writeData, uint8_t writeLen) {
|
||||||
@@ -98,6 +125,12 @@ void SHAL_I2C::masterRead(uint8_t addr, uint8_t *readBuffer, uint8_t bytesToRead
|
|||||||
masterWriteRead(addr,nullptr,0,readBuffer,bytesToRead);
|
masterWriteRead(addr,nullptr,0,readBuffer,bytesToRead);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t SHAL_I2C::masterWriteReadByte(uint8_t addr, const uint8_t *writeData, size_t writeLen) {
|
||||||
|
uint8_t val = 0;
|
||||||
|
masterWriteRead(addr, writeData, writeLen, &val, 1);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
SHAL_I2C& I2CManager::get(uint8_t I2CBus) {
|
SHAL_I2C& I2CManager::get(uint8_t I2CBus) {
|
||||||
|
|
||||||
if(I2CBus > NUM_I2C_BUSES - 1){
|
if(I2CBus > NUM_I2C_BUSES - 1){
|
||||||
|
|||||||
@@ -1,10 +1,44 @@
|
|||||||
#include "SHAL.h"
|
#include "SHAL.h"
|
||||||
#include "stm32f0xx.h"
|
#include "stm32f0xx.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
void c3Interrupt(){
|
void c3Interrupt(){
|
||||||
PIN(A5).toggle();
|
SHAL_UART2.sendString("Begin\r\n");
|
||||||
UART(2).sendString("New test");
|
|
||||||
|
uint8_t cmd[3] = {0xAC, 0x33, 0x00};
|
||||||
|
SHAL_I2C1.masterWrite(0x38, cmd, 3);
|
||||||
|
|
||||||
|
SHAL_delay_ms(100);
|
||||||
|
|
||||||
|
uint8_t dht_buf[7] = {0};
|
||||||
|
|
||||||
|
//Read 7 bytes (status + 5 data + CRC)
|
||||||
|
SHAL_I2C1.masterRead(0x38, dht_buf, 7);
|
||||||
|
|
||||||
|
//Parse humidity (20 bits)
|
||||||
|
uint32_t rawHumidity = ((uint32_t)dht_buf[1] << 12) |
|
||||||
|
((uint32_t)dht_buf[2] << 4) |
|
||||||
|
((uint32_t)dht_buf[3] >> 4);
|
||||||
|
|
||||||
|
uint32_t rawTemp = (((uint32_t)dht_buf[3] & 0x0F) << 16) |
|
||||||
|
((uint32_t)dht_buf[4] << 8) |
|
||||||
|
((uint32_t)dht_buf[5]);
|
||||||
|
|
||||||
|
// Use 64-bit intermediate to avoid overflow
|
||||||
|
uint32_t hum_hundredths = (uint32_t)(((uint64_t)rawHumidity * 10000ULL) >> 20);
|
||||||
|
int32_t temp_hundredths = (int32_t)((((uint64_t)rawTemp * 20000ULL) >> 20) - 5000);
|
||||||
|
|
||||||
|
char out[80];
|
||||||
|
sprintf(out, "rawH=0x%05lX rawT=0x%05lX\r\n",
|
||||||
|
(unsigned long)rawHumidity, (unsigned long)rawTemp);
|
||||||
|
SHAL_UART2.sendString(out);
|
||||||
|
|
||||||
|
// print as X.YY
|
||||||
|
sprintf(out, "Temp: %ld.%02ld C, Hum: %ld.%02ld %%\r\n",
|
||||||
|
(long)(temp_hundredths / 100), (long)(abs(temp_hundredths % 100)),
|
||||||
|
(long)(hum_hundredths / 100), (long)(hum_hundredths % 100));
|
||||||
|
SHAL_UART2.sendString(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tim2Handler(){
|
void tim2Handler(){
|
||||||
@@ -20,6 +54,7 @@ int main() {
|
|||||||
SHAL_UART2.begin(115200);
|
SHAL_UART2.begin(115200);
|
||||||
|
|
||||||
SHAL_I2C1.init(I2C_Pair::SCL1B6_SDA1B7);
|
SHAL_I2C1.init(I2C_Pair::SCL1B6_SDA1B7);
|
||||||
|
SHAL_I2C1.setClockConfig(0x2000090E);
|
||||||
|
|
||||||
//Use pin C3 to trigger a function on external interrupt
|
//Use pin C3 to trigger a function on external interrupt
|
||||||
PIN(C3).useAsExternalInterrupt(TriggerMode::RISING_EDGE,c3Interrupt);
|
PIN(C3).useAsExternalInterrupt(TriggerMode::RISING_EDGE,c3Interrupt);
|
||||||
@@ -31,11 +66,22 @@ int main() {
|
|||||||
PIN(A4).setPinMode(PinMode::OUTPUT_MODE);
|
PIN(A4).setPinMode(PinMode::OUTPUT_MODE);
|
||||||
PIN(A5).setPinMode(PinMode::OUTPUT_MODE);
|
PIN(A5).setPinMode(PinMode::OUTPUT_MODE);
|
||||||
|
|
||||||
|
SHAL_delay_ms(3000); //Wait 100 ms from datasheet
|
||||||
|
|
||||||
|
uint8_t cmd = 0x71;
|
||||||
|
uint8_t status = 0;
|
||||||
|
|
||||||
|
SHAL_I2C1.masterWriteRead(0x38, &cmd, 1, &status, 1);
|
||||||
|
|
||||||
|
char statusString[32];
|
||||||
|
sprintf(statusString, "Status = 0x%02X\r\n", status);
|
||||||
|
SHAL_UART2.sendString(statusString);
|
||||||
|
|
||||||
|
|
||||||
|
SHAL_delay_ms(10);
|
||||||
|
|
||||||
c3Interrupt();
|
c3Interrupt();
|
||||||
|
//End setup
|
||||||
SHAL_delay_ms(3000);
|
|
||||||
|
|
||||||
c3Interrupt(); //test
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
__WFI();
|
__WFI();
|
||||||
|
|||||||
Reference in New Issue
Block a user