Interrupt-driven USART communication with GSM module

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

So I have a custom board, that has an ATXMEGA32A4U and a MC60 GSM/GPS module from Quectel. I'm trying to communicate with the GMS module, but for some reason the data is not being sent. I'm sure the MC60 is connected and working, because there's a status LED attached to one of the status pins. When I attach to the board in debug mode, I can see that the usart_putchar ​is executed but it hangs at the while loop, where it's checking if transmission is complete. I'm using ASF and here's my code so far:

#include <asf.h>

#define USART_SERIAL                    &USARTC0
#define USART_SERIAL_BAUDRATE           USART_BAUD_9600
#define USART_SERIAL_CHAR_LENGTH        USART_CHSIZE_8BIT_gc
#define USART_SERIAL_PARITY             USART_PMODE_DISABLED_gc
#define USART_SERIAL_STOP_BIT           false
#define USART_RX_Vect                   USARTC0_RXC_vect

#define TEST_LED1 IOPORT_CREATE_PIN(PORTB, 2)
#define GSM_POWER_EN IOPORT_CREATE_PIN(PORTD, 0)
#define GSM_POWER_KEY IOPORT_CREATE_PIN(PORTD, 1)
#define C_RXD0 IOPORT_CREATE_PIN(PORTC, 2)
#define C_TXD0 IOPORT_CREATE_PIN(PORTC, 3)

int main (void)
{
 uint8_t command[] = "AT\r\n";
 uint8_t i;

 // Initialize board
 board_init();
 sysclk_init();
 
 // Disable interrupts
 if(pmic_level_is_enabled(PMIC_LVL_LOW)) pmic_disable_level(PMIC_LVL_LOW);
 if(pmic_level_is_enabled(PMIC_LVL_MEDIUM)) pmic_disable_level(PMIC_LVL_MEDIUM);
 if(pmic_level_is_enabled(PMIC_LVL_HIGH)) pmic_disable_level(PMIC_LVL_HIGH);
 
 if (cpu_irq_is_enabled()) cpu_irq_disable();
 
 // Enable IO service
 ioport_init();
 
 // Set TEST_LEDT1 as output
 ioport_set_pin_dir(TEST_LED1, IOPORT_DIR_OUTPUT);
 
 // Enable GPS on MC 60
 ioport_set_pin_dir(GSM_POWER_EN, IOPORT_DIR_OUTPUT);
 ioport_set_pin_dir(GSM_POWER_KEY, IOPORT_DIR_OUTPUT);
 
 // Enable power and turn on MC 60
 ioport_set_value(GSM_POWER_EN, true);
 ioport_set_value(GSM_POWER_KEY, true);
 
 // Set USART pin direction
 ioport_set_pin_dir(C_RXD0, IOPORT_DIR_INPUT);
 ioport_set_pin_dir(C_TXD0, IOPORT_DIR_OUTPUT);
 
 // Enable interrupts for all levels
 pmic_init();
 cpu_irq_enable();
  
 // USART options
 static usart_rs232_options_t USART_SERIAL_OPTIONS = {
  .baudrate = USART_SERIAL_BAUDRATE,
  .charlength = USART_SERIAL_CHAR_LENGTH,
  .paritytype = USART_SERIAL_PARITY,
  .stopbits = USART_SERIAL_STOP_BIT
 };
 
 // Initialize USART
 usart_init_rs232(USART_SERIAL, &USART_SERIAL_OPTIONS);
 usart_set_rx_interrupt_level(USART_SERIAL, USART_INT_LVL_LO);

 for (i = 0; i < sizeof(command); i++) {
  usart_putchar(USART_SERIAL, command[i]);
  while (!usart_tx_is_complete(USART_SERIAL)) {
  }
  usart_clear_tx_complete(USART_SERIAL);
 }

 while (true) {
 }
}

ISR(USART_RX_Vect)
{
 ioport_set_value(TEST_LED1, true);
 while(!usart_rx_is_complete(USART_SERIAL)) {
 }
 usart_clear_rx_complete(USART_SERIAL);
}

The TEST_LED should light up, indicating the interrupt happened, but it's not. Any help would be greatly appreciated!

Last Edited: Thu. Oct 26, 2017 - 12:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Does it need an sei()?

 

(admittedly I don't know a lot about Xmega but I would have expected that as well as PMIC you would need I in SREG?)

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

Hey @clawson, thanks for the quick reply. If you look here: https://github.com/avrxml/asf/blob/master/common/utils/interrupt/interrupt_avr8.h#L99 you can see, that cpu_irq_enable() is just an alias for sei()

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

Please correct the typo in the title!

 

The GSM module - or any other device connected to the UART - neither knows nor cares anything about your code.

 

So start by taking the GSM module out of the picture, and just concentrate on getting your serial comms solid.

 

Once you have the serial comms solid, you can move on to getting the AT commands working - Three AT Command libraries mentioned here: http://www.avrfreaks.net/comment...

 

Be sure you understand what AT commands you need, and how they work, by checking manually with a terminal before trying to get your micro to do it.

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

Hey @awneil, I'm just giving context by saying, that it's a GSM module. I already have other things on the board, that the XMEGA is communicating with through UART and all of them work fine. The interrupt is just not happening and that's what I care about - hence the title. This is the only module I'm trying to communicate with though interrupts. So besides giving me irrelevant answers about the AT commands (for which I have already chosen a library), do you have any other insights on what's wrong with the configuration of my interrupts? Thanks :)

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

The point is to take the GSM out of the picture as it just complicates the issue.

 

Blackarrow1 wrote:
 The interrupt is just not happening 

Is that on Tx, or Rx - or both?

 

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

Hey @awneil .. It's only happening on the RX line. The TX interrupt works fine.

​Added:
 

usart_set_tx_interrupt_level(USART_SERIAL, USART_INT_LVL_LO);

ISR(USART_TX_Vect) {
 ioport_set_value(TEST_LED1, true);
}

LED lights up.

 

 

 

Last Edited: Thu. Oct 26, 2017 - 02:45 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Blackarrow1 wrote:
 It's only happening on the RX line.

So are you sure that the signal is actually reaching the RX pin of the microcontroller?

 

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

Does your code compile without warning or error?  I don't see how it could with the vector names you are using.

/*
 * replace this:
 */
ISR(USART_RX_Vect)
{
    .
    .
    .
}

ISR(USART_TX_Vect)
{
    .
    .
    .
}

/*
 * with this:
 */
ISR(USARTC0_RXC_vect)
{
    .
    .
    .
}

ISR(USARTC0_TXC_vect)
{
    .
    .
    .
}

 

EDIT: changed "with" to "without".

Greg Muth

Portland, OR, US

Atmel Studio 7.0 on Windows 10

Xplained/Pro/Mini Boards mostly

 

 

Last Edited: Thu. Oct 26, 2017 - 04:24 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Oh, now I see it.  I assume you are doing the same for USART_TX_Vect?

 

Greg Muth

Portland, OR, US

Atmel Studio 7.0 on Windows 10

Xplained/Pro/Mini Boards mostly

 

 

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

Yes, I'm sure. I don't think it's the microcontroller, I have 3 of the same boards and I tried by uploading the code to all 3 of them .. same outcome.

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

Yeah, just replacing them with macros. Code compiles fine :)

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

Blackarrow1 wrote:
I have 3 of the same board

So what board is it - your own design, or a purchased commercial board?

 

I tried by uploading the code to all 3 of them .. same outcome.

But have you ever had the serial comms - particularly the Rx - working on this board?

 

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

Yes, that's right. The board is custom, but the serial comms are working, because I have a couple of sensors (this one in particular: http://www.ti.com/product/TMP107...) and comms work fine. It's just that they don't work with the MC60 module for some reason. I double checked the example application schematics and all of the pins are connected in the right way. I guess there's some kind of sequence for powering on the MC60, that I can't seem to figure out. In the datasheet there's a section for powering on the module. You're supposed to pull the "power enable" and "power key" low and the module is supposed to be ready in 4-5 seconds. Because it has autobauding enabled by default, an 'AT\r' command is supposed to be sent, so the MC60 can detect the baud rate (and keep being sent until in returns an OK response) ... but no response ever comes back ...

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

So does the signal from the MC60 arrive at the MCU pin, or doesn't it?

 

 

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

I'm just really skeptical, that it doesn't arrive. It should. The schematic is fine and not all 3 of them can be faulty, had them printed at a reputable PCB manufacturer. I'm going to test them later as I don't have an oscilloscope at home and post the results.

Last Edited: Fri. Oct 27, 2017 - 10:49 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Blackarrow1 wrote:
I'm just really skeptical, that it doesn't arrive.

It's the obvious first thing to check.

 

 The schematic is fine

Nobody here can see your schematic, so we don't know that - we have to ask you.

 

 

and not all 3 of them can be faulty

Oh yes they can!

 

surprise

 

there could be a systematic error/fault somewhere...

 

or just extreme bad luck.

 

Been there.

 

 

Or it could just be some "feature" of the GSM module - eg, control lines not in the right state ...

 

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

 

XMEGA TX line:XMEGA32A4U TX Line

​MC60 RX line: MC60 RX Line

​The TX line of the MC60 is flat ... and the RX line of the XMEGA is also flat. Which leads me to believe, that there's some special sequence I'm not following for enabling transmission, but what I got from the data sheet is pull the "POWEREN" low send the AT command and then set the baud.
 

​Edit: Sorry for the big images, don't know how to make them smaller.

Last Edited: Fri. Oct 27, 2017 - 01:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Well, I don't like to say, "I told you so" - but ...

 

cheeky

 

Sorry for the big images, don't know how to make them smaller

You have to double-click the image - then you get a dialogue to resize it.

 

I agree - that is not in the least bit obvious. It has been noted among the many site daftnesses ...

 

<rolls-eyes>

 

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

Blackarrow1 wrote:
The TX line of the MC60 is flat

Strictly speaking, the RS232 standard defines "TX" as the connection from the DTE to the DCE - so, at the DTE (the microcontroller) it is an output, and it the the DCE (the GSM module) it is an input.

 

Could it be that your module is adopting this convention ... ?

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

Yes, the MC60 uses that convention. It's mentioned in the AT commands manual. So if you look at page 10 in the document attached below you'll see how commands are supposed to be sent.​ And if you look at the hardware design document, you'll see on page 44, the sequence for powering on and communicating.

Attachment(s):