Stupid Stupid USART

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

Hi guys, I'm having great difficulty finding why this USART does not work, it wont send the it not printing the test sting, "sms_print_string("AT+CMGF=1\r\n");".

Maybe someone with a fresh pair of eyes can see it?

 

/*
 * _SMS.h
 *
 * Created: 02/06/2017 18:10:51
 *  Author: wmjen
 */ 


#ifndef SMS_H_
#define SMS_H_


#  define SMS_USART               (&AVR32_USART2)
#  define SMS_USART_RX_PIN        AVR32_USART2_RXD_0_0_PIN
#  define SMS_USART_RX_FUNCTION   AVR32_USART2_RXD_0_0_FUNCTION
#  define SMS_USART_TX_PIN        AVR32_USART2_TXD_0_0_PIN
#  define SMS_USART_TX_FUNCTION   AVR32_USART2_TXD_0_0_FUNCTION
#  define SMS_USART_IRQ           AVR32_USART2_IRQ

static const gpio_map_t SMS_MAP =
{
 {SMS_USART_RX_PIN, SMS_USART_RX_FUNCTION},
 {SMS_USART_TX_PIN, SMS_USART_TX_FUNCTION}
};

// USART options.
static const usart_options_t SMS_USART_OPTIONS =
{
 .baudrate     = 9600,
 .charlength   = 8,
 .paritytype   = USART_NO_PARITY,
 .stopbits     = USART_1_STOPBIT,
 .channelmode  = USART_NORMAL_CHMODE
};

void sms_print_string(char * );
void sms_print_char(char c);


void sms_hardware(void);

// Function prototypes for GFX Driver
void smsDriver(void);

# define buffer_size 100


#define carriage_return (char)13
#define linefeed (char)10

static volatile char sms_inbuffer[buffer_size];
static volatile unsigned int sms_inbuffer_inptr  = 0;
static volatile unsigned int sms_inbuffer_outptr = 0;
static volatile unsigned int sms_chars_in_inbuffer = 0;

static volatile char sms_outbuffer[buffer_size];
static volatile unsigned int sms_outbuffer_inptr    = 0;
static volatile unsigned int sms_outbuffer_outptr   = 0;
static volatile unsigned int sms_chars_in_outbuffer = 0;

void sms_print_char(char c){
 
 //enter_critical_section();
 
 // if transmitter is ready and buffer is empty
 if (usart_tx_ready(SMS_USART) && (sms_chars_in_outbuffer == 0))
 {
  
  // write to transmitter and enable interrupt (interrupt service routine disables it)
  SMS_USART->ier |= AVR32_USART_IER_TXRDY_MASK; //Enable Tx IRQ
  SMS_USART->thr= c;
 }
 else
 {
  // store in the output buffer
  sms_outbuffer[sms_outbuffer_inptr++]= c;
  
  if(sms_outbuffer_inptr >= buffer_size){
   sms_outbuffer_inptr= 0;
  }
  if(sms_outbuffer_inptr == sms_outbuffer_outptr){
   delay_us(100);
  }
  sms_chars_in_outbuffer++;
 } //leave_critical_section();
}


void sms_hardware(void){ 
 
 int character, status;
 //enter_critical_section();  
 if (SMS_USART->csr & AVR32_USART_CSR_RXRDY_MASK)
 {
  
  // receive interrupt, read the char
  status = usart_read_char(SMS_USART, (int *)&character);
  
  if(status == USART_SUCCESS){   
   extern void cs_print_char(char c); cs_print_char(character); 
  }
  else{
   SMS_USART->cr = AVR32_USART_CR_RSTSTA_MASK;
  }
 }
 
 else{ 
  
  // transmit interrupt
  if (sms_chars_in_outbuffer == 0)
  { 
   // nothing more to send, disable interrupt
   SMS_USART->idr = AVR32_USART_IDR_TXRDY_MASK;
  }
  else if(usart_tx_ready(SMS_USART)){
  
   SMS_USART->ier |= AVR32_USART_IER_TXRDY_MASK; //Enable Tx IRQ
   
   // send next char
   SMS_USART->thr= sms_outbuffer[sms_outbuffer_outptr++];
   
   if(sms_outbuffer_outptr >= buffer_size){
    sms_outbuffer_outptr = 0;
   }
   sms_chars_in_outbuffer--;
  }
 }//leave_critical_section();
}


// ===========================================================================

void sms_print_string(char * string){
 
 while(* string != '\0'){
  cs_print_char(*string); string++;
 }
}

void smsDriver(void)
{  
 enter_critical_section();
  
 // Assign GPIO to USART.
 gpio_enable_module(SMS_MAP, sizeof(SMS_MAP) / sizeof(SMS_MAP[0]));

 // Initialize USART in RS232 mode.
 usart_init_rs232(SMS_USART, &SMS_USART_OPTIONS, 66000000);

 // Register the USART interrupt handler to the interrupt controller.
 // usart_int_handler is the interrupt handler to register.
 // EXAMPLE_USART_IRQ is the IRQ of the interrupt handler to register.
 // AVR32_INTC_INT1 is the interrupt priority level to assign to the group of
 // this IRQ.
 // void INTC_register_interrupt(__int_handler handler, unsigned int irq, unsigned int int_lev);
 INTC_register_interrupt(&sms_hardware, SMS_USART_IRQ, AVR32_INTC_INT0); 
 
 // Enable USART Rx interrupt.
 SMS_USART->ier |= AVR32_USART_IER_RXRDY_MASK;

 leave_critical_section();
 
 sms_print_string("AT+CMGF=1\r\n");
}


#endif /* SMS_H_ */

 

This topic has a solution.
Last Edited: Tue. Jul 4, 2017 - 02:05 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One Error is:

 

void sms_print_string(char * string){
 
 while(* string != '\0'){
  cs_print_char(*string); string++;
 }
}

// Should Read:

void sms_print_string(char * string){
 
 while(* string != '\0'){
  sms_print_char(*string); string++;
 }
}

But the error still remains

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

1) initialise the INTC module.
2) use the correct declaration for the USART interrupt handler.
3) do not try to read from a write-only register (IER).

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

 

1. INTC is initialised else where

2. USAT Interrupt Handler does not require __interrupt__, it's called by the main interrupt

 

3. Am I reading to ier?

 

be back in a moment!

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

Fianawarrior wrote:
But the error still remains

What error, exactly?

 

Have you stepped the code in the debugger to see what is (and is not) happening?

 

BTW: Note that AT commands are terminated by just CR - not CRLF.

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

The Error is that It Displays Nothing.  Even sending one byte does not work. I have the same code working on another USAT that woks so maybe it is not the code.

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

Fianawarrior wrote:
The Error is that It Displays Nothing.

But what does that mean?

 

What is "It" ?

 

How are you testing this "display" ?

 

Again, what does stepping through the code show?

 

 

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

It displays nothing on Hyper Terminal, I'm getting there, It is displaying some of the sting.  I'll get back to yous if I need anymore help. Thanks

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

How is "some of sting", nothing? Got a scope?

It all starts with a mental vision.

Last Edited: Tue. Jul 4, 2017 - 01:21 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:
It is displaying some of the sting.

"some of" is very different from "nothing" - isn't it?!

 

Baud Rate and/or Parity would be prime suspects, then.

 

As already noted, a 'scope would be invaluable here ...

 

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

got it.  I'm using a SIM900 Module and it echo's back the character it received, but it is vey slow.  Slowing down the transmission of characters worked.

 

Thanks Guys

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

Fianawarrior wrote:
it echo's (sic) back the character it received

Only if you ask it to!

 

Look at the ATE command to control this ...

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

Please do yourself (and us)  a favour and buy yourself a USD5 logic analyser salaea clone from ebay/ali.

They work like a charm with sigrok / pulseview and you would have diagnosed this problem yourself in less time than it took to write these posts.

Paul van der Hoeven.
Bunch of old projects with AVR's:
http://www.hoevendesign.com