TODOPIC

Otros Microcontroladores / Dispositivos programables => Microcontroladores ARM => Mensaje iniciado por: juaperser1 en 01 de Mayo de 2018, 14:44:06

Título: USART ATMEL SAM
Publicado por: juaperser1 en 01 de Mayo de 2018, 14:44:06
A ver si alguien ve que se me esta pasando, he probado ya todo y nada funciona, bueno funciona por separado pero no a la vez, uno de los casos mas simples:

Código: [Seleccionar]
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);
}

}

En la configuración para este caso tengo:

Código: [Seleccionar]
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());
}

Leer lee perfectamente con la interrupción (y con otros métodos que también he probado):

Código: [Seleccionar]
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
}
}

Sin embargo escribir lo desajusta todo, en cuanto se llama a la función:

usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, usart_write_callback);

inmediatamente después salta la interrupción y ya no vuelve a saltar, por muchos datos que envies, sin embargo los datos se envian, y se guardan en el buffer de recepción!!  :? y no solo eso, si no que salta la interrupción de recepción cada vez que se envía un dato  :? :? ya he probado todo y nada parece funcionar en ninguno de los dos modos ni síncrono, ni asíncrono, y la documentación de las librerías es pésima.

La idea de este ejemplito es recibir un dato de 5 bytes y enviar otro, y al enviar es cuando se fastidia todo.

¿alguien sabe que ocurre? Por cierto el buffer de la usart por lo visto es circular y si llamamos a la funcion io_read no se espera a terminar si no que atiende otras llamadas y en cada iteración coge datos.

un saludo
Título: Re:USART ATMEL SAM
Publicado por: Carl47D en 02 de Mayo de 2018, 00:43:41
¿Podrías poner lo demás del main.c? Si es muy rara la librería de los Atmel, no he vuelto a hacer pruebas con ellos pero mañana reviso a ver si puedo encontrar la falla.

Saludos
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 02 de Mayo de 2018, 06:20:47
Hola Carl gracias por responder, el main no tiene casi nada mas, es un proyecto hecho solo para probar la uart y averiguar que narices pasa

Código: [Seleccionar]
#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;
}

}
}

y en el init:

Código: [Seleccionar]
/*! 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();
}


Citar
Si es muy rara la librería de los Atmel

No es que sea rara, es que es mala. El micro tiene perifericos que no los controlan las librerias como el RTT que he tenido que configurar con los registros, o perifericos que no los controlan debidamente como el RTC que no te lee el día de la semana, he tenido que modificar los fuentes para poder leerlo y configurarlo.

y que en una cosa tan simple como la USART se pierda tantisimo tiempo no renta para nada.


Lo mas raro es que en la interrupción de envio solo entre una vez al ejecutar la linea:

usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, usart_write_callback);

despues al enviar datos entra en la interrupción de lectura, pisando el buffer  :? :?

un saludo.
Título: Re:USART ATMEL SAM
Publicado por: KILLERJC en 02 de Mayo de 2018, 07:14:31
Mi pregunta es...

Por que tenes esto en el while?, me suena a inicializacion de seguro.

Código: C
  1. usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB,     usart_read_callback);
  2. usart_async_get_io_descriptor(&USART_0, &io);
  3. usart_async_enable(&USART_0);

Deberia ser parte del setup por lo que entiendo... no probaste:

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());
        usart_async_get_io_descriptor(&USART_0, &io);
        usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB, usart_read_callback);
        usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, usart_write_callback);
        usart_async_enable(&USART_0);
}

Supuestamente el manual pide eso... descriptor, callback y luego habilitar. Luego solo leer y escribir, esto exige que io sea al menos static en el main.c

Y por lo visto el descriptor I/O posee ambos buffers, el de escritura y lectura:
Citar
25.2.1.1 io_descriptor Struct
I/O descriptor.
Members
write
read The write function pointer

Tal ves al ejecutar nuevamente el io_get_descriptor terminas cambiando de buffer y como dice el manual:
Citar
38.2.3.1 Concurrency
• The write buffer should not be changed while data is being sent


Citar
y no solo eso, si no que salta la interrupción de recepción cada vez que se envía un dato

Eso es el comportamiento correcto. Me refiero a la parte de diferencias entre el ASFv3 y v4

Citar
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.

http://start.atmel.com/static/help/index.html?GUID-79201A5A-226F-4FBB-B0B8-AB0BE0554836
Different read function behavior in some asynchronous drivers

Creo que en la trsmision si es cuando se completa todo. Y en la transmision no usa el buffer.
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 02 de Mayo de 2018, 07:38:55
Citar
Por que tenes esto en el while?, me suena a inicializacion de seguro.

Eso esta asi por las pruebas, al principio probe como dices, pero nada el comportamiento es el mismo

Citar
Creo que en la trsmision si es cuando se completa todo. Y en la transmision no usa el buffer

No salta nunca la interrupcion de la trasmisión, ni al terminar ni nunca, bueno si, solo una sola vez, justo después de ejecutar la función:

usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, usart_write_callback)

siempre que se ejecuta esta función, se ejecuta la interrupcion y ya no vuelve a entrar al terminar el envio ni al enviar ni nunca. al terminar el envio vuelve a entrar en la de recepción y el mismo dato enviado se lee y se guarda en el buffer.

De la documentación, me la he leido toda y rara vez esta acorde con las librerias, por ejemplo del enlace que has pasado de la diferencia entre v3 y v4:

usart_async_enable(&USART_0, USART_ASYNC_RXC_CB);

esta linea esta mal, la funcion usart_async_enable solo se le pasa un parámetro, es decir:

usart_async_enable(&USART_0);

Nada parece funcionar, no se si es que las librerias estaran mal o incompletas, como con los otros perifericos que he probado
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 02 de Mayo de 2018, 07:40:54
he probado con el mismo buffer con otro, statico, dinamico, con el mismo descriptor, con distinto, ha inicializarlo si vas a escribir o leer (como en el ejemplo que he puesto)
a reiniciarlo cuando termino de leer, de escribir... nada :? :?
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 02 de Mayo de 2018, 09:05:47
Aqui se ve mejor el problema:

Código: [Seleccionar]
#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);
}
}

he puesto un break point en el while 1 y veo como se incrementan las 3 posibles interrupciones de la usart.

Bien pues como dije antes, en la interrupcion de transferencia completada entra cuando ejecutas, la linea:

Código: [Seleccionar]
usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, tx_cb_USART);
y ya no entra mas, y despues en cada iteración del bucle while entra en la interrupción de recepción, pero no entra cuando se acaba el envio, si no a cada byte que manda:

aquí se puede ver:

 - Tienes que ingresar para ver archivos adjuntos -

Esto me lleva a pensar que las librerías estan mal, o algo se me esta pasando pero ya no se que puede ser.
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 02 de Mayo de 2018, 10:45:12
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, y resulta que todo esta bien, pero no funciona, por probar me he ido a la llamada de la interrupcion de la usart y he colocado el break point ahi, y paso por paso desde hay FUNCIONA!!! WTF??

Código: [Seleccionar]
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);
}
}

si pongo el breakpoint en otro lado o ejecuto normal no funciona.

Pues muy bien.

Coloco el breakpoint en el inicio y paso por paso veo que entra en el segundo else if sin problemas, todas las veces, pongo el breakpoint dentro del segundo if y  no entra nunca  :shock: :shock: :shock:

(http://directorioseogratis.com/wp-content/uploads/2017/11/tumblr_inline_oz5lni3Bvh1qhy6fn_500.jpg)
Título: Re:USART ATMEL SAM
Publicado por: KILLERJC en 02 de Mayo de 2018, 12:04:01
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.

Citar
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,

Deberias poder ver la direccion de los punteros de los callbacks. Y apenas recibe un dato ver los estados de los bits de recepcion para ver si se activan, aunque me parece raro que no lo haga al ser por hardware.

Tambien por las dudas, defini un callback de error
Ya que veo que lo llama, pero no se si carga una funcion por default vacia o simplemente lo inicia en NULL, preferible asegurarse jeje
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 02 de Mayo de 2018, 13:53:46
Citar
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  :?

En la interrupción de error no entra nunca, por lo tanto supongo que no hay error, ademas estoy recibiendo constantemente el "Hello world" el problema es que no tengo manera de ver cuando termina de enviar.
He monitorizado el registro US_CSR que es el registro de estado de la uart y cuando empieza a enviar ya nunca cambia  :? manda los 12 bytes y vuelve a empezar sin cambiar ningún byte, he mirado las erratas de nuevo (que estan en el datasheet) y no dice nada de esto.

pero lo mas importante es esta prueba, me ido a la interrupción que esta por debajo de todas las Flexcom y esas tonterias, y he colocado contadores a ver como va entrando:
un contador que cuenta al entrar, otro que cuenta en el TXRDY, TXEMPTY (supuestamente cuando acaba la transmisión), RXRDY(un dato recibido y no leido)

coloco el breakpoint en la primera linea en ASSERT(device);

Citar
unsigned int ContadorInterrupcion=0,ContadorTXRDY=0, ContadorTXEMPTY=0, ContadorRXRDY=0, Contador4=0;
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);
   }
}
estas son las iteraciones y los valores de los Contadores, es decir cada vez que se para en el breakpoint:

PD: el main es como he puesto en mi post anterior

Primera iteración:
ContadorInterrupcion=0
ContadorTXRDY=0
ContadorTXEMPTY=0
ContadorRXRDY=0
Contador4=0

Segunda:
ContadorInterrupcion=1
ContadorTXRDY=1
ContadorTXEMPTY=0
ContadorRXRDY=0
Contador4=0

Segunda:
ContadorInterrupcion=2
ContadorTXRDY=1
ContadorTXEMPTY=1    :? :?
ContadorRXRDY=0
Contador4=0

Tercera:
ContadorInterrupcion=3
ContadorTXRDY=2
ContadorTXEMPTY=1
ContadorRXRDY=0
Contador4=0

Cuarta:
ContadorInterrupcion=4
ContadorTXRDY=3
ContadorTXEMPTY=1
ContadorRXRDY=0
Contador4=0

Asi se van incrementando el ContadorTXRDY y el Contador de Interrupción hasta la iteracion 16

Iteracion 16:
ContadorInterrupcion=16
ContadorTXRDY=14
ContadorTXEMPTY=2
ContadorRXRDY=0
Contador4=0

Iteracion 17:
ContadorInterrupcion=16
ContadorTXRDY=14
ContadorTXEMPTY=2
ContadorRXRDY=1     :? :?
Contador4=0

teracion 18:
ContadorInterrupcion=18
ContadorTXRDY=15
ContadorTXEMPTY=2
ContadorRXRDY=1
Contador4=0

y se repite, aqui por lo menos se incrementa el Contador TXEMPTY, no cuando debería pero lo hace cada 16 Iteraciones (que es lo que ocupa el bufer circular)
Sin embargo si pongo el breakpoint dentro de :

Código: [Seleccionar]
else if (hri_usart_get_US_CSR_TXEMPTY_bit(hw) && hri_usart_get_US_IMR_TXEMPTY_bit(hw))
vemos como antes que debería detenerse cada 16 veces que entra en la interrupcion no? Pues entra una vez, y ya no vuelve a entrar  :? :? :?
Repito:

(http://directorioseogratis.com/wp-content/uploads/2017/11/tumblr_inline_oz5lni3Bvh1qhy6fn_500.jpg)
Título: Re:USART ATMEL SAM
Publicado por: Carl47D en 12 de Mayo de 2018, 12:37:29
Estoy usando una D10 Xplained board y ps este código me funciona, al mandarle un char al micro el callback de recepcion se ejecuta, dentro de este escribo y cuando termina de escribir se ejecuta el callback de usart_write_callback y togglea el led de usuario de la tarjeta.

Código: C
  1. #include <atmel_start.h>
  2.  
  3. #include <string.h>
  4.  
  5. void usart_read_callback(const struct usart_async_descriptor *const descr);
  6. void usart_write_callback(const struct usart_async_descriptor *const descr);
  7.  
  8. const char *message_hello = "Hello World!\r\n";
  9. struct io_descriptor *io_uart = NULL;
  10.  
  11. int main(void)
  12. {
  13.         /* Initializes MCU, drivers and middleware */
  14.         atmel_start_init();
  15.  
  16.         gpio_set_pin_direction(PIN_PA09, GPIO_DIRECTION_OUT);
  17.         gpio_set_pin_level(PIN_PA09, 0);
  18.        
  19.         /* Enable callback */
  20.         usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB, usart_read_callback);
  21.         usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, usart_write_callback);
  22.        
  23.         /* Get io descriptor */
  24.         usart_async_get_io_descriptor(&USART_0, &io_uart);
  25.        
  26.         /* Enable USART instance */
  27.         usart_async_enable(&USART_0);
  28.  
  29.         while (1) {
  30.                
  31.         }
  32. }
  33.  
  34. void usart_read_callback(const struct usart_async_descriptor *const descr)
  35. {
  36.         io_write(io_uart, message_hello, strlen(message_hello));
  37. }
  38.  
  39. void usart_write_callback(const struct usart_async_descriptor *const descr)
  40. {
  41.         gpio_toggle_pin_level(PIN_PA09);
  42. }

por cierto, pensé que no habia nada peor a ides basados en eclipse pero este de atmel lo es xD

saludos
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 13 de Mayo de 2018, 08:04:34
Pues no entiendo por que, pero a mi ese codigo no me funciona, así que me temo que debe de ser un fallo del silicio no documentado en las erratas

Me tocara hacer la usart por software  :5]

Entre estas cosas, que he tenido que modificar los fuentes de las librerías para poder leer todos los datos del RTC, que he tenido que crear la librería para utilizar el RTT, por que en las librerias no viene (las nuevas, las ASF4) y el sistema de reloj principal que tiene, no le recomiendo a nadie que utilice este micro nunca.

El atmel samg55j19  :5]
Título: Re:USART ATMEL SAM
Publicado por: Carl47D en 13 de Mayo de 2018, 20:22:26
¿Con que te refieres a que no te sirve el codigo, no se ejecutan los callbacks, no compila?
¿Estan bien asignados los pines Tx y Rx de la UART?

Saludos
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 14 de Mayo de 2018, 06:06:03
Me pasa lo mismo que con todos los códigos que he probado, en la interrupción de terminada el envio no entra nunca, sin embargo cada vez que envia entra en la de recepción,  :? :?

Y luego  si lo ejecuto paso por paso o todo entero se comporta de distinta manera. y lo de que la funcion write, pise el buffer de recepción eso ya.... pffff :?

He revisado los pines, el hardware, el reloj y todo lo que se me ha ocurrido, pero nada....

Compila bien y no da ningun error, y envia y recibe, pero no tengo manera de saber cuando ha terminado de enviar, y ademas las interrupciones no se ejecutan correctamente
Título: Re:USART ATMEL SAM
Publicado por: KILLERJC en 14 de Mayo de 2018, 14:18:14
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.
Título: Re:USART ATMEL SAM
Publicado por: planeta9999 en 14 de Mayo de 2018, 16:05:20

¿ 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.
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 14 de Mayo de 2018, 16:12:45
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.

Que va, no funciona en normal, solo parece funcionar (solo a medias) cuando vas paso por paso, llamada por llamada, si ejecutas la funcion entera o sin debugear no funciona.

Lo puse en el foro de atmel sam el mismo día que lo puse aquí también pero no ha contestado nadie.


¿ 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.

si si la optimización esta a nivel 0 en todas las pruebas, pero nada. Lo he probado con señales como leds y con contadores, pero nada.

En modo debug tampoco es que funcione bien, por que me pisa el buffer de recepción y se ejecuta cada 16 veces, pero por lo menos en debug si salta la interrupción de fin de envio. :?
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 10 de Septiembre de 2018, 09:31:47
Lo escribo aqui para no abrir otro post,

he descubierto por que no funcionaba la uart y saltaban unas interrupciones que no eran, resulta que las librerias estan mal, que sorpresa  :5]

resulta que al usar la funcion "usart_async_register_callback" entras en el fichero hal_usart_async.c y aquí tenemos unas definiciones de las interrupciones:

enum usart_async_callback_type { USART_ASYNC_RXC_CB, USART_ASYNC_TXC_CB, USART_ASYNC_ERROR_CB };

pero luego esta función llama a "_usart_async_register_callback" la cual usa las definiciones de otro fichero:

enum _usart_async_callback_type { USART_ASYNC_BYTE_SENT, USART_ASYNC_RX_DONE, USART_ASYNC_TX_DONE, USART_ASYNC_ERROR };

Asi que claro al no estar definida la interrupción USART_ASYNC_BYTE_SENT en el primer fichero, al intentar usarla la guardabas en el espacio de USART_ASYNC_RX_DONE y cada vez que escribias la uart saltaba la interrupción de la recepción y pisaba el buffer.

Vuelvo a recalcar que a nadie se le ocurra utilizar estos micros hasta que microchip los meta en su sistema y arregle las librerias.

De todas formas la comunicación uart no me va bien, y es por que la interrupción del timer por lo visto tiene mas prioridad y hace que se corrompan los mensajes.
¿Alguien sabe como dar mas prioridad a la interrupción de la uart? no veo nada en las librerías para ajustar el orden de prioridades y en la hoja de datos tampoco solo dice:
See “Interrupt Priority Registers” in the relevant ARM documentation.

De verdad me quedo asombrado de lo mal que esta esto, es increíble.
Título: Re:USART ATMEL SAM
Publicado por: KILLERJC en 10 de Septiembre de 2018, 10:36:26
Las prioridades son manejadas por el NVIC, con las funcines NVIC_xxxx dadas por CMSIS

https://www.keil.com/pack/doc/CMSIS/Core/html/group__NVIC__gr.html

Ahi vas a encontrar NVIC_SetPriority() que es lo que buscas..

Respecto a como lo hace el ASFv4, en la funcion _usart_async_init tenes que:

Código: C
  1. NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
  2.         NVIC_ClearPendingIRQ((IRQn_Type)_sercom_get_irq_num(hw));
  3.         NVIC_EnableIRQ((IRQn_Type)_sercom_get_irq_num(hw));

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

PD: No encuentro donde estan definidos esa funcion sercom_get_irq_num(). Al menos en el codigo que encontre por internet

PD2:
Citar
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.

PD3:
http://asf.atmel.com/docs/latest/common.components.wifi.winc1500.wifi_serial_example.samd21_xplained_pro/html/group__asfdoc__sam0__system__interrupt__group.html

Por si te sirve
Título: Re:USART ATMEL SAM
Publicado por: juaperser1 en 11 de Septiembre de 2018, 02:40:25
Hola Killer, gracias yo lo he arreglado usando las librerias del CMSIS:

Citar
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

Exacto, la verdad es que no se como es posible lo mal que están estas librerías.

dejo por aquí como lo he cambiado por si ha alguien le sirve, es muy sencillo:

-segun https://www.keil.com/pack/doc/CMSIS/Core/html/group__NVIC__gr.html#ga5bb7f43ad92937c039dee3d36c3c2798 las interrupciones tienen por defecto el nivel mas alto posible, (0) (quitando las del nucleo que son negativas y mas altas), he buscado las interrupciones de los dos periferícos, usart0 y tc0 en la hoja de datos:
http://ds.arm.com/media/resources/db/chip/atmel/sams70/Atmel-11242-32-bit-Cortex-M7-Microcontroller-SAM-S70Q-SAM-S70N-SAM-S70J_Datasheet.pdf
(pag52)
y he visto que son la 24 y 13 y a la interrupción timer0 le he dado un nivel 1 para que la usart tenga prioridad con la función:
NVIC_SetPriority();

un Saludo y gracias, esperemos que no encuentre mas errores, de momento solo me ha funcionado correctamente el timer, las entradas salidas y el adc, todo lo demas he tenido o que crear los driver o modificarlos.