while (1)
{
if(FlagEnviar==0)
{
struct io_descriptor *io;
usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB, usart_read_callback);
usart_async_get_io_descriptor(&USART_0, &io);
usart_async_enable(&USART_0);
io_read(io, buf, USART_BUF_SIZE);
}
else
{
struct io_descriptor *io2;
usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, usart_write_callback);
usart_async_get_io_descriptor(&USART_0, &io2);
usart_async_enable(&USART_0);
io_write(io2, buf2, 3);
}
}void USART_0_init(void)
{
USART_0_CLOCK_init();
USART_0_PORT_init();
usart_async_init(&USART_0, FLEXCOM0, USART_0_buffer, USART_0_BUFFER_SIZE, _usart_get_usart_async());
}void usart_read_callback(const struct usart_async_descriptor *const descr)
{
BufferRecepcion[DatosRecibidos]=REG_USART0_US_RHR;
DatosRecibidos++;
if(DatosRecibidos == 5)
{
FlagEnviar=1;
DatosRecibidos = 0; // Reset received data counter
}
}#include <atmel_start.h>
#define USART_BUF_SIZE 5
static unsigned int Contador=0;
struct io_descriptor *usart_io;
uint8_t buf[USART_BUF_SIZE];
uint8_t buf2[USART_BUF_SIZE]={1,2,3,4,5};
uint8_t data_received;
uint8_t BufferRecepcion[5];
static unsigned char DatosRecibidos=0;
bool FlagEnviar=0;
void usart_read_callback(const struct usart_async_descriptor *const descr)
{
BufferRecepcion[DatosRecibidos]=REG_USART0_US_RHR;
DatosRecibidos++;
if(DatosRecibidos == 5)
{
FlagEnviar=1;
DatosRecibidos = 0; // Reset received data counter
}
}
void usart_write_callback(const struct usart_async_descriptor *const descr)
{
}
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
gpio_set_pin_level(DE485,true);
while (1)
{
if(FlagEnviar==0)
{
struct io_descriptor *io;
usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB, usart_read_callback);
usart_async_get_io_descriptor(&USART_0, &io);
usart_async_enable(&USART_0);
io_read(io, buf, USART_BUF_SIZE);
}
else
{
struct io_descriptor *io2;
usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, usart_write_callback);
usart_async_get_io_descriptor(&USART_0, &io2);
usart_async_enable(&USART_0);
Contador=io_write(io2, buf2, 3);
Contador=Contador+1-1;
}
}
}
/*! The buffer size for USART */
#define USART_0_BUFFER_SIZE 16
struct usart_async_descriptor USART_0;
static uint8_t USART_0_buffer[USART_0_BUFFER_SIZE];
/**
* \brief USART pinmux initialization function
*
* Set each required pin to USART functionality
*/
void USART_0_PORT_init()
{
gpio_set_pin_function(PA9, MUX_PA9A_FLEXCOM0_RXD);
gpio_set_pin_function(PA10, MUX_PA10A_FLEXCOM0_TXD);
}
/**
* \brief USART initialization function
*
* Enables USART peripheral, clocks and initializes USART driver
*/
void USART_0_init(void)
{
USART_0_CLOCK_init();
USART_0_PORT_init();
usart_async_init(&USART_0, FLEXCOM0, USART_0_buffer, USART_0_BUFFER_SIZE, _usart_get_usart_async());
}
void system_init(void)
{
init_mcu();
_pmc_enable_periph_clock(ID_PIOA);
_pmc_enable_periph_clock(ID_PIOB);
/* Disable Watchdog */
hri_wdt_set_MR_WDDIS_bit(WDT);
USART_0_init();
}
Si es muy rara la librería de los Atmel
25.2.1.1 io_descriptor Struct
I/O descriptor.
Members
write
read The write function pointer
38.2.3.1 Concurrency
• The write buffer should not be changed while data is being sent
y no solo eso, si no que salta la interrupción de recepción cada vez que se envía un dato
The driver convention for asynchronous vector in ASFv4 can in some cases differ from the ASFv3 convention. In cases where data is received asynchronously, for instance over USART, from an ADC, or in I2C/SPI slave mode, ASFv3 requires the application to anticipate the data length and prepare a buffer for reception or else data will be lost. When enough data is received to fill the preallocated buffer a callback is triggered to let the application know that the buffer is full.
In ASFv4 this behavior has been changed to avoid loosing data when for instance switching buffers. Such drivers in ASFv4 has an internal ring buffer to store all received data. When this buffer is full it will start to overwrite the oldest data. The read function will read data from the ring buffer and not directly from the peripheral as in ASFv3. In ASFv3 the length parameter in the read function tells the driver how much data the application wants before being notified through a callback. In ASFv4 the length parameter tells the driver how much data the buffer can take, the read function will return as much data as is available in the ring buffer up to the length, and the return variable of the function returns the size of the data actually copied into the buffer. In ASFv4 a data reception type callback in a driver with a ring buffer is triggered for every received data.
Por que tenes esto en el while?, me suena a inicializacion de seguro.
Creo que en la trsmision si es cuando se completa todo. Y en la transmision no usa el buffer
#include <atmel_start.h>
static uint8_t example_USART[12] = "Hello World!";
static unsigned int ContadorEnviado=0,ContadorRecibido=0,ContadorError=0;
static void tx_cb_USART(const struct usart_async_descriptor *const io_descr)
{
/* Transfer completed */
ContadorEnviado++;
}
static void rx_cb_USART(const struct usart_async_descriptor *const io_descr)
{
/* Transfer completed */
ContadorRecibido++;
}
static void err_cb_USART(const struct usart_async_descriptor *const io_descr)
{
/* Transfer completed */
ContadorError++;
}
int main(void)
{
/* Initializes MCU, drivers and middleware */
atmel_start_init();
struct io_descriptor *io_usart;
usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, tx_cb_USART);
usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB, rx_cb_USART);
usart_async_register_callback(&USART_0, USART_ASYNC_ERROR_CB, err_cb_USART);
usart_async_get_io_descriptor(&USART_0, &io_usart);
usart_async_enable(&USART_0);
/* Replace with your application code */
while (1)
{
io_write(io_usart, example_USART, 12);
}
}usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, tx_cb_USART);static void _usart_interrupt_handler(struct _usart_async_device *device)
{
ASSERT(device);
void *hw = device->hw;
if (hri_usart_get_US_CSR_TXRDY_bit(hw) && hri_usart_get_US_IMR_TXRDY_bit(hw)) {
hri_usart_clear_US_IMR_TXRDY_bit(hw);
device->usart_cb.tx_byte_sent(device);
} else if (hri_usart_get_US_CSR_TXEMPTY_bit(hw) && hri_usart_get_US_IMR_TXEMPTY_bit(hw)) {
hri_usart_clear_US_IMR_TXEMPTY_bit(hw);
device->usart_cb.tx_done_cb(device);
} else if (hri_usart_get_US_CSR_RXRDY_bit(hw) && hri_usart_get_US_IMR_RXRDY_bit(hw)) {
if (hri_usart_read_US_CSR_reg(hw) & (US_CSR_OVRE | US_CSR_FRAME | US_CSR_PARE)) {
hri_usart_read_US_RHR_reg(hw);
hri_usart_write_US_CR_reg(hw, US_CR_RSTSTA);
return;
}
device->usart_cb.rx_done_cb(device, (uint8_t)hri_usart_read_US_RHR_reg(hw));
} else if (hri_usart_read_US_CSR_reg(hw) & (US_CSR_OVRE | US_CSR_FRAME | US_CSR_PARE)) {
hri_usart_write_US_CR_reg(hw, US_CR_RSTSTA);
device->usart_cb.error_cb(device);
}
}Esto es incrible he seguido el call stack a ver por que llama a la función de recepción y no a la de envío,
Encima intente buscar el codigo fuente del ASFv4 y no esta online , tenes que bajarte el IDE completo casi 900MB para poder inspeccionar la fuente. Pero me imagino que la fuente es correcta, pero iba a dar una idea de que estabamos haciendo mal al menos.dime si quieres ver algo y te lo paso, por que yo no veo nada raro en la fuente, simplemente que no se actualizan correctamente los bit del registro de estado :?
unsigned int ContadorInterrupcion=0,ContadorTXRDY=0, ContadorTXEMPTY=0, ContadorRXRDY=0, Contador4=0;estas son las iteraciones y los valores de los Contadores, es decir cada vez que se para en el breakpoint:
static void _usart_interrupt_handler(struct _usart_async_device *device)
{
ASSERT(device);
void *hw = device->hw;
ContadorInterrupcion++;
if (hri_usart_get_US_CSR_TXRDY_bit(hw) && hri_usart_get_US_IMR_TXRDY_bit(hw))
{
ContadorTXRDY++;
hri_usart_clear_US_IMR_TXRDY_bit(hw);
device->usart_cb.tx_byte_sent(device);
device->usart_cb.tx_done_cb(device);
}
else if (hri_usart_get_US_CSR_TXEMPTY_bit(hw) && hri_usart_get_US_IMR_TXEMPTY_bit(hw))
{
ContadorTXEMPTY++;
hri_usart_clear_US_IMR_TXEMPTY_bit(hw);
}
else if (hri_usart_get_US_CSR_RXRDY_bit(hw) && hri_usart_get_US_IMR_RXRDY_bit(hw))
{
ContadorRXRDY++;
if (hri_usart_read_US_CSR_reg(hw) & (US_CSR_OVRE | US_CSR_FRAME | US_CSR_PARE))
{
hri_usart_read_US_RHR_reg(hw);
hri_usart_write_US_CR_reg(hw, US_CR_RSTSTA);
return;
}
device->usart_cb.rx_done_cb(device, (uint8_t)hri_usart_read_US_RHR_reg(hw));
}
else if (hri_usart_read_US_CSR_reg(hw) & (US_CSR_OVRE | US_CSR_FRAME | US_CSR_PARE))
{
Contador4++;
hri_usart_write_US_CR_reg(hw, US_CR_RSTSTA);
device->usart_cb.error_cb(device);
}
}
else if (hri_usart_get_US_CSR_TXEMPTY_bit(hw) && hri_usart_get_US_IMR_TXEMPTY_bit(hw)) Yo no conteste mas porque realmente no se porque estaba ocurriendo, la idea es ver si sin usar el debugger funciona, es decir que sea independiente de la computadora.
Porque suena a un error como del debugger ( en step funciona y corriendo no). La otra es ir directamente al foro del fabricante y exponer lo sucedido, allí alguien debería darte la solución. O darte aunque sea el porque no funciona.
¿ Has probado a desactivar la optimización en la compilación ?, con un objeto optimizado, incluso al nivel más bajo, el Debug puede hacer cosas raras, lo he sufrido y es de locos.
En última instancia, depura encendiendo un Led con un IF, eso no falla nunca, por muy optimizado que esté el objeto.
ASF4 does not assign a specific priority to the IRQs, but instead uses the default priority as assigned by
the NVIC. Different ARM cores have NVIC interrupt controllers with individual specifications and features.
Refer to the device data sheet and NVIC documentation for the ARM core being used in the selected
target device for more information on manipulating interrupt priorities and masking interrupts.
Obviamente el codigo puede cambiar, porque esto lo encontre para un SAM21, pero creo que deberia ser igual para todos. Tambien veo que en ningun momento asigna prioridad. En otras API como el de ST y de TI te proveen una funcion para modificar/habilitar/deshabilitar