Skip to content

Commit 6884cf7

Browse files
committed
ESP32/SPI: improve error result
Return meaningful tagged tuples instead of just `error` atom. Signed-off-by: Davide Bettio <[email protected]>
1 parent 052dbda commit 6884cf7

File tree

2 files changed

+28
-18
lines changed

2 files changed

+28
-18
lines changed

libs/eavmlib/src/spi.erl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ close(SPI) ->
182182
-spec read_at(
183183
SPI :: spi(), DeviceName :: device_name(), Address :: address(), Len :: non_neg_integer()
184184
) ->
185-
{ok, integer()} | error.
185+
{ok, integer()} | {error, Reason :: term()}.
186186
read_at(SPI, DeviceName, Address, Len) ->
187187
port:call(SPI, {read_at, DeviceName, Address, Len}).
188188

@@ -207,7 +207,7 @@ read_at(SPI, DeviceName, Address, Len) ->
207207
Len :: non_neg_integer(),
208208
Data :: integer()
209209
) ->
210-
{ok, integer()} | error.
210+
{ok, integer()} | {error, Reason :: term()}.
211211
write_at(SPI, DeviceName, Address, Len, Data) ->
212212
port:call(SPI, {write_at, DeviceName, Address bor 16#80, Len, Data}).
213213

@@ -271,7 +271,7 @@ write(SPI, DeviceName, Transaction) when
271271
%% @end
272272
%%-----------------------------------------------------------------------------
273273
-spec write_read(SPI :: spi(), DeviceName :: device_name(), Transaction :: transaction()) ->
274-
{ok, ReadData :: binary()} | error.
274+
{ok, ReadData :: binary()} | {error, Reason :: term()}.
275275
write_read(SPI, DeviceName, Transaction) when
276276
is_pid(SPI) andalso is_atom(DeviceName) andalso is_map(Transaction)
277277
->

src/platforms/esp32/components/avm_builtins/spi_driver.c

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ struct SPIData
7878
};
7979

8080
static NativeHandlerResult spidriver_consume_mailbox(Context *ctx);
81-
static uint32_t spidriver_transfer_at(struct SPIDevice *device, uint64_t address, int data_len, uint32_t data, bool *ok);
81+
static uint32_t spidriver_transfer_at(struct SPIDevice *device, uint64_t address, int data_len, uint32_t data, esp_err_t *err);
8282
static term create_pair(Context *ctx, term term1, term term2);
8383

8484
static const char *const spi_driver_atom = "\xA" "spi_driver";
@@ -266,6 +266,14 @@ static term device_not_found_error(Context *ctx)
266266
return create_pair(ctx, ERROR_ATOM, globalcontext_make_atom(ctx->global, device_not_found_atom));
267267
}
268268

269+
static term esp_err_tuple(esp_err_t err, Context *ctx)
270+
{
271+
if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2)) != MEMORY_GC_OK)) {
272+
return OUT_OF_MEMORY_ATOM;
273+
}
274+
return create_pair(ctx, ERROR_ATOM, esp_err_to_term(ctx->global, err));
275+
}
276+
269277
static term spidriver_close(Context *ctx)
270278
{
271279
TRACE("spidriver_close\n");
@@ -296,7 +304,7 @@ static term spidriver_close(Context *ctx)
296304
return OK_ATOM;
297305
}
298306

299-
static uint32_t spidriver_transfer_at(struct SPIDevice *device, uint64_t address, int data_len, uint32_t data, bool *ok)
307+
static uint32_t spidriver_transfer_at(struct SPIDevice *device, uint64_t address, int data_len, uint32_t data, esp_err_t *err)
300308
{
301309
TRACE("--- SPI transfer ---\n");
302310
TRACE("spi: address: %x, tx: %x\n", (int) address, (int) data);
@@ -313,9 +321,8 @@ static uint32_t spidriver_transfer_at(struct SPIDevice *device, uint64_t address
313321
transaction.tx_data[3] = (tx_data >> 24) & 0xFF;
314322

315323
//TODO: int ret = spi_device_queue_trans(device->handle, &transaction, portMAX_DELAY);
316-
int ret = spi_device_polling_transmit(device->handle, &transaction);
317-
if (UNLIKELY(ret != ESP_OK)) {
318-
*ok = false;
324+
*err = spi_device_polling_transmit(device->handle, &transaction);
325+
if (UNLIKELY(*err != ESP_OK)) {
319326
return 0;
320327
}
321328

@@ -330,7 +337,6 @@ static uint32_t spidriver_transfer_at(struct SPIDevice *device, uint64_t address
330337
TRACE("spi: rx: %x\n", (int) rx_data);
331338
TRACE("--- end of transfer ---\n");
332339

333-
*ok = true;
334340
return SPI_SWAP_DATA_RX(rx_data, data_len);
335341
}
336342

@@ -377,10 +383,10 @@ static term spidriver_read_at(Context *ctx, term req)
377383
avm_int64_t address = term_maybe_unbox_int64(address_term);
378384
avm_int_t data_len = term_to_int(len_term);
379385

380-
bool ok;
381-
uint32_t read_value = spidriver_transfer_at(device, address, data_len, 0, &ok);
382-
if (UNLIKELY(!ok)) {
383-
return ERROR_ATOM;
386+
esp_err_t err;
387+
uint32_t read_value = spidriver_transfer_at(device, address, data_len, 0, &err);
388+
if (UNLIKELY(err != ESP_OK)) {
389+
return esp_err_tuple(err, ctx);
384390
}
385391

386392
return make_read_result_tuple(read_value, ctx);
@@ -406,10 +412,10 @@ static term spidriver_write_at(Context *ctx, term req)
406412
avm_int_t data_len = term_to_int(len_term);
407413
avm_int_t data = term_maybe_unbox_int(data_term);
408414

409-
bool ok;
410-
uint32_t read_value = spidriver_transfer_at(device, address, data_len, data, &ok);
411-
if (UNLIKELY(!ok)) {
412-
return ERROR_ATOM;
415+
esp_err_t err;
416+
uint32_t read_value = spidriver_transfer_at(device, address, data_len, data, &err);
417+
if (UNLIKELY(err != ESP_OK)) {
418+
return esp_err_tuple(err, ctx);
413419
}
414420

415421
return make_read_result_tuple(read_value, ctx);
@@ -616,7 +622,11 @@ static NativeHandlerResult spidriver_consume_mailbox(Context *ctx)
616622

617623
default:
618624
TRACE("spi: error: unrecognized command.\n");
619-
ret = ERROR_ATOM;
625+
if (UNLIKELY(memory_ensure_free(ctx, TUPLE_SIZE(2)) != MEMORY_GC_OK)) {
626+
return OUT_OF_MEMORY_ATOM;
627+
}
628+
term unkn_a = globalcontext_make_atom(ctx->global, ATOM_STR("\xF", "unknown_command"));
629+
return create_pair(ctx, ERROR_ATOM, esp_err_to_term(ctx->global, unkn_a));
620630
}
621631

622632
term ret_msg;

0 commit comments

Comments
 (0)