mirror of
https://github.com/Ralim/IronOS.git
synced 2025-02-26 07:53:55 +00:00
TS101 (#1695)
* Refactor I2C_SOFT to new #define * Stitch in some of TS101 Update ShowStartupWarnings.cpp Update OLED.hpp Update stm32f1xx_hal_msp.c Update Setup.cpp Update Power.cpp Update Pins.h Update configuration.h Power Muxing Working dual input Voltage handler Scan mode required for differing injected channels Inject both dc readings Update configuration.h Update configuration.h Use htim4 for adc control on TS101 Refactor htim names Add ADC_TRIGGER Speed up BB I2C a lil Update configuration.h Update startup_stm32f103t8ux.S Update configuration.h Add LIS2DH clone LIS2DH gains another clone Create tooling to allow mapping accelerometers onto different buses Update startup_stm32f103t8ux.S Ensure PD IRQ is pulled up * Stitch in some of TS101 Update ShowStartupWarnings.cpp Update OLED.hpp Update stm32f1xx_hal_msp.c Update Setup.cpp Update Power.cpp Update Pins.h Update configuration.h Power Muxing Working dual input Voltage handler Scan mode required for differing injected channels Inject both dc readings Update configuration.h Update configuration.h Use htim4 for adc control on TS101 Refactor htim names Add ADC_TRIGGER Speed up BB I2C a lil Update configuration.h Update startup_stm32f103t8ux.S Update configuration.h Add LIS2DH clone LIS2DH gains another clone Create tooling to allow mapping accelerometers onto different buses Update startup_stm32f103t8ux.S Ensure PD IRQ is pulled up Allow toggle which button enters PD debug * Update Pins.h * Fix hard coded IRQ Pin Update stm32f1xx_it.c * Enable EPR * Tip resistance measurement * TS101 is a direct drive tip Update BSP.cpp * Add S60 and TS101 to builds Update push.yml * Update MOVThread.cpp * Refactor power menu handler * Correct prescaler Forgot to update since I changed the period * Tune in the timer divider for tip control to make PWM less audible --------- Co-authored-by: discip <53649486+discip@users.noreply.github.com>
This commit is contained in:
@@ -93,7 +93,7 @@ const uint8_t WarningBlock24[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x30, 0x0C, 0x02, 0xF1, 0xF1, 0xF1, 0x02, 0x0C, 0x30, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xC0, 0xB0, 0x8C, 0x83, 0x80, 0x80, 0x80, 0x80, 0xB3, 0xB3, 0xB3, 0x80, 0x80, 0x80, 0x80, 0x83, 0x8C, 0xB0, 0xC0, 0x00, 0x00};
|
||||
|
||||
#if defined(MODEL_TS100) + defined(MODEL_Pinecil) + defined(MODEL_Pinecilv2) > 0
|
||||
#if defined(MODEL_TS100) + defined(MODEL_Pinecil) + defined(MODEL_Pinecilv2) +defined(MODEL_TS101) > 0
|
||||
const uint8_t buttonA[] = {
|
||||
// width = 42
|
||||
// height = 16
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
#include "HUB238.hpp"
|
||||
#include "I2CBB.hpp"
|
||||
#include "I2CBB2.hpp"
|
||||
#include "Utils.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#if POW_PD_EXT == 1
|
||||
bool hub238_probe() { return I2CBB::probe(HUB238_ADDR); }
|
||||
bool hub238_probe() { return I2CBB2::probe(HUB238_ADDR); }
|
||||
|
||||
extern int32_t powerSupplyWattageLimit;
|
||||
|
||||
uint16_t hub238_debug_state() {
|
||||
uint8_t status0 = 0;
|
||||
uint8_t status1 = 0;
|
||||
if (!I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &status0, 1)) {
|
||||
if (!I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &status0, 1)) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
if (!I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS1, &status1, 1)) {
|
||||
if (!I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS1, &status1, 1)) {
|
||||
return 0xFFFF;
|
||||
}
|
||||
return status1 | (((uint16_t)status0) << 8);
|
||||
@@ -81,7 +81,7 @@ uint16_t hub238_getVoltagePDOCurrent(uint8_t voltage) {
|
||||
return 0;
|
||||
}
|
||||
uint8_t temp = 0;
|
||||
if (I2CBB::Mem_Read(HUB238_ADDR, reg, &temp, 1) == true) {
|
||||
if (I2CBB2::Mem_Read(HUB238_ADDR, reg, &temp, 1) == true) {
|
||||
if (temp & HUB238_PDO_DETECTED) {
|
||||
return pdo_slot_to_currentx100(temp);
|
||||
}
|
||||
@@ -156,17 +156,17 @@ void hub238_check_negotiation() {
|
||||
|
||||
uint8_t bestPDO = findBestPDO();
|
||||
|
||||
if (I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_SRC_PDO, ¤tPDO, 1) == true) {
|
||||
if (I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_SRC_PDO, ¤tPDO, 1) == true) {
|
||||
currentPDO >>= 4; // grab upper bits
|
||||
if (currentPDO == bestPDO) {
|
||||
haveSelected = bestPDO;
|
||||
return;
|
||||
}
|
||||
currentPDO = bestPDO << 4;
|
||||
if (I2CBB::Mem_Write(HUB238_ADDR, HUB238_REG_SRC_PDO, ¤tPDO, 1) == true) {
|
||||
if (I2CBB2::Mem_Write(HUB238_ADDR, HUB238_REG_SRC_PDO, ¤tPDO, 1) == true) {
|
||||
|
||||
currentPDO = 0x01; // request for new PDO
|
||||
if (I2CBB::Mem_Write(HUB238_ADDR, HUB238_REG_GO_COMMAND, ¤tPDO, 1) == true) {
|
||||
if (I2CBB2::Mem_Write(HUB238_ADDR, HUB238_REG_GO_COMMAND, ¤tPDO, 1) == true) {
|
||||
haveSelected = bestPDO;
|
||||
vTaskDelay(50);
|
||||
|
||||
@@ -179,7 +179,7 @@ bool hub238_has_run_selection() { return haveSelected != 0xFF; }
|
||||
|
||||
bool hub238_has_negotiated() {
|
||||
uint8_t temp = 0;
|
||||
if (I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS1, &temp, 1) == true) {
|
||||
if (I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS1, &temp, 1) == true) {
|
||||
temp >>= 3;
|
||||
return (temp & 0b111) == 0b001; // success
|
||||
}
|
||||
@@ -189,7 +189,7 @@ bool hub238_has_negotiated() {
|
||||
// Return selected source voltage in V
|
||||
uint16_t hub238_source_voltage() {
|
||||
uint8_t temp = 0;
|
||||
if (I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &temp, 1) == true) {
|
||||
if (I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &temp, 1) == true) {
|
||||
temp >>= 4;
|
||||
switch (temp) {
|
||||
case 0b0001:
|
||||
@@ -211,7 +211,7 @@ uint16_t hub238_source_voltage() {
|
||||
// Return selected source current in Amps * 100
|
||||
uint8_t hub238_source_currentX100() {
|
||||
uint8_t temp = 0;
|
||||
if (I2CBB::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &temp, 1) == true) {
|
||||
if (I2CBB2::Mem_Read(HUB238_ADDR, HUB238_REG_PD_STATUS0, &temp, 1) == true) {
|
||||
temp &= 0b1111;
|
||||
return pdo_slot_to_currentx100(temp);
|
||||
}
|
||||
|
||||
317
source/Core/Drivers/I2CBB1.cpp
Normal file
317
source/Core/Drivers/I2CBB1.cpp
Normal file
@@ -0,0 +1,317 @@
|
||||
/*
|
||||
* I2CBB1.cpp
|
||||
*
|
||||
* Created on: 12 Jun 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
#include "configuration.h"
|
||||
#ifdef I2C_SOFT_BUS_1
|
||||
#include "FreeRTOS.h"
|
||||
#include <I2CBB1.hpp>
|
||||
SemaphoreHandle_t I2CBB1::I2CSemaphore = NULL;
|
||||
StaticSemaphore_t I2CBB1::xSemaphoreBuffer;
|
||||
void I2CBB1::init() {
|
||||
// Set GPIO's to output open drain
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_InitStruct.Pin = SDA_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(SDA_GPIO_Port, &GPIO_InitStruct);
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
|
||||
GPIO_InitStruct.Pin = SCL_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(SCL_GPIO_Port, &GPIO_InitStruct);
|
||||
SOFT_SDA1_HIGH();
|
||||
SOFT_SCL1_HIGH();
|
||||
// To ensure bus is unlocked; we toggle the Clock a bunch of times to make things error out
|
||||
for (int i = 0; i < 128; i++) {
|
||||
SOFT_SCL1_LOW();
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
SOFT_SCL1_HIGH();
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
}
|
||||
I2CSemaphore = xSemaphoreCreateMutexStatic(&xSemaphoreBuffer);
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool I2CBB1::probe(uint8_t address) {
|
||||
if (!lock())
|
||||
return false;
|
||||
start();
|
||||
bool ack = send(address);
|
||||
stop();
|
||||
unlock();
|
||||
return ack;
|
||||
}
|
||||
|
||||
bool I2CBB1::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return false;
|
||||
start();
|
||||
bool ack = send(DevAddress);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
ack = send(MemAddress);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
SOFT_SCL1_LOW();
|
||||
SOFT_I2C_DELAY();
|
||||
// stop();
|
||||
start();
|
||||
ack = send(DevAddress | 1);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
while (Size) {
|
||||
pData[0] = read(Size > 1);
|
||||
pData++;
|
||||
Size--;
|
||||
}
|
||||
stop();
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool I2CBB1::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return false;
|
||||
start();
|
||||
bool ack = send(DevAddress);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
ack = send(MemAddress);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
while (Size) {
|
||||
resetWatchdog();
|
||||
ack = send(pData[0]);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
pData++;
|
||||
Size--;
|
||||
}
|
||||
stop();
|
||||
unlock();
|
||||
return true;
|
||||
}
|
||||
|
||||
void I2CBB1::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return;
|
||||
start();
|
||||
bool ack = send(DevAddress);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
while (Size) {
|
||||
ack = send(pData[0]);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
pData++;
|
||||
Size--;
|
||||
}
|
||||
stop();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2CBB1::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return;
|
||||
start();
|
||||
bool ack = send(DevAddress | 1);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
while (Size) {
|
||||
pData[0] = read(Size > 1);
|
||||
pData++;
|
||||
Size--;
|
||||
}
|
||||
stop();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2CBB1::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
|
||||
if (Size_tx == 0 && Size_rx == 0)
|
||||
return;
|
||||
if (lock() == false)
|
||||
return;
|
||||
if (Size_tx) {
|
||||
start();
|
||||
bool ack = send(DevAddress);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
while (Size_tx) {
|
||||
ack = send(pData_tx[0]);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
pData_tx++;
|
||||
Size_tx--;
|
||||
}
|
||||
}
|
||||
if (Size_rx) {
|
||||
start();
|
||||
bool ack = send(DevAddress | 1);
|
||||
if (!ack) {
|
||||
stop();
|
||||
unlock();
|
||||
return;
|
||||
}
|
||||
while (Size_rx) {
|
||||
pData_rx[0] = read(Size_rx > 1);
|
||||
pData_rx++;
|
||||
Size_rx--;
|
||||
}
|
||||
}
|
||||
stop();
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2CBB1::start() {
|
||||
/* I2C Start condition, data line goes low when clock is high */
|
||||
SOFT_SCL1_HIGH();
|
||||
SOFT_SDA1_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SDA1_LOW();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL1_LOW();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SDA1_HIGH();
|
||||
}
|
||||
|
||||
void I2CBB1::stop() {
|
||||
/* I2C Stop condition, clock goes high when data is low */
|
||||
SOFT_SDA1_LOW();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL1_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SDA1_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
}
|
||||
|
||||
bool I2CBB1::send(uint8_t value) {
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
write_bit(value & 0x80); // write the most-significant bit
|
||||
value <<= 1;
|
||||
}
|
||||
|
||||
SOFT_SDA1_HIGH();
|
||||
bool ack = (read_bit() == 0);
|
||||
return ack;
|
||||
}
|
||||
|
||||
uint8_t I2CBB1::read(bool ack) {
|
||||
uint8_t B = 0;
|
||||
|
||||
uint8_t i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
B <<= 1;
|
||||
B |= read_bit();
|
||||
}
|
||||
|
||||
SOFT_SDA1_HIGH();
|
||||
if (ack)
|
||||
write_bit(0);
|
||||
else
|
||||
write_bit(1);
|
||||
return B;
|
||||
}
|
||||
|
||||
uint8_t I2CBB1::read_bit() {
|
||||
uint8_t b;
|
||||
|
||||
SOFT_SDA1_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL1_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
|
||||
if (SOFT_SDA1_READ())
|
||||
b = 1;
|
||||
else
|
||||
b = 0;
|
||||
|
||||
SOFT_SCL1_LOW();
|
||||
return b;
|
||||
}
|
||||
|
||||
void I2CBB1::unlock() { xSemaphoreGive(I2CSemaphore); }
|
||||
|
||||
bool I2CBB1::lock() {
|
||||
if (I2CSemaphore == NULL) {}
|
||||
bool a = xSemaphoreTake(I2CSemaphore, (TickType_t)100) == pdTRUE;
|
||||
return a;
|
||||
}
|
||||
|
||||
bool I2CBB1::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); }
|
||||
|
||||
uint8_t I2CBB1::I2C_RegisterRead(uint8_t address, uint8_t reg) {
|
||||
uint8_t temp = 0;
|
||||
Mem_Read(address, reg, &temp, 1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void I2CBB1::write_bit(uint8_t val) {
|
||||
if (val) {
|
||||
SOFT_SDA1_HIGH();
|
||||
} else {
|
||||
SOFT_SDA1_LOW();
|
||||
}
|
||||
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL1_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL1_LOW();
|
||||
}
|
||||
|
||||
bool I2CBB1::writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength) {
|
||||
for (int index = 0; index < registersLength; index++) {
|
||||
if (!I2C_RegisterWrite(address, registers[index].reg, registers[index].val)) {
|
||||
return false;
|
||||
}
|
||||
if (registers[index].pause_ms)
|
||||
delay_ms(registers[index].pause_ms);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@@ -1,14 +1,14 @@
|
||||
/*
|
||||
* I2CBB.hpp
|
||||
* I2CBB1.hpp
|
||||
*
|
||||
* Created on: 12 Jun 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#ifndef BSP_MINIWARE_I2CBB_HPP_
|
||||
#define BSP_MINIWARE_I2CBB_HPP_
|
||||
#ifndef BSP_MINIWARE_I2CBB1_HPP_
|
||||
#define BSP_MINIWARE_I2CBB1_HPP_
|
||||
#include "configuration.h"
|
||||
#ifdef I2C_SOFT
|
||||
#ifdef I2C_SOFT_BUS_1
|
||||
#include "BSP.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "Pins.h"
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "Software_I2C.h"
|
||||
#include "semphr.h"
|
||||
|
||||
class I2CBB {
|
||||
class I2CBB1 {
|
||||
public:
|
||||
static void init();
|
||||
// Probe if device ACK's address or not
|
||||
@@ -1,16 +1,16 @@
|
||||
/*
|
||||
* I2CBB.cpp
|
||||
* I2CBB2.cpp
|
||||
*
|
||||
* Created on: 12 Jun 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
#include "configuration.h"
|
||||
#ifdef I2C_SOFT
|
||||
#ifdef I2C_SOFT_BUS_2
|
||||
#include "FreeRTOS.h"
|
||||
#include <I2CBB.hpp>
|
||||
SemaphoreHandle_t I2CBB::I2CSemaphore = NULL;
|
||||
StaticSemaphore_t I2CBB::xSemaphoreBuffer;
|
||||
void I2CBB::init() {
|
||||
#include <I2CBB2.hpp>
|
||||
SemaphoreHandle_t I2CBB2::I2CSemaphore = NULL;
|
||||
StaticSemaphore_t I2CBB2::xSemaphoreBuffer;
|
||||
void I2CBB2::init() {
|
||||
// Set GPIO's to output open drain
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
@@ -24,16 +24,16 @@ void I2CBB::init() {
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
HAL_GPIO_Init(SCL2_GPIO_Port, &GPIO_InitStruct);
|
||||
SOFT_SDA_HIGH();
|
||||
SOFT_SCL_HIGH();
|
||||
SOFT_SDA2_HIGH();
|
||||
SOFT_SCL2_HIGH();
|
||||
// To ensure bus is unlocked; we toggle the Clock a bunch of times to make things error out
|
||||
for (int i = 0; i < 128; i++) {
|
||||
SOFT_SCL_LOW();
|
||||
SOFT_SCL2_LOW();
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
SOFT_SCL_HIGH();
|
||||
SOFT_SCL2_HIGH();
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
asm("nop");
|
||||
@@ -43,7 +43,7 @@ void I2CBB::init() {
|
||||
unlock();
|
||||
}
|
||||
|
||||
bool I2CBB::probe(uint8_t address) {
|
||||
bool I2CBB2::probe(uint8_t address) {
|
||||
if (!lock())
|
||||
return false;
|
||||
start();
|
||||
@@ -53,7 +53,7 @@ bool I2CBB::probe(uint8_t address) {
|
||||
return ack;
|
||||
}
|
||||
|
||||
bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) {
|
||||
bool I2CBB2::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return false;
|
||||
start();
|
||||
@@ -69,7 +69,7 @@ bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, u
|
||||
unlock();
|
||||
return false;
|
||||
}
|
||||
SOFT_SCL_LOW();
|
||||
SOFT_SCL2_LOW();
|
||||
SOFT_I2C_DELAY();
|
||||
// stop();
|
||||
start();
|
||||
@@ -89,7 +89,7 @@ bool I2CBB::Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, u
|
||||
return true;
|
||||
}
|
||||
|
||||
bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size) {
|
||||
bool I2CBB2::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return false;
|
||||
start();
|
||||
@@ -121,7 +121,7 @@ bool I2CBB::Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *p
|
||||
return true;
|
||||
}
|
||||
|
||||
void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
void I2CBB2::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return;
|
||||
start();
|
||||
@@ -145,7 +145,7 @@ void I2CBB::Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
void I2CBB2::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
if (!lock())
|
||||
return;
|
||||
start();
|
||||
@@ -164,7 +164,7 @@ void I2CBB::Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size) {
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
|
||||
void I2CBB2::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx) {
|
||||
if (Size_tx == 0 && Size_rx == 0)
|
||||
return;
|
||||
if (lock() == false)
|
||||
@@ -206,41 +206,41 @@ void I2CBB::TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Siz
|
||||
unlock();
|
||||
}
|
||||
|
||||
void I2CBB::start() {
|
||||
void I2CBB2::start() {
|
||||
/* I2C Start condition, data line goes low when clock is high */
|
||||
SOFT_SCL_HIGH();
|
||||
SOFT_SDA_HIGH();
|
||||
SOFT_SCL2_HIGH();
|
||||
SOFT_SDA2_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SDA_LOW();
|
||||
SOFT_SDA2_LOW();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL_LOW();
|
||||
SOFT_SCL2_LOW();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SDA_HIGH();
|
||||
SOFT_SDA2_HIGH();
|
||||
}
|
||||
|
||||
void I2CBB::stop() {
|
||||
void I2CBB2::stop() {
|
||||
/* I2C Stop condition, clock goes high when data is low */
|
||||
SOFT_SDA_LOW();
|
||||
SOFT_SDA2_LOW();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL_HIGH();
|
||||
SOFT_SCL2_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SDA_HIGH();
|
||||
SOFT_SDA2_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
}
|
||||
|
||||
bool I2CBB::send(uint8_t value) {
|
||||
bool I2CBB2::send(uint8_t value) {
|
||||
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
write_bit(value & 0x80); // write the most-significant bit
|
||||
value <<= 1;
|
||||
}
|
||||
|
||||
SOFT_SDA_HIGH();
|
||||
SOFT_SDA2_HIGH();
|
||||
bool ack = (read_bit() == 0);
|
||||
return ack;
|
||||
}
|
||||
|
||||
uint8_t I2CBB::read(bool ack) {
|
||||
uint8_t I2CBB2::read(bool ack) {
|
||||
uint8_t B = 0;
|
||||
|
||||
uint8_t i;
|
||||
@@ -249,7 +249,7 @@ uint8_t I2CBB::read(bool ack) {
|
||||
B |= read_bit();
|
||||
}
|
||||
|
||||
SOFT_SDA_HIGH();
|
||||
SOFT_SDA2_HIGH();
|
||||
if (ack)
|
||||
write_bit(0);
|
||||
else
|
||||
@@ -257,53 +257,53 @@ uint8_t I2CBB::read(bool ack) {
|
||||
return B;
|
||||
}
|
||||
|
||||
uint8_t I2CBB::read_bit() {
|
||||
uint8_t I2CBB2::read_bit() {
|
||||
uint8_t b;
|
||||
|
||||
SOFT_SDA_HIGH();
|
||||
SOFT_SDA2_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL_HIGH();
|
||||
SOFT_SCL2_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
|
||||
if (SOFT_SDA_READ())
|
||||
if (SOFT_SDA2_READ())
|
||||
b = 1;
|
||||
else
|
||||
b = 0;
|
||||
|
||||
SOFT_SCL_LOW();
|
||||
SOFT_SCL2_LOW();
|
||||
return b;
|
||||
}
|
||||
|
||||
void I2CBB::unlock() { xSemaphoreGive(I2CSemaphore); }
|
||||
void I2CBB2::unlock() { xSemaphoreGive(I2CSemaphore); }
|
||||
|
||||
bool I2CBB::lock() {
|
||||
bool I2CBB2::lock() {
|
||||
if (I2CSemaphore == NULL) {}
|
||||
bool a = xSemaphoreTake(I2CSemaphore, (TickType_t)100) == pdTRUE;
|
||||
return a;
|
||||
}
|
||||
|
||||
bool I2CBB::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); }
|
||||
bool I2CBB2::I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data) { return Mem_Write(address, reg, &data, 1); }
|
||||
|
||||
uint8_t I2CBB::I2C_RegisterRead(uint8_t address, uint8_t reg) {
|
||||
uint8_t I2CBB2::I2C_RegisterRead(uint8_t address, uint8_t reg) {
|
||||
uint8_t temp = 0;
|
||||
Mem_Read(address, reg, &temp, 1);
|
||||
return temp;
|
||||
}
|
||||
|
||||
void I2CBB::write_bit(uint8_t val) {
|
||||
void I2CBB2::write_bit(uint8_t val) {
|
||||
if (val) {
|
||||
SOFT_SDA_HIGH();
|
||||
SOFT_SDA2_HIGH();
|
||||
} else {
|
||||
SOFT_SDA_LOW();
|
||||
SOFT_SDA2_LOW();
|
||||
}
|
||||
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL_HIGH();
|
||||
SOFT_SCL2_HIGH();
|
||||
SOFT_I2C_DELAY();
|
||||
SOFT_SCL_LOW();
|
||||
SOFT_SCL2_LOW();
|
||||
}
|
||||
|
||||
bool I2CBB::writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength) {
|
||||
bool I2CBB2::writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength) {
|
||||
for (int index = 0; index < registersLength; index++) {
|
||||
if (!I2C_RegisterWrite(address, registers[index].reg, registers[index].val)) {
|
||||
return false;
|
||||
53
source/Core/Drivers/I2CBB2.hpp
Normal file
53
source/Core/Drivers/I2CBB2.hpp
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* I2CBB2.hpp
|
||||
*
|
||||
* Created on: 12 Jun 2020
|
||||
* Author: Ralim
|
||||
*/
|
||||
|
||||
#ifndef BSP_MINIWARE_I2CBB2_HPP_
|
||||
#define BSP_MINIWARE_I2CBB2_HPP_
|
||||
#include "configuration.h"
|
||||
#ifdef I2C_SOFT_BUS_2
|
||||
#include "BSP.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "Pins.h"
|
||||
#include "Setup.h"
|
||||
#include "Software_I2C.h"
|
||||
#include "semphr.h"
|
||||
|
||||
class I2CBB2 {
|
||||
public:
|
||||
static void init();
|
||||
// Probe if device ACK's address or not
|
||||
static bool probe(uint8_t address);
|
||||
// Issues a complete 8bit register read
|
||||
static bool Mem_Read(uint16_t DevAddress, uint16_t MemAddress, uint8_t *pData, uint16_t Size);
|
||||
// Implements a register write
|
||||
static bool Mem_Write(uint16_t DevAddress, uint16_t MemAddress, const uint8_t *pData, uint16_t Size);
|
||||
static void Transmit(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
|
||||
static void Receive(uint16_t DevAddress, uint8_t *pData, uint16_t Size);
|
||||
static void TransmitReceive(uint16_t DevAddress, uint8_t *pData_tx, uint16_t Size_tx, uint8_t *pData_rx, uint16_t Size_rx);
|
||||
static bool I2C_RegisterWrite(uint8_t address, uint8_t reg, uint8_t data);
|
||||
static uint8_t I2C_RegisterRead(uint8_t address, uint8_t reg);
|
||||
typedef struct {
|
||||
const uint8_t reg; // The register to write to
|
||||
uint8_t val; // The value to write to this register
|
||||
const uint8_t pause_ms; // How many ms to pause _after_ writing this reg
|
||||
} I2C_REG;
|
||||
static bool writeRegistersBulk(const uint8_t address, const I2C_REG *registers, const uint8_t registersLength);
|
||||
|
||||
private:
|
||||
static SemaphoreHandle_t I2CSemaphore;
|
||||
static StaticSemaphore_t xSemaphoreBuffer;
|
||||
static void unlock();
|
||||
static bool lock();
|
||||
static void start();
|
||||
static void stop();
|
||||
static bool send(uint8_t value);
|
||||
static uint8_t read(bool ack);
|
||||
static uint8_t read_bit();
|
||||
static void write_bit(uint8_t val);
|
||||
};
|
||||
#endif
|
||||
#endif /* BSP_MINIWARE_I2CBB_HPP_ */
|
||||
@@ -10,26 +10,26 @@
|
||||
#include "LIS2DH12.hpp"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
static const FRToSI2C::I2C_REG i2c_registers[] = {{LIS_CTRL_REG1, 0x17, 0}, // 25Hz
|
||||
{LIS_CTRL_REG2, 0b00001000, 0}, // Highpass filter off
|
||||
{LIS_CTRL_REG3, 0b01100000, 0}, // Setup interrupt pins
|
||||
{LIS_CTRL_REG4, 0b00001000, 0}, // Block update mode off, HR on
|
||||
{LIS_CTRL_REG5, 0b00000010, 0}, //
|
||||
{LIS_CTRL_REG6, 0b01100010, 0},
|
||||
// Basically setup the unit to run, and enable 4D orientation detection
|
||||
{LIS_INT2_CFG, 0b01111110, 0}, // setup for movement detection
|
||||
{LIS_INT2_THS, 0x28, 0}, //
|
||||
{LIS_INT2_DURATION, 64, 0}, //
|
||||
{LIS_INT1_CFG, 0b01111110, 0}, //
|
||||
{LIS_INT1_THS, 0x28, 0}, //
|
||||
{LIS_INT1_DURATION, 64, 0}};
|
||||
static const ACCEL_I2C_CLASS::I2C_REG i2c_registers[] = {{LIS_CTRL_REG1, 0x17, 0}, // 25Hz
|
||||
{LIS_CTRL_REG2, 0b00001000, 0}, // Highpass filter off
|
||||
{LIS_CTRL_REG3, 0b01100000, 0}, // Setup interrupt pins
|
||||
{LIS_CTRL_REG4, 0b00001000, 0}, // Block update mode off, HR on
|
||||
{LIS_CTRL_REG5, 0b00000010, 0}, //
|
||||
{LIS_CTRL_REG6, 0b01100010, 0},
|
||||
// Basically setup the unit to run, and enable 4D orientation detection
|
||||
{LIS_INT2_CFG, 0b01111110, 0}, // setup for movement detection
|
||||
{LIS_INT2_THS, 0x28, 0}, //
|
||||
{LIS_INT2_DURATION, 64, 0}, //
|
||||
{LIS_INT1_CFG, 0b01111110, 0}, //
|
||||
{LIS_INT1_THS, 0x28, 0}, //
|
||||
{LIS_INT1_DURATION, 64, 0}};
|
||||
|
||||
bool LIS2DH12::initalize() { return FRToSI2C::writeRegistersBulk(LIS2DH_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0])); }
|
||||
bool LIS2DH12::initalize() { return ACCEL_I2C_CLASS::writeRegistersBulk(LIS2DH_I2C_ADDRESS, i2c_registers, sizeof(i2c_registers) / sizeof(i2c_registers[0])); }
|
||||
|
||||
void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||
std::array<int16_t, 3> sensorData;
|
||||
|
||||
FRToSI2C::Mem_Read(LIS2DH_I2C_ADDRESS, 0xA8, reinterpret_cast<uint8_t *>(sensorData.begin()), sensorData.size() * sizeof(int16_t));
|
||||
ACCEL_I2C_CLASS::Mem_Read(LIS2DH_I2C_ADDRESS, 0xA8, reinterpret_cast<uint8_t *>(sensorData.begin()), sensorData.size() * sizeof(int16_t));
|
||||
|
||||
x = sensorData[0];
|
||||
y = sensorData[1];
|
||||
@@ -37,13 +37,21 @@ void LIS2DH12::getAxisReadings(int16_t &x, int16_t &y, int16_t &z) {
|
||||
}
|
||||
|
||||
bool LIS2DH12::detect() {
|
||||
if (!FRToSI2C::probe(LIS2DH_I2C_ADDRESS)) {
|
||||
if (!ACCEL_I2C_CLASS::probe(LIS2DH_I2C_ADDRESS)) {
|
||||
return false;
|
||||
}
|
||||
// Read chip id to ensure its not an address collision
|
||||
uint8_t id = 0;
|
||||
if (FRToSI2C::Mem_Read(LIS2DH_I2C_ADDRESS, LIS2DH_WHOAMI_REG, &id, 1)) {
|
||||
return id == LIS2DH_WHOAMI_ID;
|
||||
if (ACCEL_I2C_CLASS::Mem_Read(LIS2DH_I2C_ADDRESS, LIS2DH_WHOAMI_REG, &id, 1)) {
|
||||
return (id == LIS2DH_WHOAMI_ID) || (id == LIS2DH_CLONE_WHOAMI_ID);
|
||||
}
|
||||
return false; // cant read ID
|
||||
}
|
||||
|
||||
bool LIS2DH12::isClone() {
|
||||
uint8_t id = 0;
|
||||
if (ACCEL_I2C_CLASS::Mem_Read(LIS2DH_I2C_ADDRESS, LIS2DH_WHOAMI_REG, &id, 1)) {
|
||||
return (id == LIS2DH_CLONE_WHOAMI_ID);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -8,17 +8,19 @@
|
||||
#ifndef LIS2DH12_HPP_
|
||||
#define LIS2DH12_HPP_
|
||||
#include "BSP.h"
|
||||
#include "I2C_Wrapper.hpp"
|
||||
|
||||
#include "LIS2DH12_defines.hpp"
|
||||
#include "accelerometers_common.h"
|
||||
|
||||
class LIS2DH12 {
|
||||
public:
|
||||
static bool detect();
|
||||
static bool isClone();
|
||||
static bool initalize();
|
||||
// 1 = rh, 2,=lh, 8=flat
|
||||
static Orientation getOrientation() {
|
||||
#ifdef LIS_ORI_FLIP
|
||||
uint8_t val = (FRToSI2C::I2C_RegisterRead(LIS2DH_I2C_ADDRESS, LIS_INT2_SRC) >> 2);
|
||||
uint8_t val = (ACCEL_I2C_CLASS::I2C_RegisterRead(LIS2DH_I2C_ADDRESS, LIS_INT2_SRC) >> 2);
|
||||
if (val == 8)
|
||||
val = 3;
|
||||
else if (val == 1)
|
||||
@@ -29,7 +31,7 @@ public:
|
||||
val = 3;
|
||||
return static_cast<Orientation>(val);
|
||||
#else
|
||||
return static_cast<Orientation>((FRToSI2C::I2C_RegisterRead(LIS2DH_I2C_ADDRESS, LIS_INT2_SRC) >> 2) - 1);
|
||||
return static_cast<Orientation>((ACCEL_I2C_CLASS::I2C_RegisterRead(LIS2DH_I2C_ADDRESS, LIS_INT2_SRC) >> 2) - 1);
|
||||
#endif
|
||||
}
|
||||
static void getAxisReadings(int16_t &x, int16_t &y, int16_t &z);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define LIS2DH_I2C_ADDRESS (25 << 1)
|
||||
#define LIS2DH_WHOAMI_REG 0x0F
|
||||
#define LIS2DH_WHOAMI_ID (0b00110011)
|
||||
#define LIS2DH_CLONE_WHOAMI_ID 0x11
|
||||
#define LIS_CTRL_REG1 0x20 | 0x80
|
||||
#define LIS_CTRL_REG2 0x21 | 0x80
|
||||
#define LIS_CTRL_REG3 0x22 | 0x80
|
||||
|
||||
@@ -24,9 +24,12 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef OLED_I2CBB
|
||||
#include "I2CBB.hpp"
|
||||
#define I2C_CLASS I2CBB
|
||||
#if defined(OLED_I2CBB2)
|
||||
#include "I2CBB2.hpp"
|
||||
#define I2C_CLASS I2CBB2
|
||||
#elif defined(OLED_I2CBB1)
|
||||
#include "I2CBB1.hpp"
|
||||
#define I2C_CLASS I2CBB1
|
||||
#else
|
||||
#define I2C_CLASS FRToSI2C
|
||||
#include "I2C_Wrapper.hpp"
|
||||
@@ -44,7 +47,8 @@ extern "C" {
|
||||
|
||||
#define OLED_VCOM_LAYOUT 0x12
|
||||
#define OLED_SEGMENT_MAP_REVERSED
|
||||
#warning "S60 Not fully supported"
|
||||
|
||||
#warning "128x32 OLED's Not fully supported"
|
||||
#else
|
||||
#define OLED_WIDTH 96
|
||||
#define OLED_HEIGHT 16
|
||||
|
||||
15
source/Core/Drivers/accelerometers_common.h
Normal file
15
source/Core/Drivers/accelerometers_common.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef CORE_DRIVERS_ACCELEROMTERS_COMMON_H_
|
||||
#define CORE_DRIVERS_ACCELEROMTERS_COMMON_H_
|
||||
|
||||
#if defined(ACCEL_I2CBB2)
|
||||
#include "I2CBB2.hpp"
|
||||
#define ACCEL_I2C_CLASS I2CBB2
|
||||
#elif defined(ACCEL_I2CBB1)
|
||||
#include "I2CBB1.hpp"
|
||||
#define ACCEL_I2C_CLASS I2CBB1
|
||||
#else
|
||||
#include "I2C_Wrapper.hpp"
|
||||
#define ACCEL_I2C_CLASS FRToSI2C
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user