Add support for the Oceanic Pro Plus X

The Oceanic Pro Plus X is quite different from the previous models. The
profile data is now stored in a dedicated memory area, and hence there
are a few important differences:

Reading data from the new profile memory area is done with a new F6
command. This new command is very similar to the existing B8 command,
but accesses a completely different memory area. In order to integrate
those two memory areas as transparantly as possible into the existing
infrastructure, a virtual memory space is introduced. The lower part of
the virtual memory is mapped onto the main memory area, while the upper
part is mapped onto the new profile memory area.

The page size of the new profile memory area also increased from 16 to
256 bytes. If the profile size is not an exact multiple of 256 bytes,
the dive computer pads the profile data with 0xFF bytes.

The other changes are the usual Oceanic device specific changes.
This commit is contained in:
Jef Driesen 2017-12-13 23:18:47 +01:00
parent b3144ac26b
commit aee70d1ec7
7 changed files with 132 additions and 36 deletions

View File

@ -208,6 +208,7 @@ static const dc_descriptor_t g_descriptors[] = {
{"Oceanic", "OCi", DC_FAMILY_OCEANIC_ATOM2, 0x454B, DC_TRANSPORT_SERIAL, NULL},
{"Aeris", "A300CS", DC_FAMILY_OCEANIC_ATOM2, 0x454C, DC_TRANSPORT_SERIAL, NULL},
{"Beuchat", "Mundial 3", DC_FAMILY_OCEANIC_ATOM2, 0x4550, DC_TRANSPORT_SERIAL, NULL},
{"Oceanic", "Pro Plus X", DC_FAMILY_OCEANIC_ATOM2, 0x4552, DC_TRANSPORT_SERIAL, NULL},
{"Oceanic", "F10", DC_FAMILY_OCEANIC_ATOM2, 0x4553, DC_TRANSPORT_SERIAL, NULL},
{"Oceanic", "F11", DC_FAMILY_OCEANIC_ATOM2, 0x4554, DC_TRANSPORT_SERIAL, NULL},
{"Subgear", "XP-Air", DC_FAMILY_OCEANIC_ATOM2, 0x4555, DC_TRANSPORT_SERIAL, NULL},

View File

@ -32,6 +32,7 @@
#define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_atom2_device_vtable.base)
#define PROPLUSX 0x4552
#define VTX 0x4557
#define I750TC 0x455A
@ -44,6 +45,7 @@
#define CMD_READ1 0xB1
#define CMD_READ8 0xB4
#define CMD_READ16 0xB8
#define CMD_READ16HI 0xF6
#define CMD_WRITE 0xB2
#define CMD_KEEPALIVE 0x91
#define CMD_QUIT 0x6A
@ -57,7 +59,8 @@ typedef struct oceanic_atom2_device_t {
unsigned int delay;
unsigned int bigpage;
unsigned char cache[256];
unsigned int cached;
unsigned int cached_page;
unsigned int cached_highmem;
} oceanic_atom2_device_t;
static dc_status_t oceanic_atom2_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size);
@ -184,6 +187,10 @@ static const oceanic_common_version_t oceanic_reactpro_version[] = {
{"REACPRO2 \0\0 512K"},
};
static const oceanic_common_version_t oceanic_proplusx_version[] = {
{"OCEANOCX \0\0 2048"},
};
static const oceanic_common_version_t aeris_a300cs_version[] = {
{"AER300CS \0\0 2048"},
{"OCEANVTX \0\0 2048"},
@ -196,6 +203,7 @@ static const oceanic_common_version_t aqualung_i450t_version[] = {
static const oceanic_common_layout_t aeris_f10_layout = {
0x10000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0100, /* rb_logbook_begin */
@ -210,6 +218,7 @@ static const oceanic_common_layout_t aeris_f10_layout = {
static const oceanic_common_layout_t aeris_f11_layout = {
0x20000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0100, /* rb_logbook_begin */
@ -224,6 +233,7 @@ static const oceanic_common_layout_t aeris_f11_layout = {
static const oceanic_common_layout_t oceanic_default_layout = {
0x10000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0240, /* rb_logbook_begin */
@ -238,6 +248,7 @@ static const oceanic_common_layout_t oceanic_default_layout = {
static const oceanic_common_layout_t oceanic_atom1_layout = {
0x8000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0240, /* rb_logbook_begin */
@ -252,6 +263,7 @@ static const oceanic_common_layout_t oceanic_atom1_layout = {
static const oceanic_common_layout_t oceanic_atom2a_layout = {
0xFFF0, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0240, /* rb_logbook_begin */
@ -266,6 +278,7 @@ static const oceanic_common_layout_t oceanic_atom2a_layout = {
static const oceanic_common_layout_t oceanic_atom2b_layout = {
0x10000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0240, /* rb_logbook_begin */
@ -280,6 +293,7 @@ static const oceanic_common_layout_t oceanic_atom2b_layout = {
static const oceanic_common_layout_t oceanic_atom2c_layout = {
0xFFF0, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0240, /* rb_logbook_begin */
@ -294,6 +308,7 @@ static const oceanic_common_layout_t oceanic_atom2c_layout = {
static const oceanic_common_layout_t sherwood_wisdom_layout = {
0xFFF0, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x03D0, /* rb_logbook_begin */
@ -308,6 +323,7 @@ static const oceanic_common_layout_t sherwood_wisdom_layout = {
static const oceanic_common_layout_t oceanic_proplus3_layout = {
0x10000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x03E0, /* rb_logbook_begin */
@ -322,6 +338,7 @@ static const oceanic_common_layout_t oceanic_proplus3_layout = {
static const oceanic_common_layout_t tusa_zenair_layout = {
0xFFF0, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0240, /* rb_logbook_begin */
@ -336,6 +353,7 @@ static const oceanic_common_layout_t tusa_zenair_layout = {
static const oceanic_common_layout_t oceanic_oc1_layout = {
0x20000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0240, /* rb_logbook_begin */
@ -350,6 +368,7 @@ static const oceanic_common_layout_t oceanic_oc1_layout = {
static const oceanic_common_layout_t oceanic_oci_layout = {
0x20000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x10C0, /* rb_logbook_begin */
@ -364,6 +383,7 @@ static const oceanic_common_layout_t oceanic_oci_layout = {
static const oceanic_common_layout_t oceanic_atom3_layout = {
0x20000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0400, /* rb_logbook_begin */
@ -378,6 +398,7 @@ static const oceanic_common_layout_t oceanic_atom3_layout = {
static const oceanic_common_layout_t oceanic_vt4_layout = {
0x20000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0420, /* rb_logbook_begin */
@ -392,6 +413,7 @@ static const oceanic_common_layout_t oceanic_vt4_layout = {
static const oceanic_common_layout_t hollis_tx1_layout = {
0x40000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0780, /* rb_logbook_begin */
@ -406,6 +428,7 @@ static const oceanic_common_layout_t hollis_tx1_layout = {
static const oceanic_common_layout_t oceanic_veo1_layout = {
0x0400, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0400, /* rb_logbook_begin */
@ -420,6 +443,7 @@ static const oceanic_common_layout_t oceanic_veo1_layout = {
static const oceanic_common_layout_t oceanic_reactpro_layout = {
0xFFF0, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0400, /* rb_logbook_begin */
@ -432,8 +456,24 @@ static const oceanic_common_layout_t oceanic_reactpro_layout = {
1, /* pt_mode_serial */
};
static const oceanic_common_layout_t oceanic_proplusx_layout = {
0x440000, /* memsize */
0x40000, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x1000, /* rb_logbook_begin */
0x10000, /* rb_logbook_end */
16, /* rb_logbook_entry_size */
0x40000, /* rb_profile_begin */
0x440000, /* rb_profile_end */
0, /* pt_mode_global */
1, /* pt_mode_logbook */
0, /* pt_mode_serial */
};
static const oceanic_common_layout_t aeris_a300cs_layout = {
0x40000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0900, /* rb_logbook_begin */
@ -448,6 +488,7 @@ static const oceanic_common_layout_t aeris_a300cs_layout = {
static const oceanic_common_layout_t aqualung_i450t_layout = {
0x40000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x10C0, /* rb_logbook_begin */
@ -595,12 +636,13 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream
device->iostream = iostream;
device->delay = 0;
device->bigpage = 1; // no big pages
device->cached = INVALID;
device->cached_page = INVALID;
device->cached_highmem = INVALID;
memset(device->cache, 0, sizeof(device->cache));
// Get the correct baudrate.
unsigned int baudrate = 38400;
if (model == VTX || model == I750TC) {
if (model == VTX || model == I750TC || model == PROPLUSX) {
baudrate = 115200;
}
@ -684,6 +726,9 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream
device->base.layout = &oceanic_veo1_layout;
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_reactpro_version)) {
device->base.layout = &oceanic_reactpro_layout;
} else if (OCEANIC_COMMON_MATCH (device->base.version, oceanic_proplusx_version)) {
device->base.layout = &oceanic_proplusx_layout;
device->bigpage = 16;
} else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_a300cs_version)) {
device->base.layout = &aeris_a300cs_layout;
device->bigpage = 16;
@ -779,6 +824,7 @@ static dc_status_t
oceanic_atom2_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size)
{
oceanic_atom2_device_t *device = (oceanic_atom2_device_t*) abstract;
const oceanic_common_layout_t *layout = device->base.layout;
if ((address % PAGESIZE != 0) ||
(size % PAGESIZE != 0))
@ -807,12 +853,26 @@ oceanic_atom2_device_read (dc_device_t *abstract, unsigned int address, unsigned
// Pick the best pagesize to use.
unsigned int pagesize = device->bigpage * PAGESIZE;
// High memory state.
unsigned int highmem = 0;
unsigned int nbytes = 0;
while (nbytes < size) {
unsigned int page = address / pagesize;
if (page != device->cached) {
// Switch to the correct read command when entering the high memory area.
if (layout->highmem && address >= layout->highmem && !highmem) {
highmem = layout->highmem;
read_cmd = CMD_READ16HI;
crc_size = 2;
pagesize = 16 * PAGESIZE;
}
// Calculate the page number after mapping the virtual high memory
// addresses back to their physical address.
unsigned int page = (address - highmem) / pagesize;
if (page != device->cached_page || highmem != device->cached_highmem) {
// Read the package.
unsigned int number = page * device->bigpage; // This is always PAGESIZE, even in big page mode.
unsigned int number = highmem ? page : page * device->bigpage; // This is always PAGESIZE, even in big page mode.
unsigned char answer[256 + 2] = {0}; // Maximum we support for the known commands.
unsigned char command[4] = {read_cmd,
(number >> 8) & 0xFF, // high
@ -824,7 +884,8 @@ oceanic_atom2_device_read (dc_device_t *abstract, unsigned int address, unsigned
// Cache the page.
memcpy (device->cache, answer, pagesize);
device->cached = page;
device->cached_page = page;
device->cached_highmem = highmem;
}
unsigned int offset = address % pagesize;
@ -853,7 +914,8 @@ oceanic_atom2_device_write (dc_device_t *abstract, unsigned int address, const u
return DC_STATUS_INVALIDARGS;
// Invalidate the cache.
device->cached = INVALID;
device->cached_page = INVALID;
device->cached_highmem = INVALID;
unsigned int nbytes = 0;
while (nbytes < size) {

View File

@ -75,6 +75,7 @@
#define OCI 0x454B
#define A300CS 0x454C
#define MUNDIAL3 0x4550
#define PROPLUSX 0x4552
#define F10B 0x4553
#define F11B 0x4554
#define XPAIR 0x4555
@ -174,6 +175,8 @@ oceanic_atom2_parser_create (dc_parser_t **out, dc_context_t *context, unsigned
} else if (model == A300CS || model == VTX ||
model == I450T || model == I750TC) {
parser->headersize = 5 * PAGESIZE;
} else if (model == PROPLUSX) {
parser->headersize = 3 * PAGESIZE;
}
parser->cached = 0;
@ -309,6 +312,7 @@ oceanic_atom2_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetim
case VTX:
case I450T:
case I750TC:
case PROPLUSX:
datetime->year = (p[10]) + 2000;
datetime->month = (p[8]);
datetime->day = (p[9]);
@ -622,7 +626,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
if (parser->mode != FREEDIVE) {
unsigned int idx = 0x17;
if (parser->model == A300CS || parser->model == VTX ||
parser->model == I450T || parser->model == I750TC)
parser->model == I450T || parser->model == I750TC ||
parser->model == PROPLUSX)
idx = 0x1f;
switch (data[idx] & 0x03) {
case 0:
@ -677,7 +682,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
parser->model == OC1C || parser->model == OCI ||
parser->model == TX1 || parser->model == A300CS ||
parser->model == VTX || parser->model == I450T ||
parser->model == I750TC) {
parser->model == I750TC || parser->model == PROPLUSX) {
samplesize = PAGESIZE;
}
@ -855,7 +860,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
parser->model == XPAIR) {
temperature = ((data[offset + 7] & 0xF0) >> 4) | ((data[offset + 7] & 0x0C) << 2) | ((data[offset + 5] & 0x0C) << 4);
} else if (parser->model == A300CS || parser->model == VTX ||
parser->model == I750TC) {
parser->model == I750TC || parser->model == PROPLUSX) {
temperature = data[offset + 11];
} else {
unsigned int sign;
@ -895,7 +900,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
parser->model == VISION || parser->model == XPAIR)
pressure = (((data[offset + 0] & 0x03) << 8) + data[offset + 1]) * 5;
else if (parser->model == TX1 || parser->model == A300CS ||
parser->model == VTX || parser->model == I750TC)
parser->model == VTX || parser->model == I750TC ||
parser->model == PROPLUSX)
pressure = array_uint16_le (data + offset + 4);
else
pressure -= data[offset + 1];
@ -943,7 +949,8 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
unsigned int have_deco = 0;
unsigned int decostop = 0, decotime = 0;
if (parser->model == A300CS || parser->model == VTX ||
parser->model == I450T || parser->model == I750TC) {
parser->model == I450T || parser->model == I750TC ||
parser->model == PROPLUSX) {
decostop = (data[offset + 15] & 0x70) >> 4;
decotime = array_uint16_le(data + offset + 6) & 0x03FF;
have_deco = 1;
@ -986,7 +993,7 @@ oceanic_atom2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_
have_rbt = 1;
} else if (parser->model == I450T || parser->model == OC1A ||
parser->model == OC1B || parser->model == OC1C ||
parser->model == OCI) {
parser->model == OCI || parser->model == PROPLUSX) {
rbt = array_uint16_le(data + offset + 8) & 0x01FF;
have_rbt = 1;
} else if (parser->model == VISION || parser->model == XPAIR ||

View File

@ -41,7 +41,7 @@
#define INVALID 0
static unsigned int
get_profile_first (const unsigned char data[], const oceanic_common_layout_t *layout)
get_profile_first (const unsigned char data[], const oceanic_common_layout_t *layout, unsigned int pagesize)
{
unsigned int value;
@ -55,17 +55,22 @@ get_profile_first (const unsigned char data[], const oceanic_common_layout_t *la
return array_uint16_le (data + 16);
}
if (layout->memsize > 0x20000)
return (value & 0x3FFF) * PAGESIZE;
else if (layout->memsize > 0x10000)
return (value & 0x1FFF) * PAGESIZE;
else
return (value & 0x0FFF) * PAGESIZE;
unsigned int npages = (layout->memsize - layout->highmem) / pagesize;
if (npages > 0x2000) {
value &= 0x3FFF;
} else if (npages > 0x1000) {
value &= 0x1FFF;
} else {
value &= 0x0FFF;
}
return layout->highmem + value * pagesize;
}
static unsigned int
get_profile_last (const unsigned char data[], const oceanic_common_layout_t *layout)
get_profile_last (const unsigned char data[], const oceanic_common_layout_t *layout, unsigned int pagesize)
{
unsigned int value;
@ -79,12 +84,17 @@ get_profile_last (const unsigned char data[], const oceanic_common_layout_t *lay
return array_uint16_le(data + 18);
}
if (layout->memsize > 0x20000)
return (value & 0x3FFF) * PAGESIZE;
else if (layout->memsize > 0x10000)
return (value & 0x1FFF) * PAGESIZE;
else
return (value & 0x0FFF) * PAGESIZE;
unsigned int npages = (layout->memsize - layout->highmem) / pagesize;
if (npages > 0x2000) {
value &= 0x3FFF;
} else if (npages > 0x1000) {
value &= 0x1FFF;
} else {
value &= 0x0FFF;
}
return layout->highmem + value * pagesize;
}
@ -330,6 +340,9 @@ oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progr
const oceanic_common_layout_t *layout = device->layout;
// Get the pagesize
unsigned int pagesize = layout->highmem ? 16 * PAGESIZE : PAGESIZE;
// Cache the logbook pointer and size.
const unsigned char *logbooks = dc_buffer_get_data (logbook);
unsigned int rb_logbook_size = dc_buffer_get_size (logbook);
@ -352,8 +365,8 @@ oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progr
entry -= layout->rb_logbook_entry_size;
// Get the profile pointers.
unsigned int rb_entry_first = get_profile_first (logbooks + entry, layout);
unsigned int rb_entry_last = get_profile_last (logbooks + entry, layout);
unsigned int rb_entry_first = get_profile_first (logbooks + entry, layout, pagesize);
unsigned int rb_entry_last = get_profile_last (logbooks + entry, layout, pagesize);
if (rb_entry_first < layout->rb_profile_begin ||
rb_entry_first >= layout->rb_profile_end ||
rb_entry_last < layout->rb_profile_begin ||
@ -365,8 +378,8 @@ oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progr
}
// Calculate the end pointer and the number of bytes.
unsigned int rb_entry_end = RB_PROFILE_INCR (rb_entry_last, PAGESIZE, layout);
unsigned int rb_entry_size = RB_PROFILE_DISTANCE (rb_entry_first, rb_entry_last, layout) + PAGESIZE;
unsigned int rb_entry_end = RB_PROFILE_INCR (rb_entry_last, pagesize, layout);
unsigned int rb_entry_size = RB_PROFILE_DISTANCE (rb_entry_first, rb_entry_last, layout) + pagesize;
// Take the end pointer of the most recent logbook entry as the
// end of profile pointer.
@ -430,8 +443,8 @@ oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progr
entry -= layout->rb_logbook_entry_size;
// Get the profile pointers.
unsigned int rb_entry_first = get_profile_first (logbooks + entry, layout);
unsigned int rb_entry_last = get_profile_last (logbooks + entry, layout);
unsigned int rb_entry_first = get_profile_first (logbooks + entry, layout, pagesize);
unsigned int rb_entry_last = get_profile_last (logbooks + entry, layout, pagesize);
if (rb_entry_first < layout->rb_profile_begin ||
rb_entry_first >= layout->rb_profile_end ||
rb_entry_last < layout->rb_profile_begin ||
@ -445,8 +458,8 @@ oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progr
}
// Calculate the end pointer and the number of bytes.
unsigned int rb_entry_end = RB_PROFILE_INCR (rb_entry_last, PAGESIZE, layout);
unsigned int rb_entry_size = RB_PROFILE_DISTANCE (rb_entry_first, rb_entry_last, layout) + PAGESIZE;
unsigned int rb_entry_end = RB_PROFILE_INCR (rb_entry_last, pagesize, layout);
unsigned int rb_entry_size = RB_PROFILE_DISTANCE (rb_entry_first, rb_entry_last, layout) + pagesize;
// Skip gaps between the profiles.
unsigned int gap = 0;
@ -481,6 +494,14 @@ oceanic_common_device_profile (dc_device_t *abstract, dc_event_progress_t *progr
offset -= layout->rb_logbook_entry_size;
memcpy (profiles + offset, logbooks + entry, layout->rb_logbook_entry_size);
// Remove padding from the profile.
if (layout->highmem) {
unsigned char *profile = profiles + offset + layout->rb_logbook_entry_size;
while (rb_entry_size >= PAGESIZE && array_isequal (profile + rb_entry_size - PAGESIZE, PAGESIZE, 0xFF)) {
rb_entry_size -= PAGESIZE;
}
}
unsigned char *p = profiles + offset;
if (callback && !callback (p, rb_entry_size + layout->rb_logbook_entry_size, p, layout->rb_logbook_entry_size, userdata)) {
break;

View File

@ -38,6 +38,7 @@ extern "C" {
typedef struct oceanic_common_layout_t {
// Memory size.
unsigned int memsize;
unsigned int highmem;
// Device info.
unsigned int cf_devinfo;
// Ringbuffer pointers.

View File

@ -75,6 +75,7 @@ static const oceanic_common_version_t oceanic_veo250_version[] = {
static const oceanic_common_layout_t oceanic_veo250_layout = {
0x8000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0400, /* rb_logbook_begin */

View File

@ -89,6 +89,7 @@ static const oceanic_common_version_t oceanic_wisdom_version[] = {
static const oceanic_common_layout_t oceanic_vtpro_layout = {
0x8000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x0240, /* rb_logbook_begin */
@ -103,6 +104,7 @@ static const oceanic_common_layout_t oceanic_vtpro_layout = {
static const oceanic_common_layout_t oceanic_wisdom_layout = {
0x8000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0040, /* cf_pointers */
0x03D0, /* rb_logbook_begin */
@ -117,6 +119,7 @@ static const oceanic_common_layout_t oceanic_wisdom_layout = {
static const oceanic_common_layout_t aeris_500ai_layout = {
0x20000, /* memsize */
0, /* highmem */
0x0000, /* cf_devinfo */
0x0110, /* cf_pointers */
0x0200, /* rb_logbook_begin */