Undefined reference to `usbInit' in C AVR - linker

I use v-usb library for my project.
I wrote code and i want compile it, but unfortunately I have an error which I'm unable to resolve.
Here is my screen-shot:
Description Resource Path Location Type
make: *** [USB_module.elf] Error 1 USB_module C/C++ Problem
undefined reference to `usbInit' main.c /USB_module C/C++ Problem
undefined reference to `usbMsgPtr' main.c /USB_module C/C++ Problem
undefined reference to `usbPoll' main.c /USB_module C/C++ Problem
This situation is for me strange because i have in header this:
#include "usbconfig.h"
#include "usbdrv/usbdrv.h"
#include "usbdrv/oddebug.h"
And usbdrv/usbdrv.h defines the USBpoll function:
Shouldn't the compiler be able to compile it?
Here is my project: http://goo.gl/P6ujK
And here is my entire workspace directory: http://minus.com/mbhTkJuvOK#1
Here is my code: main.c:
/*
* main.c
*
* Created on: 25-01-2012
* Author: Bordeux
*/
#define F_CPU 12000000
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include "usbconfig.h"
#include "usbdrv/usbdrv.h"
#include "usbdrv/oddebug.h"
#define DDS1_SDA (1<<1) //PORTB1
#define DDS_SCL (1<<3) //PORTB3
#define DDS_UPDATE (1<<4) //PORTB4
static uchar usb_val;
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len) //sends len bytes to DDS_SDA
{
uchar i;
uchar b;
uchar adr=0;
while (len!=0)
{
b=1;
for (i=0; i<8; i++)
{
if (b & data[adr])
{
PORTB = (PORTB | DDS1_SDA) & ~DDS_SCL;
PORTB = PORTB | DDS_SCL;
}
else
{
PORTB = PORTB & (~DDS1_SDA & ~DDS_SCL);
PORTB = PORTB | DDS_SCL;
}
b=b<<1;
}
len--;
adr++;
}
if (usb_val)
{
PORTB = PORTB | DDS_UPDATE;// update DDS
PORTB = PORTB & ~DDS_UPDATE;
}
return 1;
}
USB_PUBLIC uchar usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *)data;
static uchar replyBuf[3];
usbMsgPtr = replyBuf;
if(rq->bRequest == 0) // ECHO value
{
replyBuf[0] = data[2]; // rq->bRequest identical data[1]!
replyBuf[1] = data[3];
return 2;
}
if(rq->bRequest == 1) // set port directions
{
// DDRA = data[2];
DDRB = data[3];
DDRD = data[4] & (~USBMASK & ~(1 << 2)); // protect USB interface
return 0;
}
if(rq->bRequest == 2) // read ports
{
// replyBuf[0] = PINA;
replyBuf[1] = PINB;
replyBuf[2] = PIND;
return 3;
}
if(rq->bRequest == 3) // read port states
{
// replyBuf[0] = PORTA;
replyBuf[1] = PORTB;
replyBuf[2] = PORTD;
return 3;
}
if(rq->bRequest == 4) // set ports
{
// PORTA = data[2];
PORTB = data[3];
PORTD = data[4];
return 0;
}
if(rq->bRequest == 5) // use usbFunctionWrite to transfer len bytes to DDS
{
usb_val = data[2]; // usb_val!=0 => DDS update pulse after data transfer
return 0xff;
}
if(rq->bRequest == 6)
{
PORTB = PORTB | DDS_UPDATE; // issue update pulse to DDS
PORTB = PORTB & ~DDS_UPDATE;
return 0;
}
replyBuf[0] = 0xff; // return value 0xff => command not supported
return 1;
}
int main(void)
{
wdt_enable(WDTO_1S); // set Watchdog Timer
odDebugInit();
PORTB=0xe0; // Set PortB 0-4 zero
DDRB=0x1f; // Set PORTB 0-4 output
PORTD = 0; /* no pullups on USB pins */
DDRD = ~USBMASK & ~(1 << 2); /* all outputs except USB data and PD2 = INT0 */
usbInit();
sei();
for(;;) /* main event loop */
{
wdt_reset(); // restart watchdog timer
usbPoll();
}
return 0;
}

solution:
mv usbdrv.c usbdrv.cpp
or compile with avr-g++

You need to link against whatever file supplies usbInit etc., from the looks of your screen shots you've shown the file usbdrv.c, but not actually compiled/linked it into your project. Only usbdrv.h is showing in the tree view.
#includeing the header file shows the compiler the declaration of the function, you need to make sure it sees the definition somewhere too.

you could also have included usbdrv.h in extern "C":
extern "C" {
#include "usbdrv.h";
}

Related

Read a txt file from PC using UART - Atmega32A

I am a beginner in microprocessor programming. I created an array and sent datas using UART. I want to read a text file and create this array using datas in the text file with the simplest way possible. Any suggestion to proceed? Thanks in advance.
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define F_CPU 8000000UL // Clock freq
char flag = 0;
void usart_init(void){
UCSRA = 0x02;
UCSRB = 0x98; // Enable transmitter Enable receiver Enable Interrupt
UCSRC = (1<<UCSZ1) | (1<<UCSZ0); // set as 8 bit data, no parity bit and 1 stop bit.
UBRRH = 0x00;
UBRRL = 109;
}
int main(void){
usart_init();
while(1){
unsigned char array[5]={0x44,0xAA,0x33,0xBB,0x55};
for (int i=0;i<5;i++){
UDR = array[i];
UDR = 0xFF;
_delay_ms(100);
}
sei();
if(flag == 1)
{
flag = 0;
UCSRB = 0x98;
}
}
}
ISR(USART_RXC_vect){
UCSRB = (0<<RXEN)|(0<<TXEN)|(0<<RXCIE);
flag = 1;
}
You are working with a microcontroller so you can't handle a file directly. You had to code every value (copy & paste) in your source code.
unsigned char const array[5]={0x44,0xAA,0x33,0xBB,0x55};
You had to do this even for a large array.

how to read and write to same port in ATMEL studio C program

How to write C program in atmel studio to read and write to same port B. I want to read from port B pin 4 and write to the same port B but on pin 5. I have the following:
#include
int main(void)
{
DDRB = 0b00100000;
while(1)
{
PORTB = PINB;
}
}
ofcourse not working, cannot find a tutorial on that on the net.
thanks
Something fast:
int main() {
//....
//Init your pins and so on
//....
while (1) {
if ((PINB & (1 << 4))) {
PORTB |= 1 << 5;
} else {
PORTB &= ~(1 << 5);
}
}
}

USART with ATMEGA168A -

I am trying to make a very simple USART program which send the received character back to the transmitter and represent the equivalent binary number by flashing 8 leds in my breadboard.
Here is the code:
#define F_CPU 1000000UL // set the CPU clock
#define BAUD 9600 // define baud
#define BAUDRATE ((F_CPU)/(BAUD*16UL)-1) // set baudrate value for UBRR
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <inttypes.h>
#include "led.h"
// function to initialize UART
void uart_init (void)
{
UBRRH=(BAUDRATE>>8);
UBRRL=BAUDRATE; //set baud rate
UCSRB|=(1<<TXEN)|(1<<RXEN); //enable receiver and transmitter
UCSRC|=(1<<URSEL)|(1<<UCSZ0)|(1<<UCSZ1);// 8bit data format
}
// function to send data
void uart_transmit (unsigned char data)
{
while (!( UCSRA & (1<<UDRE))); // wait while register is free
UDR = data; // load data in the register
}
// function to receive data
unsigned char uart_receive (void)
{
while(!(UCSRA) & (1<<RXC)); // wait while data is being received
return UDR; // return 8-bit data
}
// main function: entry point of program
int main (void)
{
unsigned char a = 0;
char buffer[10] = 0;
DDRB = 0xFF;
uart_init(); // initialize UART
while(1)
{
a=uart_receive(); // save the received data in a variable
uart_transmit(a); // send it back
blink(a - 0); // print in the led
_delay_ms(100); // wait before next attempt
}
return 0;
}
The problem I am facing is that none of the registers related to the USART seem to be recognized by the compiler. See an example of the compilation error I am getting:
'UBRRH' undeclared (first use in this function)
Am I missing an include here?
It seems that code you have is not for ATMEGA168, the errors you are getting are due to some registers that doesnt exist in ATMEGA168. In ATMEGA168, there is more than one UART, so the register names are numbered. You can use UBRR0H instead of UBRRH, for example.
Try this:
#ifdef UDR0
#define UBRRH UBRR0H
#define UBRRL UBRR0L
#define UDR UDR0
#define UCSRA UCSR0A
#define UDRE UDRE0
#define RXC RXC0
#define UCSRB UCSR0B
#define RXEN RXEN0
#define TXEN TXEN0
#define RXCIE RXCIE0
#define UCSRC UCSR0C
#define URSEL
#define UCSZ0 UCSZ00
#define UCSZ1 UCSZ01
#define UCSRC_SELECT 0
#else
#define UCSRC_SELECT (1 << URSEL)
#endif
#define BAUD 9600UL
#define UBRRVAL (F_CPU/(BAUD*16)-1)
#define USE_SLEEP 1
void uart_init() {
/* set baud rate */
UBRRH = UBRRVAL >> 8;
UBRRL = UBRRVAL & 0xff;
/* set frame format: 8 bit, no parity, 1 bit */
UCSRC = UCSRC_SELECT | (1 << UCSZ1) | (1 << UCSZ0);
/* enable serial receiver and transmitter */
#if !USE_SLEEP
UCSRB = (1 << RXEN) | (1 << TXEN);
#else
UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);
#endif
}
void uart_putc(uint8_t c) {
if(c == '\n')
uart_putc('\r');
/* wait until transmit buffer is empty */
while(!(UCSRA & (1 << UDRE)));
/* send next byte */
UDR = c;
}
uint8_t uart_getc()
{
/* wait until receive buffer is full */
#if USE_SLEEP
uint8_t sreg = SREG;
sei();
while(!(UCSRA & (1 << RXC)))
sleep_mode();
SREG = sreg;
#else
while(!(UCSRA & (1 << RXC)));
#endif
uint8_t b = UDR;
if(b == '\r')
b = '\n';
return b;
}
int main(){
DDRB = 0xff;
uint8_t data = 0;
uart_init();
while(1){
data = uart_getc();
uart_putc(data);
blink(a - 0);
_delay_ms(100);
}
return 0;
}

AVR, UART, Proteus simulation, not all data displayed on virtual terminal

I am writing a code for a MCU until that will transmit data via UART (RS232).
[ATmega8A]
Currently, I am testing my code in Proteus:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdlib.h>
#include <compat/twi.h>
#define FOSC 16000000 //Clock Speed
#define BAUD 9600 //Baud rate set to 9600
#define MYBRR FOSC/16/BAUD-1
void USART_Init (void)
{
UBRRH = (MYBRR >> 8); //Code for setting
UBRRL = MYBRR; //the baud rate
UCSRB = (1 << RXEN) | (1 << TXEN); //Enable receiver and transmitter
UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); //Frame format setting: 8 Data, 2 Stop bit
}
/* USART transmit function */
void USART_Transmit(unsigned char data)
{
while(!(UCSRA & (1 << UDRE))); //Wait until transmit buffer is empty
UDR = data;
}
/* USART receive function */
unsigned char USART_Receive(void)
{
while(!(UCSRA & (1 << RXC))); //Wait until data is received
return UDR; //Get the data from buffer and return it
}
and the test code in main:
int main(void)
{
unsigned char c;
while(1)
{
a = USART_Receive();
c = 10;
USART_Transmit(c);
_delay(10000);
}
}
In Proteus, the virtual terminal displays 0. However, I am expecting to see 10.
This is just one example, in general only the last digit/character is getting displayed on the virtual terminal.
I cannot explain this. Proteus bug or logic error?
Thank you for any advise.
UART data is sent only in ascii format...you have to convert the integer data to ascii format..use itoa() or do this one
int main(void)
{
unsigned char c;
unsigned char b;
while(1)
{
a = USART_Receive();
c = 10;
b=c;
b=c/10;
USART_Transmit(b+48);
b=0;
b=c%10;
USART_Transmit(b+48);
_delay(10000);
}
}

Changing a global variable in C

I am running a C program on an AVR chip. Whenever a serial signal is heard, it runs the serial interrupt ISR (USART_RX_vect). In this method it should turn on change to = 1;. Then in my main while loop, it should clear the LCD and display it and then set change = 0 again.
This is to stop it continually doing the calulations, and displaying the result on the LCD a million times a minute..
However, when the interrupt method changes the change variable to 1, it does not seem to change it "globally" and in the main method it is always 0..
There is a bit of stuff in here that is for debugging purposes.
/* LCD DEFINES */
#define LED PB5
#define output_low(port,pin) port &= ~(1<<pin)
#define output_high(port,pin) port |= (1<<pin)
#define set_input(portdir,pin) portdir &= ~(1<<pin)
#define set_output(portdir,pin) portdir |= (1<<pin)
/* UART SERIAL DEFINES */
#define F_CPU 16000000UL
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1
#define STARTCHAR 'R'
#define ENDCHAR 'E'
char reading;
char inputBuffer[12];
char readStatus;
uint8_t position;
int change;
char output;
int result;
struct Axis
{
uint8_t axisNumber;
uint16_t position;
uint16_t oldPosition;
} axis1, axis2, axis3;
/* SETUP UART */
void USART_Init( unsigned int ubrr)
{
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
/*Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
void USART_Transmit( unsigned char data )
{
UDR0 = data;
}
unsigned char USART_Receive( void )
{
return UDR0;
}
/*****************************************************************/
int main(void)
{
/* INITALISE SERIAL */
USART_Init(MYUBRR);
/* Turn on Receive Complete Interrupt */
UCSR0B |= (1 << RXCIE0);
/* Turn On GLobal Interrupts */
sei();
position = 0;
change = 0;
/* Initialise LCD */
lcd_init(LCD_DISP_ON); /* Initialize display, cursor off. */
lcd_clrscr();
lcd_puts("READY");
//Turn on LED 13
set_output(PORTB,LED);
output_low(PORTB,LED);
while (1) /* Loop forever */
{
if (change == 1)
{
//If not reading, display the result on the LCD display.
axis1.position = (inputBuffer[0]<< 8) | inputBuffer[1];
axis2.position = (inputBuffer[2]<< 8) | inputBuffer[3];
axis3.position = (inputBuffer[4]<< 8) | inputBuffer[5];
char axis1Printout[12];
char axis2Printout[12];
char axis3Printout[12];
sprintf(axis1Printout,"%u ", axis1.position);
sprintf(axis2Printout,"%u ", axis2.position);
sprintf(axis3Printout,"%u ", axis3.position);
char output[40] = "";
strcat(output, axis1Printout);
strcat(output, axis2Printout);
//strcat(output, axis3Printout);
lcd_clrscr(); /* Clear the screen*/
lcd_puts(output);
_delay_ms(300);
change = 0;
}
}
}
/* INTERRUPTS */
ISR (USART_RX_vect)
{
change = 1;
unsigned char input = USART_Receive();
if (input == 'R')
{
readStatus = 0; //Reading
position = 0;
}
else if ((input != 'E') && (position < 12) && (position > -1))
{
inputBuffer[position] = input;
position++;
}
else if (input == 'E')
{
readStatus = 1; //Stop Reading
position = -1;
output_high(PORTB,LED);
}
}
You need to declare change using the volatile keyword:
volatile int change;
This tells the two 'threads' (main execution loop and your ISR code) to not 'cache' the value in a register, but always retrieve it from memory.
Edit: There's another problem with the code - in your main loop, by the time you set changed to 0, you may have already had another interrupt which should have triggered your loop to run again. The easy-but-not-guaranteed fix is to immediately set changed to 0 straight after you check it. The proper way would be to use a lock - but depending on your situation, the first option might do.
Make the variable declaration volatile to ensure that a changed value is written imediately to the variable in memory.
An object shared by an interrupt handler and the application code should be qualified as volatile in the declaration.
Without the qualifier, the implementation can assume the object cannot change unexpectedly in the application code and can cache the variable (in a register for example) for optimizations while executing the application code.

Resources