Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added changes #42

Merged
merged 1 commit into from
Mar 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ Copyright (C) 2023 Ole Lange
// Defining the module type, using the same schema as the hitpoint mcfg
#define MODULE_TYPE MODULE_PHASER

// Enable to shoot debug packages
// #define PHASER_DEBUG_SHOOTING

// Logging
#define LOG_SERIAL_SPEED 115200
// (Levels are 0->5 Debug, Info, Warn, Error, Fatal, Off)
Expand Down Expand Up @@ -102,6 +105,7 @@ Copyright (C) 2023 Ole Lange
#define UI_REFRESH_INTERVAL 15000

// Communication
#define HP_TIMESYNC_SEND_INTERVAL 10000
#define HW_STATUS_SEND_INTERVAL 15000

#define NO_HPNOW // Disable hpnow with this flag.. (requires much energy i
Expand Down
266 changes: 141 additions & 125 deletions src/inc/hitpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ void IRAM_ATTR hitpointISR() { isHitpointEventTriggered = true; }
* @return true if a event should be executed
*/
bool hitpointEventTriggered() {
// store a local copy
bool retVal = isHitpointEventTriggered;
// reset the event trigger
isHitpointEventTriggered = false;
// store a local copy
bool retVal = isHitpointEventTriggered;
// reset the event trigger
isHitpointEventTriggered = false;

return retVal;
return retVal;
}

/**
Expand All @@ -57,26 +57,26 @@ bool hitpointEventTriggered() {
* @return Raw shot data packet. If 0, the shot isn't valid.
*/
uint32_t hitpointReadShotRaw(uint8_t addr) {
// Request 4 Bytes from the hitpoint
uint8_t returned_bytes = Wire.requestFrom(addr, (uint8_t)4);

// Check if 4 Bytes are returned
if (returned_bytes != 4) {
// If not abort the operation without reading a shot
return 0;
}

// Variable to store the packet
uint32_t shot = 0x00000000;
while (Wire.available()) {
// Shift the current value of shot left by 8 bits and
// OR it with the next byte of data. This adds the
// next byte of data to the end of shot, preserving
// the existing data.
shot = (shot << 8) | (uint8_t)Wire.read();
}

return shot;
// Request 4 Bytes from the hitpoint
uint8_t returned_bytes = Wire.requestFrom(addr, (uint8_t)4);

// Check if 4 Bytes are returned
if (returned_bytes != 4) {
// If not abort the operation without reading a shot
return 0;
}

// Variable to store the packet
uint32_t shot = 0x00000000;
while (Wire.available()) {
// Shift the current value of shot left by 8 bits and
// OR it with the next byte of data. This adds the
// next byte of data to the end of shot, preserving
// the existing data.
shot = (shot << 8) | (uint8_t)Wire.read();
}

return shot;
}

/**
Expand All @@ -87,26 +87,26 @@ uint32_t hitpointReadShotRaw(uint8_t addr) {
* @return Raw shot data packet. If 0, no shot was received.
*/
uint32_t hitpointReadShotRaw(uint8_t *addr) {
// This function is typically called when one or more hitpoints triggered
// the hitpoint interrupt, to make sure that the data is ready when read
// this function will wait some time before starting to read the hitpoints
delay(50);

uint32_t retVal = 0;
uint32_t hpVal = 0;

// Read every hitpoint, but only write the first which isn't
// zero to the return value. This causes that the first shot
// is used but every hitpoint it reset
for (uint8_t i = 0; i < attachedHitpointsCount; i++) {
hpVal = hitpointReadShotRaw(attachedHitpoints[i]);
if (retVal == 0 && hpVal != 0) {
retVal = hpVal;
*addr = attachedHitpoints[i];
// This function is typically called when one or more hitpoints triggered
// the hitpoint interrupt, to make sure that the data is ready when read
// this function will wait some time before starting to read the hitpoints
delay(50);

uint32_t retVal = 0;
uint32_t hpVal = 0;

// Read every hitpoint, but only write the first which isn't
// zero to the return value. This causes that the first shot
// is used but every hitpoint it reset
for (uint8_t i = 0; i < attachedHitpointsCount; i++) {
hpVal = hitpointReadShotRaw(attachedHitpoints[i]);
if (retVal == 0 && hpVal != 0) {
retVal = hpVal;
*addr = attachedHitpoints[i];
}
}
}

return retVal;
return retVal;
}

/**
Expand Down Expand Up @@ -162,19 +162,19 @@ uint8_t *i2cWriteBuffer;
* @param addr Hitpoint Address
*/
void writeBuffer(uint8_t n, uint8_t addr) {
// Starts the transmission
Wire.beginTransmission(addr);
// Transfers the bytes
Wire.write(i2cWriteBuffer, n);
// Ends the transmission
Wire.endTransmission();

// And delays a short period of time.
// I don't really remeber why this was implemented
// in the old prototype code but I transfered it
// to this code to prevent any bugs. TODO: find out
// if it is really required!
delay(50);
// Starts the transmission
Wire.beginTransmission(addr);
// Transfers the bytes
Wire.write(i2cWriteBuffer, n);
// Ends the transmission
Wire.endTransmission();

// And delays a short period of time.
// I don't really remeber why this was implemented
// in the old prototype code but I transfered it
// to this code to prevent any bugs. TODO: find out
// if it is really required!
delay(50);
}

/**
Expand All @@ -185,17 +185,17 @@ void writeBuffer(uint8_t n, uint8_t addr) {
* @param animation The animation which the given hitpoint should run
*/
void hitpointSelectAnimation(uint8_t addr, uint8_t animation) {
// Set Command
i2cWriteBuffer[0] = HP_CMD_SELECT_ANIM;
// Set animation parameter
i2cWriteBuffer[1] = animation;
// Set end value
i2cWriteBuffer[2] = 0x00;
// Set Command
i2cWriteBuffer[0] = HP_CMD_SELECT_ANIM;
// Set animation parameter
i2cWriteBuffer[1] = animation;
// Set end value
i2cWriteBuffer[2] = 0x00;

// Write the data to the hitpoint
writeBuffer(3, addr);
// Write the data to the hitpoint
writeBuffer(3, addr);

logDebug("Set Hitpoint (0x%02x) animation: 0x%02x", addr, animation);
logDebug("Set Hitpoint (0x%02x) animation: 0x%02x", addr, animation);
}

/**
Expand All @@ -205,9 +205,7 @@ void hitpointSelectAnimation(uint8_t addr, uint8_t animation) {
* @param animation The animation which the given hitpoint should run
*/
void hitpointSelectAnimation(uint8_t animation) {
for (uint8_t i = 0; i < attachedHitpointsCount; i++) {
hitpointSelectAnimation(attachedHitpoints[i], animation);
}
hitpointSelectAnimation(0x00, animation);
}

/**
Expand All @@ -223,17 +221,17 @@ void hitpointSelectAnimation(uint8_t animation) {
* @param speed Speed to set for the animations
*/
void hitpointSetAnimationSpeed(uint8_t addr, uint8_t speed) {
// Set Command
i2cWriteBuffer[0] = HP_CMD_SET_ANIM_SPEED;
// Set speed parameter
i2cWriteBuffer[1] = speed;
// Set end value
i2cWriteBuffer[2] = 0;
// Set Command
i2cWriteBuffer[0] = HP_CMD_SET_ANIM_SPEED;
// Set speed parameter
i2cWriteBuffer[1] = speed;
// Set end value
i2cWriteBuffer[2] = 0;

// Write the data to the hitpoint
writeBuffer(3, addr);
// Write the data to the hitpoint
writeBuffer(3, addr);

logDebug("Set Hitpoint (0x%02x) animation speed to: %d", addr, speed);
logDebug("Set Hitpoint (0x%02x) animation speed to: %d", addr, speed);
}

/**
Expand All @@ -248,9 +246,7 @@ void hitpointSetAnimationSpeed(uint8_t addr, uint8_t speed) {
* @param speed Speed to set for the animations
*/
void hitpointSetAnimationSpeed(uint8_t speed) {
for (uint8_t i = 0; i < attachedHitpointsCount; i++) {
hitpointSetAnimationSpeed(attachedHitpoints[i], speed);
}
hitpointSetAnimationSpeed(0x00, speed);
}

/**
Expand All @@ -262,22 +258,22 @@ void hitpointSetAnimationSpeed(uint8_t speed) {
* @param b Blue color value (0-255)
*/
void hitpointSetColor(uint8_t addr, uint8_t r, uint8_t g, uint8_t b) {
// Set Command
i2cWriteBuffer[0] = HP_CMD_SET_COLOR;
// Set r, g, b parameter
uint8_t dim_r = r * LED_MAX_BRIGHTNESS;
uint8_t dim_g = g * LED_MAX_BRIGHTNESS;
uint8_t dim_b = b * LED_MAX_BRIGHTNESS;
i2cWriteBuffer[1] = gamma8[dim_r];
i2cWriteBuffer[2] = gamma8[dim_g];
i2cWriteBuffer[3] = gamma8[dim_b];
// Set end value
i2cWriteBuffer[4] = 0;

// Write the data to the hitpoint
writeBuffer(5, addr);

logDebug("Set Hitpoint (0x%02x) color to: #%02x%02x%02x", addr, r, g, b);
// Set Command
i2cWriteBuffer[0] = HP_CMD_SET_COLOR;
// Set r, g, b parameter
uint8_t dim_r = r * LED_MAX_BRIGHTNESS;
uint8_t dim_g = g * LED_MAX_BRIGHTNESS;
uint8_t dim_b = b * LED_MAX_BRIGHTNESS;
i2cWriteBuffer[1] = gamma8[dim_r];
i2cWriteBuffer[2] = gamma8[dim_g];
i2cWriteBuffer[3] = gamma8[dim_b];
// Set end value
i2cWriteBuffer[4] = 0;

// Write the data to the hitpoint
writeBuffer(5, addr);

logDebug("Set Hitpoint (0x%02x) color to: #%02x%02x%02x", addr, r, g, b);
}

/**
Expand All @@ -288,9 +284,28 @@ void hitpointSetColor(uint8_t addr, uint8_t r, uint8_t g, uint8_t b) {
* @param b Blue color value (0-255)
*/
void hitpointSetColor(uint8_t r, uint8_t g, uint8_t b) {
for (uint8_t i = 0; i < attachedHitpointsCount; i++) {
hitpointSetColor(attachedHitpoints[i], r, g, b);
}
hitpointSetColor(0x00, r, g, b);
}

/**
* Sends the current timestamp to I2C general call to
* sync the time
*/
void hitpointSyncTime() {
i2cWriteBuffer[0] = HP_CMD_TIMESYNC;

unsigned long now = millis();
i2cWriteBuffer[1] = (now >> 24) & 0xff;
i2cWriteBuffer[2] = (now >> 16) & 0xff;
i2cWriteBuffer[3] = (now >> 8) & 0xff;
i2cWriteBuffer[4] = now & 0xff;
i2cWriteBuffer[5] = 0;

writeBuffer(6, 0x00);

logDebug("Broadcasted timesync command to hitpoints (%02x %02x %02x %02x)",
i2cWriteBuffer[1], i2cWriteBuffer[2], i2cWriteBuffer[3],
i2cWriteBuffer[4]);
}

/**
Expand All @@ -301,31 +316,32 @@ void hitpointSetColor(uint8_t r, uint8_t g, uint8_t b) {
* ability to trigger an interrupt on the phaser.
*/
void hitpointInit() {
logInfo("Init: Hitpoint driver");

// Initing I2C Communication
Wire.begin(PIN_SDA, PIN_SCL);
logDebug("-> I2C initialized");

// Attaching interrupts to the configured IRQ pin
pinMode(PIN_HP_IRQ, INPUT);
attachInterrupt(PIN_HP_IRQ, hitpointISR, FALLING);
logDebug("-> Hitpoint ISR attached");

// Allocating memory for the i2c write buffer
i2cWriteBuffer = (uint8_t *)malloc(5 * sizeof(uint8_t));

// Automatic scanning for connected hitpoints
attachedHitpoints = (uint8_t *)malloc(8);
uint8_t transmissionError = 0;
for (uint8_t addr = 0x50; addr < 0x58; addr++) {
Wire.beginTransmission(addr);
transmissionError = Wire.endTransmission();

if (transmissionError == 0) {
logDebug("Found attached hitpoint @ 0x%02x", addr);
attachedHitpoints[attachedHitpointsCount] = addr;
attachedHitpointsCount++;
logInfo("Init: Hitpoint driver");

// Initing I2C Communication
Wire.begin(PIN_SDA, PIN_SCL);
logDebug("-> I2C initialized");

// Attaching interrupts to the configured IRQ pin
pinMode(PIN_HP_IRQ, INPUT);
attachInterrupt(PIN_HP_IRQ, hitpointISR, FALLING);
logDebug("-> Hitpoint ISR attached");

// Allocating memory for the i2c write buffer
i2cWriteBuffer = (uint8_t *)malloc(6 * sizeof(uint8_t));
memset(i2cWriteBuffer, 0, 6 * sizeof(uint8_t));

// Automatic scanning for connected hitpoints
attachedHitpoints = (uint8_t *)malloc(8);
uint8_t transmissionError = 0;
for (uint8_t addr = 0x50; addr < 0x58; addr++) {
Wire.beginTransmission(addr);
transmissionError = Wire.endTransmission();

if (transmissionError == 0) {
logDebug("Found attached hitpoint @ 0x%02x", addr);
attachedHitpoints[attachedHitpointsCount] = addr;
attachedHitpointsCount++;
}
}
}
}
2 changes: 2 additions & 0 deletions src/inc/hitpoint.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Copyright (C) 2023 Ole Lange
#define HP_CMD_SELECT_ANIM 0x01
#define HP_CMD_SET_ANIM_SPEED 0x02
#define HP_CMD_SET_COLOR 0x03
#define HP_CMD_TIMESYNC 0x04

void hitpointInit();

Expand All @@ -27,6 +28,7 @@ void hitpointSetAnimationSpeed(uint8_t addr, uint8_t speed);
void hitpointSetAnimationSpeed(uint8_t speed);
void hitpointSetColor(uint8_t addr, uint8_t r, uint8_t g, uint8_t b);
void hitpointSetColor(uint8_t r, uint8_t g, uint8_t b);
void hitpointSyncTime();

uint8_t getPIDFromShot(uint32_t shot);
uint16_t getSIDFromShot(uint32_t shot);
Loading
Loading