Issue regarding UART write callback for ATSAMC21

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The following problem regarding an Atmel SMART ARM-based MCU, ATSAMC21.

I am using ATSAMC21-XPRO development board, Atmel Studiov7 IDE and ASF3 framework.

 

Application flow  --    PC<==EDBG==> ATSAMC21 <==UART==> GSM module, also  --  another microcontroller ==CAN==> ATSAMC21.

 

So, here I want to send 8-bytes of CAN data to GSM by using UARTs write callback method (usart_write_buffer_job function). Program flow is like I send an AT command to the GSM it responds by sending a ">" char, which then is received by ATSAMC21 which further should send the CAN data to the GSM.

Here I am able implement the "usart_read_buffer_job" to receive the ">" char but I am failing to implement the "usart_write_buffer_job".

 

Like only the last received byte is sent and rest of the frame is missing. While debugging I am able to see the required bytes in the respective buffer but on the GSM-terminal side all I can see is the last byte. I am not able to rectify the problem.

 

If I use the "usart_read_buffer_wait" function everything is achieved as required but with a larger CAN data and as the GSM module's response latency varies I have to implement this communication using "_job" or callback method.

 

I attaching a few snippets of my code, please share your suggestions/solutions for the same. Thank you.

 

Attachment(s): 

This topic has a solution.
Last Edited: Sat. Dec 21, 2019 - 11:51 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
                 usart_write_buffer_job(&usart3_instance, (uint8_t *)temp, c);  //Problem with this
                 usart_write_job(&usart3_instance, spc);

The usart_write_buffer_job call is not done when you call usart_write_job. Why not include the spc in the temp buffer and do it all with a single call. And for any additional writes, you need to wait for the usart3_write_callback before calling usart_write_buffer_job again.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am not sure whether I will be able to include spc with temp, but I will try following your suggestion and get back to you again.

Wait for "usart3_write_callback" as in are you suggesting on adding a delay function of a few milli-seconds or a few seconds before "usart_write_buffer_job" function, right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No wait for the callback. Or wait for usart_get_job_status() != STATUS_BUSY.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay I will try this and get back to you.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Can you please give little more details on the same. I am sorry, I tried but I am not able get the right results.

Thank you.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That double write job was the thing that looked wrong and actually when looking at it you are performing 10 _job calls without waiting. And there is another another problem with the temp buffer since you overwrite it with sprintf before the previous usart_write_buffer_job is done.

Anyway, that is way too much to do in the interrupt handler. It can also be a problem if you tried to wait for the usart job there, it would only be possible if the SERCOM interrupt has higher priority than the CAN interrupt.

 

I suggest you just collect the data in the CAN handler and set a flag and then the main loop can look at the flag and perform all usart writes when there is data to send.

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Okay. The thing is that I am new to this development, a beginner. It is a little difficult for me to put the things logically in the code. But, I can understand what you are suggesting me to do. I will try and get back on this. Thank you.