Skip to content

Commit

Permalink
Add patch saving and loading
Browse files Browse the repository at this point in the history
  • Loading branch information
nsynthsuper committed Aug 10, 2018
1 parent e3f48cc commit 7e5eed9
Show file tree
Hide file tree
Showing 14 changed files with 785 additions and 106 deletions.
1 change: 1 addition & 0 deletions app/open-nsynth/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/bin/data/localSettings.json
/bin/data/patches.json
/bin/open-nsynth
/obj
16 changes: 10 additions & 6 deletions app/open-nsynth/src/AnalogInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,21 @@ void AnalogInput::init(uint8_t value){
}


bool AnalogInput::update(uint8_t value, bool currentScreen){
int8_t delta = abs(static_cast<int8_t>(value - displayedValue));
bool AnalogInput::update(uint8_t value, bool software, bool currentScreen){
bool changed;

if(currentScreen){
changed = delta > CURRENT_SCREEN_DELTA;
if(software){
changed = value != displayedValue;
}else{
changed = delta > HIDDEN_SCREEN_DELTA;
int delta = abs(int(value) - int(readValue));
if(currentScreen){
changed = delta > CURRENT_SCREEN_DELTA;
}else{
changed = delta > HIDDEN_SCREEN_DELTA;
}
readValue = value;
}

readValue = value;
if(changed){
displayedValue = value;
}
Expand Down
4 changes: 2 additions & 2 deletions app/open-nsynth/src/AnalogInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ class AnalogInput{

// Updates the value.
// Returns true if the value has changed more than a threshold.
bool update(uint8_t value, bool currentScreen);
bool update(uint8_t value, bool software, bool currentScreen=false);

// Returns the value as a float in the range 0.0 - 1.0.
// Returns the displayedValue as a float in the range 0.0 - 1.0.
float getNormalized() const;

static constexpr int CURRENT_SCREEN_DELTA = 2;
Expand Down
124 changes: 124 additions & 0 deletions app/open-nsynth/src/Gpio.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
Copyright 2017 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#include "Gpio.h"

#include <chrono>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <thread>
#include <unistd.h>


constexpr int SET = 7;
constexpr int CLEAR = 10;
constexpr int GET = 13;
constexpr int MAP_SIZE = 0xb4;
constexpr int GPPUD = 37;
constexpr int GPPUDCLK = 38;


Gpio::Gpio(){
int fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
if(fd >= 0){
gpioReg = (uint32_t *)mmap(
NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

if(gpioReg == MAP_FAILED){
gpioReg = nullptr;
}

close(fd);
}
}


Gpio::~Gpio(){
if(gpioReg){
munmap(const_cast<uint32_t *>(gpioReg), MAP_SIZE);
}
}


Gpio::operator bool() const{
return gpioReg != nullptr;
}


bool Gpio::setInput(int pin, Pull pull){
if(!gpioReg || pin < 2 || pin > 27){
return false;
}

int reg = pin / 10;
int shift = (pin % 10) * 3;

gpioReg[reg] = (gpioReg[reg] & ~(7<<shift));

gpioReg[GPPUD] = pull & 3;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
gpioReg[GPPUDCLK] = 1 << pin;
std::this_thread::sleep_for(std::chrono::milliseconds(1));

gpioReg[GPPUD] = 0;
gpioReg[GPPUDCLK] = 0;

return true;
}


bool Gpio::setOutput(int pin){
if(!gpioReg || pin < 2 || pin > 27){
return false;
}

int reg = pin / 10;
int shift = (pin % 10) * 3;

gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (1<<shift);

return true;
}


bool Gpio::write(int pin, bool high){
if(!gpioReg || pin < 2 || pin > 27){
return false;
}

gpioReg[high ? SET : CLEAR] = 1 << (pin & 0x1f);
return true;
}


bool Gpio::read(int pin){
if(!gpioReg || pin < 2 || pin > 27){
return false;
}

return (gpioReg[GET] & (1 << (pin & 0x1f))) != 0;
}


void Gpio::reset(int pin, size_t uSecHold, size_t uSecDelay){
// Set the pin to an output and drive it low.
setOutput(pin);
write(pin, false);
std::this_thread::sleep_for(std::chrono::microseconds(uSecHold));

// Restore the pin
write(pin, 1);
setInput(pin, PULL_UP);
std::this_thread::sleep_for(std::chrono::microseconds(uSecDelay));
}
45 changes: 45 additions & 0 deletions app/open-nsynth/src/Gpio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
Copyright 2017 Google Inc. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

#pragma once

#include <cstddef>
#include <stdint.h>


// Provides access to the GPIO pins on a Raspberry Pi
class Gpio{
public:
enum Pull{
PULL_NONE=0,
PULL_DOWN,
PULL_UP
};

Gpio();
~Gpio();

operator bool() const;

bool setInput(int pin, Pull pull=PULL_NONE);
bool setOutput(int pin);

bool write(int pin, bool high);
bool read(int pin);

// Sends a reset signal by pulsing a pin low.
void reset(int pin, size_t uSecHold, size_t uSecDelay);

protected:
volatile uint32_t *gpioReg = nullptr;
};
66 changes: 2 additions & 64 deletions app/open-nsynth/src/OledScreenDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ limitations under the License.
#include <unistd.h>


bool OledScreenDriver::setup(int i2cFd_, uint8_t address_, int resetPin){
bool OledScreenDriver::setup(int i2cFd_, uint8_t address_){
i2cFd = i2cFd_;
address = address_;

Expand All @@ -31,10 +31,7 @@ bool OledScreenDriver::setup(int i2cFd_, uint8_t address_, int resetPin){
return false;
}

// First use the reset pin to reset the screen.
reset(resetPin);

// Now send the screen setup commands.
// Send the screen setup commands.
static uint8_t setup0[] = {
0, 174, 213, 128, 168, 63, 211, 0, 64, 141, 20, 32,
0, 161, 200, 218, 18, 217, 241, 219, 64, 164, 166
Expand Down Expand Up @@ -110,62 +107,3 @@ void OledScreenDriver::draw(ofFbo &fbo){
return;
}
}


void OledScreenDriver::reset(int resetPin){
constexpr int INPUT = 1;
constexpr int OUTPUT = 1;
constexpr int SET = 7;
constexpr int CLEAR = 10;
constexpr int MAP_SIZE = 0xb4;

if(resetPin < 0){
return;
}

// Mmap the GPIO device to access the pins.
int fd = open("/dev/gpiomem", O_RDWR | O_SYNC);
if(fd < 0){
return;
}

volatile uint32_t *gpioReg = (uint32_t *)mmap(
NULL, MAP_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

close(fd);

if(gpioReg == MAP_FAILED){
return;
}

// Sets the mode to either INPUT or OUTPUT.
auto setMode = [&](int mode){
int reg = resetPin / 10;
int shift = (resetPin % 10) * 3;

gpioReg[reg] = (gpioReg[reg] & ~(7<<shift)) | (mode<<shift);
};

// Sets the level to high (1) or low (0).
auto writeLevel = [&](int level){
int bank = resetPin >> 5;
int val = 1 << (resetPin & 0x1f);
if(level){
gpioReg[bank+SET] = val;
}else{
gpioReg[bank+CLEAR] = val;
}
};

// Drive the reset pin low for 1ms.
setMode(OUTPUT);
writeLevel(0);
usleep(1000);
writeLevel(1);

// Then change it back to an input and wait for the screen to initialise.
setMode(INPUT);
usleep(1000);

munmap(const_cast<uint32_t *>(gpioReg), MAP_SIZE);
}
5 changes: 2 additions & 3 deletions app/open-nsynth/src/OledScreenDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,18 @@ limitations under the License.
#pragma once

#include "ofMain.h"
#include "Gpio.h"


// Drives the SSD1306 based screen over I2C.
class OledScreenDriver{
public:
// Sends the initial configuration to the screen.
bool setup(int i2cFd, uint8_t address, int resetPin=-1);
bool setup(int i2cFd, uint8_t address);
// Draws a 128x64 frame buffer on the screen.
void draw(ofFbo &fbo);

private:
// Resets the screen by driving a GPIO reset pin low.
void reset(int resetPin);
// The file descriptor of the I2C device.
int i2cFd;
// The I2C address of the screen.
Expand Down
Loading

0 comments on commit 7e5eed9

Please sign in to comment.