Added delay functions
This commit is contained in:
@@ -11,9 +11,24 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
//Overall init function for SHAL --------------------------
|
||||
|
||||
void SHAL_init();
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
//Universal structs and defines ---------------------------
|
||||
|
||||
//Currently configures systick to count down in microseconds
|
||||
void systick_init();
|
||||
|
||||
//Max of 16ms, use SHAL_delay_ms for longer delay
|
||||
void SHAL_delay_us(uint32_t us);
|
||||
|
||||
void SHAL_delay_ms(uint32_t ms);
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#ifndef SHMINGO_HAL_SHAL_I2C_H
|
||||
#define SHMINGO_HAL_SHAL_I2C_H
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "SHAL_CORE.h"
|
||||
#include "SHAL_I2C_REG.h"
|
||||
|
||||
@@ -17,16 +19,26 @@ public:
|
||||
|
||||
void init(I2C_Pair pair) volatile;
|
||||
|
||||
///
|
||||
/// \param addr I2C address of slave device
|
||||
/// \param reg Address of register in slave device to write to
|
||||
/// \param data Data to write to slave register
|
||||
void masterTransmit(uint8_t addr, uint8_t reg, uint8_t data);
|
||||
/// General I2C function to send commands to a device, then read back any returned data if necessary
|
||||
/// \param addr address of slave device
|
||||
/// \param writeData pointer to array of write commands
|
||||
/// \param writeLen number of write commands
|
||||
/// \param readData pointer to buffer to write received data to
|
||||
/// \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);
|
||||
|
||||
/// Function to write an array of commands to an I2C device
|
||||
/// \param addr Address of slave device
|
||||
/// \param writeData Pointer to array of commands
|
||||
/// \param writeLen Number of commands
|
||||
void masterWrite(uint8_t addr, const uint8_t* writeData, uint8_t writeLen);
|
||||
|
||||
/// Function to read bytes from an I2C device
|
||||
/// \param addr Address of slave device
|
||||
/// \param readBuffer Pointer to buffer where data will be placed
|
||||
/// \param bytesToRead Number of bytes to read
|
||||
void masterRead(uint8_t addr, uint8_t* readBuffer, uint8_t bytesToRead);
|
||||
|
||||
///
|
||||
/// \param addr I2C address of slave device
|
||||
/// \param reg Register to read data from
|
||||
uint8_t masterReceive(uint8_t addr, uint8_t reg);
|
||||
|
||||
//Manually set the clock configuration. Refer to your MCU's reference manual for examples
|
||||
void setClockConfig(uint8_t prescaler, uint8_t dataSetupTime, uint8_t dataHoldTime, uint8_t SCLHighPeriod, uint8_t SCLLowPeriod);
|
||||
|
||||
@@ -11,5 +11,6 @@
|
||||
#include "SHAL_TIM.h"
|
||||
#include "SHAL_GPIO.h"
|
||||
#include "SHAL_UART.h"
|
||||
#include "SHAL_I2C.h"
|
||||
|
||||
#endif
|
||||
|
||||
31
SHAL/Src/Core/SHAL_CORE.cpp
Normal file
31
SHAL/Src/Core/SHAL_CORE.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
//
|
||||
// Created by Luca on 9/15/2025.
|
||||
//
|
||||
|
||||
#include "SHAL_CORE.h"
|
||||
|
||||
void SHAL_init(){
|
||||
systick_init(); //Just this for now
|
||||
}
|
||||
|
||||
|
||||
void systick_init(){
|
||||
SysTick->CTRL = 0; //disable first
|
||||
SysTick->LOAD = 0xFFFFFF; //max 24-bit
|
||||
SysTick->VAL = 0; //clear
|
||||
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
|
||||
while (((start - SysTick->VAL) & 0x00FFFFFF) < ticks) { }
|
||||
}
|
||||
|
||||
void SHAL_delay_ms(uint32_t ms){
|
||||
while(ms-- > 0){
|
||||
SHAL_delay_us(1000);
|
||||
}
|
||||
}
|
||||
@@ -54,59 +54,48 @@ void SHAL_I2C::setClockConfig(uint32_t configuration) {
|
||||
*getI2CTimerReg(m_I2CPair).reg = configuration;
|
||||
}
|
||||
|
||||
void SHAL_I2C::masterTransmit(uint8_t addr, uint8_t reg, uint8_t data) {
|
||||
|
||||
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;
|
||||
|
||||
//Wait until not busy
|
||||
//Wait for I2C bus
|
||||
while (I2CPeripheral->ISR & I2C_ISR_BUSY);
|
||||
|
||||
//Send start + slave address
|
||||
I2CPeripheral->CR2 = (addr << 1) | (2 << I2C_CR2_NBYTES_Pos) | I2C_CR2_START | I2C_CR2_AUTOEND; //Pack bits in compliance with I2C format
|
||||
//Write phase
|
||||
if (writeLen > 0) {
|
||||
//Configure: NBYTES = wlen, write mode, START
|
||||
I2CPeripheral->CR2 = (addr << 1) |
|
||||
(writeLen << I2C_CR2_NBYTES_Pos) |
|
||||
I2C_CR2_START;
|
||||
|
||||
//Wait until TX ready
|
||||
while (!(I2CPeripheral->ISR & I2C_ISR_TXIS));
|
||||
for (size_t i = 0; i < writeLen; i++) {
|
||||
while (!(I2CPeripheral->ISR & I2C_ISR_TXIS)); // TX ready
|
||||
I2CPeripheral->TXDR = writeData[i];
|
||||
}
|
||||
|
||||
//Send register address
|
||||
I2CPeripheral->TXDR = reg;
|
||||
//Wait until transfer complete
|
||||
while (!(I2CPeripheral->ISR & I2C_ISR_TC));
|
||||
}
|
||||
|
||||
//Wait until TX ready
|
||||
while (!(I2CPeripheral->ISR & I2C_ISR_TXIS));
|
||||
//Read phase
|
||||
if (readLen > 0) {
|
||||
I2CPeripheral->CR2 = (addr << 1) |
|
||||
I2C_CR2_RD_WRN |
|
||||
(readLen << I2C_CR2_NBYTES_Pos) |
|
||||
I2C_CR2_START | I2C_CR2_AUTOEND;
|
||||
|
||||
//Send data to write to register
|
||||
I2CPeripheral->TXDR = data;
|
||||
for (size_t i = 0; i < readLen; i++) {
|
||||
while (!(I2CPeripheral->ISR & I2C_ISR_RXNE)); //RX ready
|
||||
readData[i] = static_cast<uint8_t>(I2CPeripheral->RXDR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SHAL_I2C::masterWrite(uint8_t addr, const uint8_t *writeData, uint8_t writeLen) {
|
||||
masterWriteRead(addr,writeData,writeLen,nullptr,0);
|
||||
}
|
||||
|
||||
uint8_t SHAL_I2C::masterReceive(uint8_t addr, uint8_t reg) {
|
||||
|
||||
volatile I2C_TypeDef* I2CPeripheral = getI2CPair(m_I2CPair).I2CReg;
|
||||
|
||||
//Send register address with write
|
||||
|
||||
//Wait for bus
|
||||
while (I2CPeripheral->ISR & I2C_ISR_BUSY);
|
||||
|
||||
//Send start with I2C config
|
||||
I2CPeripheral->CR2 = (addr << 1) | (1 << I2C_CR2_NBYTES_Pos) | I2C_CR2_START;
|
||||
|
||||
//Wait for transmit
|
||||
while (!(I2CPeripheral->ISR & I2C_ISR_TXIS));
|
||||
|
||||
//Set address to read from
|
||||
I2CPeripheral->TXDR = reg;
|
||||
|
||||
//Wait for transfer to complete
|
||||
while (!(I2CPeripheral->ISR & I2C_ISR_TC));
|
||||
|
||||
//Restart in read mode, auto end
|
||||
I2CPeripheral->CR2 = (addr << 1) | I2C_CR2_RD_WRN |
|
||||
(1 << I2C_CR2_NBYTES_Pos) |
|
||||
I2C_CR2_START | I2C_CR2_AUTOEND;
|
||||
|
||||
//Wait
|
||||
while (!(I2C1->ISR & I2C_ISR_RXNE));
|
||||
return (uint8_t)I2C1->RXDR;
|
||||
void SHAL_I2C::masterRead(uint8_t addr, uint8_t *readBuffer, uint8_t bytesToRead) {
|
||||
masterWriteRead(addr,nullptr,0,readBuffer,bytesToRead);
|
||||
}
|
||||
|
||||
SHAL_I2C& I2CManager::get(uint8_t I2CBus) {
|
||||
|
||||
@@ -13,10 +13,14 @@ void tim2Handler(){
|
||||
|
||||
int main() {
|
||||
|
||||
SHAL_init();
|
||||
|
||||
//Setup UART2 (used by nucleo devices for USB comms)
|
||||
SHAL_UART2.init(UART_Pair::Tx2A2_Rx2A3);
|
||||
SHAL_UART2.begin(115200);
|
||||
|
||||
SHAL_I2C1.init(I2C_Pair::SCL1B6_SDA1B7);
|
||||
|
||||
//Use pin C3 to trigger a function on external interrupt
|
||||
PIN(C3).useAsExternalInterrupt(TriggerMode::RISING_EDGE,c3Interrupt);
|
||||
|
||||
@@ -27,6 +31,12 @@ int main() {
|
||||
PIN(A4).setPinMode(PinMode::OUTPUT_MODE);
|
||||
PIN(A5).setPinMode(PinMode::OUTPUT_MODE);
|
||||
|
||||
c3Interrupt();
|
||||
|
||||
SHAL_delay_ms(3000);
|
||||
|
||||
c3Interrupt(); //test
|
||||
|
||||
while (true) {
|
||||
__WFI();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user