mirror of
https://github.com/eried/portapack-mayhem.git
synced 2025-11-26 14:46:23 -05:00
New memory address for i2c dev loaded apps (#2817)
* New memory address for i2c dev loaded apps * better download handling on error * new hackrf version (added PortapackRf support) * lock i2cdev while loading apps
This commit is contained in:
parent
54d99945f2
commit
2f4d222403
5 changed files with 52 additions and 10 deletions
|
|
@ -132,20 +132,36 @@ namespace ui {
|
|||
|
||||
gridItem.on_select = [&nav, appInfo, i]() {
|
||||
auto dev2 = (i2cdev::I2cDev_PPmod*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDECMDL_PPMOD);
|
||||
dev2->lockDevice();
|
||||
if (dev2) {
|
||||
auto app_image = reinterpret_cast<uint8_t*>(portapack::memory::map::m4_code.end() - appInfo->binary_size);
|
||||
// auto app_image = reinterpret_cast<uint8_t*>(portapack::memory::map::m4_code.end() - appInfo->binary_size);
|
||||
auto app_image = reinterpret_cast<uint8_t*>(portapack::memory::map::local_sram_0.base());
|
||||
uint8_t errorcnt = 0;
|
||||
for (size_t j = 0; j < appInfo->binary_size; j += 128) {
|
||||
errorcnt = 0;
|
||||
do {
|
||||
auto segment = dev2->downloadStandaloneApp(i, j);
|
||||
if (segment.size() != 128) {
|
||||
continue;
|
||||
errorcnt++;
|
||||
if (errorcnt > 5) {
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
std::copy(segment.begin(), segment.end(), app_image + j);
|
||||
break;
|
||||
}
|
||||
} while (1); // when ok, break. when errorcnt > 5, break
|
||||
if (errorcnt > 5) {
|
||||
nav.display_modal("Error", "Unable to download app.");
|
||||
dev2->unlockDevice();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!run_module_app(nav, app_image, appInfo->binary_size)) {
|
||||
nav.display_modal("Error", "Unable to run downloaded app.");
|
||||
}
|
||||
dev2->unlockDevice();
|
||||
} else
|
||||
nav.display_modal("Error", "Unable to download app.");
|
||||
};
|
||||
|
|
@ -346,7 +362,6 @@ namespace ui {
|
|||
if (openError)
|
||||
return false;
|
||||
|
||||
// TODO: move this to m4 memory space
|
||||
auto app_image = reinterpret_cast<uint8_t*>(portapack::memory::map::local_sram_0.base());
|
||||
|
||||
// read file in 512 byte chunks
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ bool I2cDev_PPmod::init(uint8_t addr_) {
|
|||
}
|
||||
|
||||
void I2cDev_PPmod::update() {
|
||||
if (isLocked()) return; // device is busy
|
||||
// mask = get_features_mask(); //saved on init. replug device if something changed. //needs to revise when modules come out.
|
||||
if (mask & (uint64_t)SupportedFeatures::FEAT_GPS && self_timer % SENSORUPDATETIME == 0) {
|
||||
auto data = get_gps_data();
|
||||
|
|
@ -101,11 +102,13 @@ void I2cDev_PPmod::update() {
|
|||
}
|
||||
|
||||
bool I2cDev_PPmod::get_shell_get_buffer_data(uint8_t* buff, size_t len) {
|
||||
if (isLocked()) return false; // device is busy
|
||||
Command cmd = Command::COMMAND_SHELL_MODTOPP_DATA;
|
||||
return i2c_read((uint8_t*)&cmd, 2, buff, len);
|
||||
}
|
||||
|
||||
std::optional<orientation_t> I2cDev_PPmod::get_orientation_data() {
|
||||
if (isLocked()) return std::nullopt; // device is busy
|
||||
Command cmd = Command::COMMAND_GETFEAT_DATA_ORIENTATION;
|
||||
orientation_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(orientation_t));
|
||||
|
|
@ -116,6 +119,7 @@ std::optional<orientation_t> I2cDev_PPmod::get_orientation_data() {
|
|||
}
|
||||
|
||||
std::optional<gpssmall_t> I2cDev_PPmod::get_gps_data() {
|
||||
if (isLocked()) return std::nullopt; // device is busy
|
||||
Command cmd = Command::COMMAND_GETFEAT_DATA_GPS;
|
||||
gpssmall_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(gpssmall_t));
|
||||
|
|
@ -126,6 +130,7 @@ std::optional<gpssmall_t> I2cDev_PPmod::get_gps_data() {
|
|||
}
|
||||
|
||||
std::optional<environment_t> I2cDev_PPmod::get_environment_data() {
|
||||
if (isLocked()) return std::nullopt; // device is busy
|
||||
Command cmd = Command::COMMAND_GETFEAT_DATA_ENVIRONMENT;
|
||||
environment_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(environment_t));
|
||||
|
|
@ -136,6 +141,7 @@ std::optional<environment_t> I2cDev_PPmod::get_environment_data() {
|
|||
}
|
||||
|
||||
std::optional<uint16_t> I2cDev_PPmod::get_light_data() {
|
||||
if (isLocked()) return std::nullopt; // device is busy
|
||||
Command cmd = Command::COMMAND_GETFEAT_DATA_LIGHT;
|
||||
uint16_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(uint16_t));
|
||||
|
|
@ -146,6 +152,7 @@ std::optional<uint16_t> I2cDev_PPmod::get_light_data() {
|
|||
}
|
||||
|
||||
uint16_t I2cDev_PPmod::get_shell_buffer_bytes() {
|
||||
if (isLocked()) return 0; // device is busy
|
||||
Command cmd = Command::COMMAND_SHELL_MODTOPP_DATA_SIZE;
|
||||
uint16_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(uint16_t));
|
||||
|
|
@ -156,6 +163,7 @@ uint16_t I2cDev_PPmod::get_shell_buffer_bytes() {
|
|||
}
|
||||
|
||||
uint64_t I2cDev_PPmod::get_features_mask() {
|
||||
if (isLocked()) return 0; // device is busy
|
||||
uint64_t mask_ = 0;
|
||||
Command cmd = Command::COMMAND_GETFEATURE_MASK;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&mask_, sizeof(mask_));
|
||||
|
|
@ -170,6 +178,7 @@ uint64_t I2cDev_PPmod::get_features_mask() {
|
|||
}
|
||||
|
||||
std::optional<I2cDev_PPmod::device_info> I2cDev_PPmod::readDeviceInfo() {
|
||||
if (isLocked()) return std::nullopt; // device is busy
|
||||
Command cmd = Command::COMMAND_INFO;
|
||||
I2cDev_PPmod::device_info info;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,6 +108,19 @@ FROM HERE YOU SHOULDN'T WRITE ANYTHING IF YOU JUST IMPLEMENT A NEW DRIVER
|
|||
|
||||
*/
|
||||
|
||||
void I2cDev::unlockDevice() {
|
||||
mtx = 0;
|
||||
}
|
||||
|
||||
// when device is locked, all not important queries will return 0 or nullopt, so no communication broken.
|
||||
bool I2cDev::lockDevice() {
|
||||
if (mtx == 0) {
|
||||
mtx = 1;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void I2cDev::set_update_interval(uint8_t interval) {
|
||||
query_interval = interval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace i2cdev {
|
|||
class I2cDev {
|
||||
public:
|
||||
virtual ~I2cDev(){};
|
||||
virtual bool init(uint8_t addr); // returns true if it is that that device we are looking for.
|
||||
virtual bool init(uint8_t addr) = 0; // returns true if it is that that device we are looking for.
|
||||
virtual void update() = 0; // override this, and you'll be able to query your device and broadcast the result to the system
|
||||
|
||||
void set_update_interval(uint8_t interval); // sets the device's update interval in sec. if you change it, don't forget to change back to it's original value after you finished!
|
||||
|
|
@ -59,6 +59,10 @@ class I2cDev {
|
|||
int16_t readS16_LE_1(uint8_t reg);
|
||||
uint32_t read24_1(uint8_t reg);
|
||||
|
||||
bool lockDevice(); // locks the device's "mutex". returns true on success. guard important communication with this
|
||||
void unlockDevice(); // unlocks the device's "mutex"
|
||||
inline bool isLocked() { return mtx != 0; }
|
||||
|
||||
bool need_del = false; // device can self destruct, and re-init when new scan discovers it
|
||||
I2C_DEVMDL model = I2CDEVMDL_NOTSET; // overwrite it in the init()!!!
|
||||
uint8_t query_interval = 5; // in seconds. can be overriden in init() if necessary
|
||||
|
|
@ -68,6 +72,7 @@ class I2cDev {
|
|||
|
||||
uint8_t addr = 0; // some devices can have different addresses, so we store what was it wound with
|
||||
uint8_t errcnt = 0; // error count during communication. if it reaches a threshold set need_del to remove itself from the device list
|
||||
uint8_t mtx = 0; // internal lock, so important client code can be skipped when lock is on. check PPMod for an example
|
||||
};
|
||||
|
||||
// store for the devices. may not have a driver if not supported
|
||||
|
|
|
|||
2
hackrf
2
hackrf
|
|
@ -1 +1 @@
|
|||
Subproject commit 651d0a7f232e12016b3b12fb6a9b3fea08eb52fd
|
||||
Subproject commit 03e4732a5308a3d0de5b0341004d7a2fcc825806
|
||||
Loading…
Add table
Add a link
Reference in a new issue