Hace poco pregunté sobre esto en la pila de Arduino, pero era una pregunta amplia, y he avanzado y acotado los problemas.
Tengo dos Arduino Nano's, cada uno conectado a un DWM1000. Esto es en una tabla de ruptura personalizada y una placa de pruebas. Aquí hay una biblioteca Arduino DWM1000 que utilizo para probar con los tableros. Los bocetos básicos de tx / rx funcionan perfectamente y pueden enviar mensajes de ping-pong.
Esta biblioteca no está completa y necesito más funciones avanzadas para un proyecto en el que estoy trabajando. Así que DecaWave (el fabricante del DWM1000) tiene un controlador completamente escrito para él: (Interfaz de programación de aplicaciones DW1000 con STM32F10x Ejemplos de aplicaciones) Porté las funciones necesarias para usar el chip ATmega.
Al usar el controlador DecaWave, puedo leer / escribir todos los registros pero tengo problemas con los ejemplos básicos de tx / rx. Parece que la transmisión no se está enviando correctamente. Puedo enviar código desde mi única placa utilizando el ejemplo de la biblioteca Arduino, y recibirlo con el ejemplo de rx básico de DecaWave sin errores.
Si envío desde el ejemplo de DecaWave basic tx, y lo recibo del ejemplo de DecaWave basic rx, lo recibo, pero con errores.
A veces estos bits se establecen:
CPLOCK, RXPRD, RXSFDD, RXPHE, SLP2INIT, CLKPLL_LL
Otras veces, estos están configurados:
CPLOCK, RXPRD, RXSFDD, RXPHD, RXRFSL, SLP2INIT, CLKPLL_LL
A partir del código de envío, se establecen los bits apropiados ( TXFRB, TXPRS, TXPHS, TXFRS
)
El código de mi controlador DecaWave:
#include <Arduino.h>
#include <SPI.h>
#include <prescaler.h>
#include <deca_device_api.h>
#include <deca_regs.h>
//#include "DW1000.h"
//#include "usart.h"
static dwt_config_t config = {
5, /* Channel number. */
DWT_PRF_16M, /* Pulse repetition frequency. */
DWT_PLEN_1024, /* Preamble length. Used in TX only. */
DWT_PAC32, /* Preamble acquisition chunk size. Used in RX only. */
4, /* TX preamble code. Used in TX only. */
4, /* RX preamble code. Used in RX only. */
0, /* 0 to use standard SFD, 1 to use non-standard SFD. */
DWT_BR_110K, /* Data rate. */
DWT_PHRMODE_STD, /* PHY header mode. */
(1025 + 64 - 32) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
};
static uint8 tx_msg[] = {0xC5, 0, 'D', 'E', 'C', 'A', 'W', 'A', 'V', 'E', 0, 0};
/* Index to access to sequence number of the blink frame in the tx_msg array. */
#define BLINK_FRAME_SN_IDX 1
/* Inter-frame delay period, in milliseconds. */
#define TX_DELAY_MS 1000
void reset_DW1000()
{
digitalWrite(5, LOW);
pinMode(5, OUTPUT);
delay(10);
pinMode(5, INPUT);
delay(10);
}
void setup()
{
SPI.begin();
Serial.begin(9600);
while (!Serial) { ; };
delay(50);
reset_DW1000();
setClockPrescaler(CLOCK_PRESCALER_8);
if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR)
{
setClockPrescaler(CLOCK_PRESCALER_1);
Serial.println("INIT FAILED");
while (1)
{ };
}
setClockPrescaler(CLOCK_PRESCALER_1);
dwt_configure(&config);
}
void loop()
{
/* Write frame data to DW1000 and prepare transmission. See NOTE 4 below.*/
dwt_writetxdata(sizeof(tx_msg), tx_msg, 0); /* Zero offset in TX buffer. */
dwt_writetxfctrl(sizeof(tx_msg), 0, 0); /* Zero offset in TX buffer, no ranging. */
/* Start transmission. */
dwt_starttx(DWT_START_TX_IMMEDIATE);
while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
{ };
/* Clear TX frame sent event. */
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
/* Execute a delay between transmissions. */
delay(TX_DELAY_MS);
/* Increment the blink frame sequence number (modulo 256). */
tx_msg[BLINK_FRAME_SN_IDX]++;
}
Mi código DecaWave rx rx:
#include <Arduino.h>
#include <SPI.h>
#include <prescaler.h>
#include <deca_device_api.h>
#include <deca_regs.h>
//#include "USART.h"
/*! ----------------------------------------------------------------------------
* @file main.c
* @brief Simple RX example code
*
* @attention
*
* Copyright 2015 (c) Decawave Ltd, Dublin, Ireland.
*
* All rights reserved.
*
* @author Decawave
*/
static dwt_config_t config = {
5, /* Channel number. */
DWT_PRF_16M, /* Pulse repetition frequency. */
DWT_PLEN_1024, /* Preamble length. Used in TX only. */
DWT_PAC32, /* Preamble acquisition chunk size. Used in RX only. */
4, /* TX preamble code. Used in TX only. */
4, /* RX preamble code. Used in RX only. */
0, /* 0 to use standard SFD, 1 to use non-standard SFD. */
DWT_BR_110K, /* Data rate. */
DWT_PHRMODE_STD, /* PHY header mode. */
(1025 + 64 - 32) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
};
#define FRAME_LEN_MAX 127
static uint8 rx_buffer[FRAME_LEN_MAX];
static uint32 status_reg = 0;
static uint16 frame_len = 0;
void reset_DW1000()
{
digitalWrite(5, LOW);
pinMode(5, OUTPUT);
delay(10);
pinMode(5, INPUT);
delay(10);
}
void debug_register(uint16_t reg, uint8_t len)
{
uint8_t ar[len];
dwt_readfromdevice (reg, 0, len, ar) ;
for (int i=0; i<len; i++)
{
Serial.print(i); Serial.print(" = "); Serial.println(ar[i]);
}
}
void setup()
{
SPI.begin();
Serial.begin(9600);
//initUSART();
while (!Serial) { ; };
delay(50);
Serial.println("Hi hello hi hello fdaffasd?");
reset_DW1000();
setClockPrescaler(CLOCK_PRESCALER_8);
if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR)
{
setClockPrescaler(CLOCK_PRESCALER_1);
Serial.println("INIT FAILED");
while (1)
{ };
}
setClockPrescaler(CLOCK_PRESCALER_1);
delay(50);
dwt_configure(&config);
}
void loop()
{
int i;
for (i = 0 ; i < FRAME_LEN_MAX; i++ )
{
rx_buffer[i] = 0;
}
dwt_rxenable(DWT_START_RX_IMMEDIATE);
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR))) { ; }
if (status_reg & SYS_STATUS_RXFCG)
{
frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;
if (frame_len <= FRAME_LEN_MAX)
{
dwt_readrxdata(rx_buffer, frame_len, 0);
}
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
}
else
{
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
}
}
EDITAR: Entonces, me está costando mucho pensar que es algo de mi parte, y ahora, ¿puedo pensar que podría haber algún problema con el controlador? Al menos con el dwm1000 específicamente.
Ahora tengo dos DWM1000s conectados con STM32s. Ahora estoy usando la arquitectura de tablero para la cual fue diseñada la api. Tengo exactamente los mismos resultados ...
Si comento el mensaje "dwt_configure (& config);" Soy capaz de recibir mensajes con los bits de error mencionados anteriormente, el rx stm32 imprime "err".
Si utilizo cualquier configuración, nunca recibo ningún mensaje.
Estos módulos aún funcionan bien usando la biblioteca arduino, así que no hay nada de malo en ellos, y tengo 4 módulos que he probado con cada uno.
Por favor, si alguien tiene alguna sugerencia, hágamelo saber. Si no, parece que me moveré a un nuevo chip UWB.
¡Gracias!
Código tx STM32:
#include <mbed.h>
#include "decadriver/deca_device_api.h"
#include "decadriver/deca_regs.h"
static dwt_config_t config = {
2, /* Channel number. */
DWT_PRF_64M, /* Pulse repetition frequency. */
DWT_PLEN_1024, /* Preamble length. Used in TX only. */
DWT_PAC32, /* Preamble acquisition chunk size. Used in RX only. */
9, /* TX preamble code. Used in TX only. */
9, /* RX preamble code. Used in RX only. */
1, /* 0 to use standard SFD, 1 to use non-standard SFD. */
DWT_BR_110K, /* Data rate. */
DWT_PHRMODE_STD, /* PHY header mode. */
(1025 + 64 - 32) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
};
DigitalOut myled(PC_13);
static uint8 tx_msg[] = {0xC5, 0, 'D', 'E', 'C', 'A', 'W', 'A', 'V', 'E', 0, 0};
#define BLINK_FRAME_SN_IDX 1
#define TX_DELAY_MS 1000
DigitalInOut pin_rst(PA_10);
void reset_DW1000()
{
pin_rst.write(0);
wait(0.01);
pin_rst.write(1);
}
int main(void)
{
myled = 0;
Serial serial(PB_6, PB_7);
wait(0.5);
serial.baud(9600);
pin_rst.output();
pin_rst.mode(OpenDrain);
SPI bus(PA_7, PA_6, PA_5);//mosi, miso, clk
serial.printf("Device ID: %u\r\n", dwt_readdevid());
reset_DW1000();
bus.frequency(2000000);
if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR)
{
serial.printf("Error on init11\n\r");
while (1) { ; };
}
bus.frequency(20000000);
//dwt_configure(&config);
while(1)
{
dwt_writetxdata(sizeof(tx_msg), tx_msg, 0); /* Zero offset in TX buffer. */
dwt_writetxfctrl(sizeof(tx_msg), 0, 0); /* Zero offset in TX buffer, no ranging. */
dwt_starttx(DWT_START_TX_IMMEDIATE);
while (!(dwt_read32bitreg(SYS_STATUS_ID) & SYS_STATUS_TXFRS))
{ };
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_TXFRS);
myled = 1;
wait(1);
myled = 0;
tx_msg[BLINK_FRAME_SN_IDX]++;
}
}
STM32 código rx:
#include <mbed.h>
#include "decadriver/deca_device_api.h"
#include "decadriver/deca_regs.h"
static dwt_config_t config = {
2, /* Channel number. */
DWT_PRF_64M, /* Pulse repetition frequency. */
DWT_PLEN_1024, /* Preamble length. Used in TX only. */
DWT_PAC32, /* Preamble acquisition chunk size. Used in RX only. */
9, /* TX preamble code. Used in TX only. */
9, /* RX preamble code. Used in RX only. */
1, /* 0 to use standard SFD, 1 to use non-standard SFD. */
DWT_BR_110K, /* Data rate. */
DWT_PHRMODE_STD, /* PHY header mode. */
(1025 + 64 - 32) /* SFD timeout (preamble length + 1 + SFD length - PAC size). Used in RX only. */
};
#define FRAME_LEN_MAX 127
static uint8 rx_buffer[FRAME_LEN_MAX];
static uint32 status_reg = 0;
static uint16 frame_len = 0;
DigitalInOut pin_rst(PA_10);
void reset_DW1000()
{
pin_rst.write(0);
wait(0.01);
pin_rst.write(1);
}
int main(void)
{
//myled = 0;
Serial serial(PB_6, PB_7);
wait(0.5);
serial.baud(9600);
pin_rst.output();
pin_rst.mode(OpenDrain);
SPI bus(PA_7, PA_6, PA_5);//mosi, miso, clk
serial.printf("Device ID: %u\r\n", dwt_readdevid());
reset_DW1000();
bus.frequency(2000000);
if (dwt_initialise(DWT_LOADNONE) == DWT_ERROR)
{
serial.printf("Error on init11\n\r");
while (1) { ; };
}
bus.frequency(20000000);
//dwt_configure(&config);
while(1)
{
int i;
for (i = 0 ; i < FRAME_LEN_MAX; i++ )
{
rx_buffer[i] = 0;
}
dwt_rxenable(DWT_START_RX_IMMEDIATE);
while (!((status_reg = dwt_read32bitreg(SYS_STATUS_ID)) & (SYS_STATUS_RXFCG | SYS_STATUS_ALL_RX_ERR))) { ; }
if (status_reg & SYS_STATUS_RXFCG)
{
frame_len = dwt_read32bitreg(RX_FINFO_ID) & RX_FINFO_RXFL_MASK_1023;
if (frame_len <= FRAME_LEN_MAX)
{
dwt_readrxdata(rx_buffer, frame_len, 0);
for(int s=0; s<frame_len-3; s++)
{
serial.printf("%c", rx_buffer[s]);
}
serial.printf("\r\n");
}
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_RXFCG);
}
else
{
dwt_write32bitreg(SYS_STATUS_ID, SYS_STATUS_ALL_RX_ERR);
serial.printf("Err\r\n");
}
}
}