Printf on ATTiny817 Xplained

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

AS 7.0.1931

 

The following program only prints:   Hel

 

#define F_CPU 20000000ul
#define PRESCALE 1
#define F_PER (F_CPU / PRESCALE)
#define BAUD_RATE0 38400ul
#define USART0_BAUD_RATE (F_PER * 4 / BAUD_RATE0)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <string.h>
static int uart_putchar(char c, FILE *stream);
volatile uint32_t knt;
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
int main(void)
{
	 //set peripheral prescale to 1
	CPU_CCP = 0XD8;
	CLKCTRL.MCLKCTRLB = 0;   //1
	knt=0;
	while ((CLKCTRL.MCLKSTATUS & 1)){};    //wait for clk change
	stdout = &mystdout;
	//SET PB2 FOR OUTPUT FOR TXD
	PORTB.PIN3CTRL &= ~PORT_PULLUPEN_bm;  //PB3 = RXD no pullup
	VPORTB.OUT |= (1 << 2);  //PB2 out = 1;
	VPORTB.DIR |= (1 << 2);   //PB2 out
	VPORTB.OUT &= ~(1 << 2);  //PB2 out = 0;
	//setup USART0
	USART0.BAUD = USART0_BAUD_RATE;
	USART0.CTRLB = 0b11000000;	//enable rx & tx;
	knt++;
	sei();
	knt++;
	printf("Hello, world!\r\n");
    while (1) 
    {

    }
}

static int uart_putchar(char c, FILE *stream)
{
	knt++;
	while (USART0.STATUS & 0x00100000);
	USART0.TXDATAL = c;
	return 0;
}

 

This topic has a solution.
Last Edited: Thu. Nov 8, 2018 - 08:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, you seem to have a debugging variable there, "knt". What value does it get?

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

I see you have enabled interrupts for the USART but I don't see any ISRs?? Maybe lucky you are getting anything at all?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

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

Well, you seem to have a debugging variable there, "knt". What value does it get?

 I removed the varable knt, no difference.

 

I see you have enabled interrupts for the USART but I don't see any ISRs?? Maybe lucky you are getting anything at all?

 Interrupts are enabled in CTRLA which is not changed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
	while (USART0.STATUS & 0x00100000);

Is this a 32 bit micro?? I am kind of guessing 0x here was supposed to be 0b

 

(which is why using (1 << bitname) would appear to be a FAR better idea!)

 

EDIT: OK so pulled the 817 datasheet and bit 5 in Status is DREIF so I guess:

 

    while (USART0.STATUS & (1 << USART_DREIF_bp));

or because 817 has _bm as well as _bp then:

 

    while (USART0.STATUS & USART_DREIF_bm);

By the same token this unreadable code:

	USART0.CTRLB = 0b11000000;	//enable rx & tx;

should be:

	USART0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;	//enable rx & tx;

Last Edited: Thu. Nov 8, 2018 - 11:25 AM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
while (USART0.STATUS & 0x00100000);

Is the status reg a 32 bit reg?   (0x001000000) hex number?

Drop the magic number stuff and learn to use (1<<TDRE) or similar.

 

Jim

 

Click Link: Get Free Stock: Retire early!

share.robinhood.com/jamesc3274

 

 

 

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

So, given what has already been mentioned, what happens is that

while (USART0.STATUS & 0x00100000);

is always false, therefore the string is dumped into the USART buffer all at once. Since the buffer + shifter can just hold 3 characters, that's what gets sent.

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

Running program printf example on ATTiny817 Xplained Mini

 


#define F_CPU 20000000ul
#define PRESCALE 1
#define F_PER (F_CPU / PRESCALE)
#define BAUD_RATE0 38400ul
#define USART0_BAUD_RATE (F_PER * 4 / BAUD_RATE0)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <string.h>
static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
int main(void)
{
	 //set peripheral prescale to 1
	CPU_CCP = 0XD8;
	CLKCTRL.MCLKCTRLB = 0;   //1
	while ((CLKCTRL.MCLKSTATUS & 1)){};    //wait for clk change
	stdout = &mystdout;
	//SET PB2 FOR OUTPUT FOR TXD
	PORTB.PIN3CTRL &= ~PORT_PULLUPEN_bm;  //PB3 = RXD no pullup
	VPORTB.OUT |= PIN2_bm;  //PB2 out = 1;
	VPORTB.DIR |= PIN2_bm;   //PB2 out
	VPORTB.OUT &= ~PIN2_bm;  //PB2 out = 0;
	//setup USART0
	USART0.BAUD = USART0_BAUD_RATE;
	USART0.CTRLB = USART_TXEN_bm;	//enable tx;
	sei();
	printf("Hello, world!\r\n");
    while (1) 
    {

    }
}

static int uart_putchar(char c, FILE *stream)
{
	while ((USART0.STATUS & USART_DREIE_bm) == 0);
	USART0.TXDATAL = c;
	return 0;
}

 

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

Why sei()? It's synchronous not asynchronous.