Skip to content
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
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ var implementation = generator.GenerateImplementation();

## Generating Python interface code

Assuming the `deviceMetadata` object loaded above is available, a Python interface targeting the [pyharp](https://github.com/harp-tech/pyharp) register and payload API can be generated from the same metadata.
Assuming the `deviceMetadata` object loaded above is available, an interface targeting [Harp Python](https://harp-tech.org/python) can be generated from the same metadata.

```csharp
...
Expand Down
4 changes: 2 additions & 2 deletions src/Python.cs
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ static PythonField BuildPythonField(
if (string.IsNullOrEmpty(member.InterfaceType))
{
module.ProtocolImports.Add("IdentityConverter");
if (memberLength > 1)
if (memberLength > 0)
{
module.UsesNDArray = true;
return new PythonField
Expand Down Expand Up @@ -524,7 +524,7 @@ static string GetMemberAnnotation(PayloadMemberInfo member, RegisterInfo registe
static string GetPythonDefaultArgument(PayloadMemberInfo member, string typeName, RegisterInfo register, DeviceInfo deviceMetadata)
{
var defaultValue = member.DefaultValue ?? member.MinValue;
if (!defaultValue.HasValue || member.Length > 1)
if (!defaultValue.HasValue || member.Length > 0)
return string.Empty;

var value = defaultValue.GetValueOrDefault();
Expand Down
60 changes: 60 additions & 0 deletions tests/ExpectedOutput/device.app_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ void (*app_func_rd_pointer[])(void) = {
&app_read_REG_PORT_DIO_SET,
&app_read_REG_PULSE_DO_PORT0,
&app_read_REG_PULSE_DO0,
&app_read_REG_MULTI_ELEMENT_PAYLOAD,
&app_read_REG_SINGLE_ELEMENT_PAYLOAD,
&app_read_REG_MIXED_MEMBER_LENGTH,
&app_read_REG_START_PULSE,
&app_read_REG_START_PULSE_TRAIN,
&app_read_REG_ENCODER_MODE
Expand All @@ -39,6 +42,9 @@ bool (*app_func_wr_pointer[])(void*) = {
&app_write_REG_PORT_DIO_SET,
&app_write_REG_PULSE_DO_PORT0,
&app_write_REG_PULSE_DO0,
&app_write_REG_MULTI_ELEMENT_PAYLOAD,
&app_write_REG_SINGLE_ELEMENT_PAYLOAD,
&app_write_REG_MIXED_MEMBER_LENGTH,
&app_write_REG_START_PULSE,
&app_write_REG_START_PULSE_TRAIN,
&app_write_REG_ENCODER_MODE
Expand Down Expand Up @@ -212,6 +218,60 @@ bool app_write_REG_PULSE_DO0(void *a)
return true;
}

/************************************************************************/
/* REG_MULTI_ELEMENT_PAYLOAD */
/************************************************************************/
// This register is an array with 3 positions
void app_read_REG_MULTI_ELEMENT_PAYLOAD(void)
{
//app_regs.REG_MULTI_ELEMENT_PAYLOAD[0] = 0;

}

bool app_write_REG_MULTI_ELEMENT_PAYLOAD(void *a)
{
uint16_t *reg = ((uint16_t*)a);

app_regs.REG_MULTI_ELEMENT_PAYLOAD[0] = reg[0];
return true;
}

/************************************************************************/
/* REG_SINGLE_ELEMENT_PAYLOAD */
/************************************************************************/
// This register is an array with 1 positions
void app_read_REG_SINGLE_ELEMENT_PAYLOAD(void)
{
//app_regs.REG_SINGLE_ELEMENT_PAYLOAD[0] = 0;

}

bool app_write_REG_SINGLE_ELEMENT_PAYLOAD(void *a)
{
uint16_t *reg = ((uint16_t*)a);

app_regs.REG_SINGLE_ELEMENT_PAYLOAD[0] = reg[0];
return true;
}

/************************************************************************/
/* REG_MIXED_MEMBER_LENGTH */
/************************************************************************/
// This register is an array with 4 positions
void app_read_REG_MIXED_MEMBER_LENGTH(void)
{
//app_regs.REG_MIXED_MEMBER_LENGTH[0] = 0;

}

bool app_write_REG_MIXED_MEMBER_LENGTH(void *a)
{
uint8_t *reg = ((uint8_t*)a);

app_regs.REG_MIXED_MEMBER_LENGTH[0] = reg[0];
return true;
}

/************************************************************************/
/* REG_START_PULSE */
/************************************************************************/
Expand Down
6 changes: 6 additions & 0 deletions tests/ExpectedOutput/device.app_funcs.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ void app_read_REG_COUNTER0(void);
void app_read_REG_PORT_DIO_SET(void);
void app_read_REG_PULSE_DO_PORT0(void);
void app_read_REG_PULSE_DO0(void);
void app_read_REG_MULTI_ELEMENT_PAYLOAD(void);
void app_read_REG_SINGLE_ELEMENT_PAYLOAD(void);
void app_read_REG_MIXED_MEMBER_LENGTH(void);
void app_read_REG_START_PULSE(void);
void app_read_REG_START_PULSE_TRAIN(void);
void app_read_REG_ENCODER_MODE(void);
Expand All @@ -48,6 +51,9 @@ bool app_write_REG_COUNTER0(void *a);
bool app_write_REG_PORT_DIO_SET(void *a);
bool app_write_REG_PULSE_DO_PORT0(void *a);
bool app_write_REG_PULSE_DO0(void *a);
bool app_write_REG_MULTI_ELEMENT_PAYLOAD(void *a);
bool app_write_REG_SINGLE_ELEMENT_PAYLOAD(void *a);
bool app_write_REG_MIXED_MEMBER_LENGTH(void *a);
bool app_write_REG_START_PULSE(void *a);
bool app_write_REG_START_PULSE_TRAIN(void *a);
bool app_write_REG_ENCODER_MODE(void *a);
Expand Down
9 changes: 9 additions & 0 deletions tests/ExpectedOutput/device.app_ios_and_regs.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ uint8_t app_regs_type[] = {
TYPE_U16,
TYPE_U16,
TYPE_U16,
TYPE_U8,
TYPE_U16,
TYPE_U16,
TYPE_U8
};

Expand All @@ -94,6 +97,9 @@ uint16_t app_regs_n_elements[] = {
1,
1,
1,
3,
1,
4,
1,
2,
1
Expand All @@ -112,6 +118,9 @@ uint8_t *app_regs_pointer[] = {
(uint8_t*)(&app_regs.REG_PORT_DIO_SET),
(uint8_t*)(&app_regs.REG_PULSE_DO_PORT0),
(uint8_t*)(&app_regs.REG_PULSE_DO0),
(uint8_t*)(&app_regs.REG_MULTI_ELEMENT_PAYLOAD),
(uint8_t*)(&app_regs.REG_SINGLE_ELEMENT_PAYLOAD),
(uint8_t*)(&app_regs.REG_MIXED_MEMBER_LENGTH),
(uint8_t*)(&app_regs.REG_START_PULSE),
(uint8_t*)(&app_regs.REG_START_PULSE_TRAIN),
(uint8_t*)(&app_regs.REG_ENCODER_MODE)
Expand Down
8 changes: 7 additions & 1 deletion tests/ExpectedOutput/device.app_ios_and_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ typedef struct
uint8_t REG_PORT_DIO_SET;
uint16_t REG_PULSE_DO_PORT0;
uint16_t REG_PULSE_DO0;
uint16_t REG_MULTI_ELEMENT_PAYLOAD[3];
uint16_t REG_SINGLE_ELEMENT_PAYLOAD[1];
uint8_t REG_MIXED_MEMBER_LENGTH[4];
uint16_t REG_START_PULSE;
uint16_t REG_START_PULSE_TRAIN[2];
uint8_t REG_ENCODER_MODE;
Expand All @@ -164,6 +167,9 @@ typedef struct
#define ADD_REG_PORT_DIO_SET 41 // U8
#define ADD_REG_PULSE_DO_PORT0 42 // U16
#define ADD_REG_PULSE_DO0 43 // U16
#define ADD_REG_MULTI_ELEMENT_PAYLOAD 44 // U16
#define ADD_REG_SINGLE_ELEMENT_PAYLOAD 45 // U16
#define ADD_REG_MIXED_MEMBER_LENGTH 46 // U8
#define ADD_REG_START_PULSE 100 // U16 Starts a PWM pulse.
#define ADD_REG_START_PULSE_TRAIN 101 // U16 Starts a PWM pulse train.
#define ADD_REG_ENCODER_MODE 103 // U8 Configures the operation mode of the encoder.
Expand All @@ -177,7 +183,7 @@ typedef struct
/* Memory limits */
#define APP_REGS_ADD_MIN 0x20
#define APP_REGS_ADD_MAX 0x67
#define APP_NBYTES_OF_REG_BANK 118
#define APP_NBYTES_OF_REG_BANK 130

/************************************************************************/
/* Registers' bits */
Expand Down
138 changes: 138 additions & 0 deletions tests/ExpectedOutput/device.async.cs
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,144 @@ public async Task WritePulseDO0Async(ushort value, CancellationToken cancellatio
await CommandAsync(request, cancellationToken);
}

/// <summary>
/// Asynchronously reads the contents of the <see cref="MultiElementPayload"/> register.
/// </summary>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>
/// A task that represents the asynchronous read operation. The task result contains
/// the register payload.
/// </returns>
public async Task<ushort[]> ReadMultiElementPayloadAsync(CancellationToken cancellationToken = default)
{
var reply = await CommandAsync(HarpCommand.ReadUInt16(MultiElementPayload.Address), cancellationToken);
return MultiElementPayload.GetPayload(reply);
}

/// <summary>
/// Asynchronously reads the timestamped contents of the <see cref="MultiElementPayload"/> register.
/// </summary>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>
/// A task that represents the asynchronous read operation. The task result contains
/// the timestamped register payload.
/// </returns>
public async Task<Timestamped<ushort[]>> ReadTimestampedMultiElementPayloadAsync(CancellationToken cancellationToken = default)
{
var reply = await CommandAsync(HarpCommand.ReadUInt16(MultiElementPayload.Address), cancellationToken);
return MultiElementPayload.GetTimestampedPayload(reply);
}

/// <summary>
/// Asynchronously writes a value to the <see cref="MultiElementPayload"/> register.
/// </summary>
/// <param name="value">The value to write in the register.</param>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>The task object representing the asynchronous write operation.</returns>
public async Task WriteMultiElementPayloadAsync(ushort[] value, CancellationToken cancellationToken = default)
{
var request = MultiElementPayload.FromPayload(MessageType.Write, value);
await CommandAsync(request, cancellationToken);
}

/// <summary>
/// Asynchronously reads the contents of the <see cref="SingleElementPayload"/> register.
/// </summary>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>
/// A task that represents the asynchronous read operation. The task result contains
/// the register payload.
/// </returns>
public async Task<ushort[]> ReadSingleElementPayloadAsync(CancellationToken cancellationToken = default)
{
var reply = await CommandAsync(HarpCommand.ReadUInt16(SingleElementPayload.Address), cancellationToken);
return SingleElementPayload.GetPayload(reply);
}

/// <summary>
/// Asynchronously reads the timestamped contents of the <see cref="SingleElementPayload"/> register.
/// </summary>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>
/// A task that represents the asynchronous read operation. The task result contains
/// the timestamped register payload.
/// </returns>
public async Task<Timestamped<ushort[]>> ReadTimestampedSingleElementPayloadAsync(CancellationToken cancellationToken = default)
{
var reply = await CommandAsync(HarpCommand.ReadUInt16(SingleElementPayload.Address), cancellationToken);
return SingleElementPayload.GetTimestampedPayload(reply);
}

/// <summary>
/// Asynchronously writes a value to the <see cref="SingleElementPayload"/> register.
/// </summary>
/// <param name="value">The value to write in the register.</param>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>The task object representing the asynchronous write operation.</returns>
public async Task WriteSingleElementPayloadAsync(ushort[] value, CancellationToken cancellationToken = default)
{
var request = SingleElementPayload.FromPayload(MessageType.Write, value);
await CommandAsync(request, cancellationToken);
}

/// <summary>
/// Asynchronously reads the contents of the <see cref="MixedMemberLength"/> register.
/// </summary>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>
/// A task that represents the asynchronous read operation. The task result contains
/// the register payload.
/// </returns>
public async Task<MixedMemberLengthPayload> ReadMixedMemberLengthAsync(CancellationToken cancellationToken = default)
{
var reply = await CommandAsync(HarpCommand.ReadByte(MixedMemberLength.Address), cancellationToken);
return MixedMemberLength.GetPayload(reply);
}

/// <summary>
/// Asynchronously reads the timestamped contents of the <see cref="MixedMemberLength"/> register.
/// </summary>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>
/// A task that represents the asynchronous read operation. The task result contains
/// the timestamped register payload.
/// </returns>
public async Task<Timestamped<MixedMemberLengthPayload>> ReadTimestampedMixedMemberLengthAsync(CancellationToken cancellationToken = default)
{
var reply = await CommandAsync(HarpCommand.ReadByte(MixedMemberLength.Address), cancellationToken);
return MixedMemberLength.GetTimestampedPayload(reply);
}

/// <summary>
/// Asynchronously writes a value to the <see cref="MixedMemberLength"/> register.
/// </summary>
/// <param name="value">The value to write in the register.</param>
/// <param name="cancellationToken">
/// A <see cref="CancellationToken"/> which can be used to cancel the operation.
/// </param>
/// <returns>The task object representing the asynchronous write operation.</returns>
public async Task WriteMixedMemberLengthAsync(MixedMemberLengthPayload value, CancellationToken cancellationToken = default)
{
var request = MixedMemberLength.FromPayload(MessageType.Write, value);
await CommandAsync(request, cancellationToken);
}

/// <summary>
/// Asynchronously reads the contents of the <see cref="StartPulse"/> register.
/// </summary>
Expand Down
Loading
Loading