Skip to content

Commit

Permalink
WIP; split into commits later
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashton Eby committed Feb 21, 2021
1 parent 704fa25 commit f31ab41
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 104 deletions.
6 changes: 4 additions & 2 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
],
"conditions": [
["OS == 'linux'", {
"cflags": ["-fpermissive", "-fexceptions", "-Wmisleading-indentation"],
"cflags_cc": ["-fpermissive", "-fexceptions", "-Wmisleading-indentation"],
"sources": [
"src/bcm2835.c",
"src/sunxi.c"
"src/bcm2835.cpp",
"src/sunxi.cpp"
]
}]
]
Expand Down
98 changes: 46 additions & 52 deletions src/bcm2835.c → src/bcm2835.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <time.h>
#include <unistd.h>
#include <sys/types.h>
#include <map>

#define BCK2835_LIBRARY_BUILD
#include "bcm2835.h"
Expand Down Expand Up @@ -116,16 +117,6 @@ static uint8_t bcm2835_byte_reverse_table[] =
0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff
};

struct PDESettings
{
uint32_t longDuration = 0;
uint32_t shortDuration = 0;
uint32_t separatorDuration = 0;
uint32_t separator = 1;
};

std::map<uint32_t , PDESettings> pin_settings_map = {};

static uint8_t bcm2835_correct_order(uint8_t b)
{
if (bcm2835_spi_bit_order == BCM2835_SPI_BIT_ORDER_LSBFIRST)
Expand Down Expand Up @@ -185,6 +176,16 @@ uint32_t* bcm2835_regbase(uint8_t regbase)
return (uint32_t *)MAP_FAILED;
}

struct PDESettings
{
uint32_t longDuration;
uint32_t shortDuration;
uint32_t separatorDuration;
uint32_t separator;
};

std::map<uint32_t, PDESettings> bcm2835_pin_settings_map = {};

void bcm2835_set_debug(uint8_t d)
{
debug = d;
Expand Down Expand Up @@ -945,109 +946,102 @@ void bcm2835_spi_write(uint16_t data)

void bcm2835_pde_set_separator_duration(uint32_t pin, uint32_t duration)
{
if (!pin_settings_map.contains(pin)) {
pin_settings_map.emplace(pin, {});
if (bcm2835_pin_settings_map.find(pin) == bcm2835_pin_settings_map.end()) {
bcm2835_pin_settings_map.insert(std::make_pair(pin, PDESettings()));
}

pin_settings_map.at(pin).separatorDuration = duration;
bcm2835_pin_settings_map.at(pin).separatorDuration = duration;
}

void bcm2835_pde_set_short_duration(uint32_t pin, uint32_t duration)
{
if (!pin_settings_map.contains(pin)) {
pin_settings_map.emplace(pin, {});
if (bcm2835_pin_settings_map.find(pin) == bcm2835_pin_settings_map.end()) {
bcm2835_pin_settings_map.insert(std::make_pair(pin, PDESettings()));
}

pin_settings_map.at(pin).shortDuration = duration;
bcm2835_pin_settings_map.at(pin).shortDuration = duration;
}

void bcm2835_pde_set_long_duration(uint32_t pin, uint32_t duration)
{
if (!pin_settings_map.contains(pin)) {
pin_settings_map.emplace(pin, {});
if (bcm2835_pin_settings_map.find(pin) == bcm2835_pin_settings_map.end()) {
bcm2835_pin_settings_map.insert(std::make_pair(pin, PDESettings()));
}

pin_settings_map.at(pin).longDuration = duration;
bcm2835_pin_settings_map.at(pin).longDuration = duration;
}

void bcm2835_pde_set_separator(uint32_t pin, uint32_t separator)
{
if (!pin_settings_map.contains(pin)) {
pin_settings_map.emplace(pin, {});
if (bcm2835_pin_settings_map.find(pin) == bcm2835_pin_settings_map.end()) {
bcm2835_pin_settings_map.insert(std::make_pair(pin, PDESettings()));
}

pin_settings_map.at(pin).separator = separator;
bcm2835_pin_settings_map.at(pin).separator = separator;
}

void bcm2835_pde_write(uint32_t pin, char* buf, uint32_t len)
{
// validate that pin_settings_map[pin] is correct
if (!pin_settings_map.contains(pin)) {
char* error [48];
sprintf(error, "Pin %d was not configured before calling write!", pin);
throw new exception(error);
// validate that bcm2835_pin_settings_map[pin] is correct
if (bcm2835_pin_settings_map.find(pin) == bcm2835_pin_settings_map.end()) {
char error [48];
throw sprintf(error, "Pin %d was not configured before calling write!", pin);
}

if (pin_settings_map[pin].longDuration == 0) {
char* error [56];
sprintf(error, "Pin %d's longDuration was not set before calling write!", pin);
throw new exception(error);
if (bcm2835_pin_settings_map[pin].longDuration == 0) {
char error [56];
throw sprintf(error, "Pin %d's longDuration was not set before calling write!", pin);
}

if (pin_settings_map[pin].shortDuration == 0) {
char* error [57];
sprintf(error, "Pin %d's shortDuration was not set before calling write!", pin);
throw new exception(error);
if (bcm2835_pin_settings_map[pin].shortDuration == 0) {
char error [57];
throw sprintf(error, "Pin %d's shortDuration was not set before calling write!", pin);
}

if (pin_settings_map[pin].separatorDuration == 0) {
char* error [61];
sprintf(error, "Pin %d's separatorDuration was not set before calling write!", pin);
throw new exception(error);
if (bcm2835_pin_settings_map[pin].separatorDuration == 0) {
char error [61];
throw sprintf(error, "Pin %d's separatorDuration was not set before calling write!", pin);
}

// implied: separator will be 0 or 1, with default being set upstream in node (lib/rpio.js)
if (pin_settings_map[pin].separator > 1) {
char* error [83];
sprintf(error, "Pin %d's separator was set to an incorrect value (not 0 or 1) before calling write!", pin);
throw new exception(error);
if (bcm2835_pin_settings_map[pin].separator > 1) {
char error [83];
throw sprintf(error, "Pin %d's separator was set to an incorrect value (not 0 or 1) before calling write!", pin);
}

// TODO: verify len <= buf.len

if (pin_settings_map[pin].separator) {
if (bcm2835_pin_settings_map[pin].separator) {
bcm2835_gpio_set(pin);
} else {
bcm2835_gpio_clr(pin);
}

bcm2835_delayMicroseconds(pin_settings_map[pin].separatorDuration);
bcm2835_delayMicroseconds(bcm2835_pin_settings_map[pin].separatorDuration);

for(uint32_t index = 0; index < len; index++) {
// TODO: LSB. Should allow customizing for MSB as well
for(int bitdex = 0; bitdex < 8; bitdex++) {
// do the "encoded" bit
if (!pin_settings_map[pin].separator) {
if (!bcm2835_pin_settings_map[pin].separator) {
bcm2835_gpio_set(pin);
} else {
bcm2835_gpio_clr(pin);
}

// TODO: should these be renamed? long is actually "high", short is actually "low"
if ((buf[index] >> bitdex) & 0x01) {
bcm2835_delayMicroseconds(pin_settings_map[pin].longDuration);
bcm2835_delayMicroseconds(bcm2835_pin_settings_map[pin].longDuration);
} else {
bcm2835_delayMicroseconds(pin_settings_map[pin].shortDuration);
bcm2835_delayMicroseconds(bcm2835_pin_settings_map[pin].shortDuration);
}

// do the "separator" bit
if (pin_settings_map[pin].separator) {
if (bcm2835_pin_settings_map[pin].separator) {
bcm2835_gpio_set(pin);
} else {
bcm2835_gpio_clr(pin);
}

bcm2835_delayMicroseconds(pin_settings_map[pin].separatorDuration);
bcm2835_delayMicroseconds(bcm2835_pin_settings_map[pin].separatorDuration);
}
}
}
Expand Down
8 changes: 7 additions & 1 deletion src/bcm2835.h
Original file line number Diff line number Diff line change
Expand Up @@ -1980,13 +1980,19 @@ extern "C" {
\param[in] data Controls the PWM output ratio as a fraction of the range.
Can vary from 0 to RANGE.
*/
/*! @} */
extern void bcm2835_pwm_set_data(uint8_t channel, uint32_t data);

/*! @} */
#ifdef __cplusplus
}
#endif

extern void bcm2835_pde_set_separator_duration(uint32_t pin, uint32_t duration);
extern void bcm2835_pde_set_short_duration(uint32_t pin, uint32_t duration);
extern void bcm2835_pde_set_long_duration(uint32_t pin, uint32_t duration);
extern void bcm2835_pde_set_separator(uint32_t pin, uint32_t separator);
extern void bcm2835_pde_write(uint32_t pin, char* buf, uint32_t len);

#endif /* BCM2835_H */

/*! @example blink.c
Expand Down
4 changes: 2 additions & 2 deletions src/rpio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -584,10 +584,10 @@ NAN_METHOD(pde_write)

switch (soctype) {
case RPIO_SOC_BCM2835:
bcm2835_pde_write(pin, buf[i], len);
bcm2835_pde_write(pin, buf, len);
break;
case RPIO_SOC_SUNXI:
sunxi_pde_write(pin, buf[i], len);
sunxi_pde_write(pin, buf, len);
break;
}
}
Expand Down
Loading

0 comments on commit f31ab41

Please sign in to comment.