Commit 644096bb authored by Sam Calisch's avatar Sam Calisch
Browse files

added i2c example (which also uses usart)

parent 1fa3d9fc
//
// xmega twi for as5510 linear magnetic encoder
// sec, 2016
#include "serial.h"
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "twi_master_driver.h"
#define SLAVE_ADDRESS 0x56
#define CPU_SPEED 32000000
#define TWI_BAUDRATE 100000
#define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, TWI_BAUDRATE)
TWI_Master_t twiMaster; /*!< TWI master module. */
USART_data_t USART_data;
uint32_t value; //magnetic encoder reading
unsigned char Data_LSB, Data_MSB; //high byte and low byte of reading
uint8_t address_data[2] = {0x00, 0x01};
uint8_t speed_mode_date[2] = {0x02, 0x04}; //set into slow mode, value=4
uint8_t sensitivity_mode_data[2] = {0x0B, 0x02}; //set into highest sensitivity value=2
bool result = true;
int main(void) {
// set up clock
OSC.CTRL = OSC_RC32MEN_bm; // enable 32MHz clock
while (!(OSC.STATUS & OSC_RC32MRDY_bm)); // wait for clock to be ready
CCP = CCP_IOREG_gc; // enable protected register change
CLK.CTRL = CLK_SCLKSEL_RC32M_gc; // switch to 32MHz clock
//set up usart
PORTD.DIRSET = PIN3_bm; //TXD0
PORTD.DIRCLR = PIN2_bm; //RXD0
USART_InterruptDriver_Initialize(&USART_data, &USARTD0, USART_DREINTLVL_LO_gc);
USART_Format_Set(USART_data.usart, USART_CHSIZE_8BIT_gc,
USART_PMODE_DISABLED_gc, 0);
USART_RxdInterruptLevel_Set(USART_data.usart, USART_RXCINTLVL_LO_gc);
//take f_sysclk/(BSEL+1) ~= f_baud*16 with zero scale. See manual or spreadsheet for scale defs
USART_Baudrate_Set(&USARTD0, 123 , -4); //230400 baud with .08% error
USART_Rx_Enable(USART_data.usart);
USART_Tx_Enable(USART_data.usart);
//enable interrupts
PMIC.CTRL |= PMIC_LOLVLEX_bm;
//set up twi
TWI_MasterInit(&twiMaster, &TWIC, TWI_MASTER_INTLVL_LO_gc, TWI_BAUDSETTING);
//PORTC.DIRCLR = PIN0_bm | PIN1_bm; //TXD0
sei();
//set as5011 speed mode
result = TWI_MasterWrite(&twiMaster, SLAVE_ADDRESS, &speed_mode_date[0], 2);
while (twiMaster.status != TWIM_STATUS_READY) {}
//set as5011 sensitivity
result = TWI_MasterWrite(&twiMaster, SLAVE_ADDRESS, &sensitivity_mode_data[0],2);
while (twiMaster.status != TWIM_STATUS_READY) {}
while(1){
result = TWI_MasterWriteRead(&twiMaster, SLAVE_ADDRESS, &address_data[0], 1,2); // Read D7..0
while (twiMaster.status != TWIM_STATUS_READY) {}
if (result) {
Data_LSB = twiMaster.readData[0];
Data_MSB = twiMaster.readData[1];
}
else { Data_LSB = 255; Data_MSB = 255;}
//value = ((Data_MSB & 0x03)<<8) + Data_LSB;
usart_send_byte(&USART_data,1);
usart_send_byte(&USART_data,2);
usart_send_byte(&USART_data,3);
usart_send_byte(&USART_data,4);
//usart_send_uint32(&USART_data,value);
usart_send_byte(&USART_data,Data_LSB);
//usart_send_byte(&USART_data,twiMaster.result);
usart_send_byte(&USART_data,(Data_MSB & 0x03));
usart_send_byte(&USART_data,10);
_delay_ms(100);
}
}
ISR(USARTD0_RXC_vect){USART_RXComplete(&USART_data);}
ISR(USARTD0_DRE_vect){USART_DataRegEmpty(&USART_data);}
ISR(TWIC_TWIM_vect){TWI_MasterInterruptHandler(&twiMaster);}
from koko.lib.pcb import *
from koko.lib.sam import *
class TagConnectPDI(Component):
'''
'''
_pad = s2d.circle(0,0,.5*.031)
_via = s2d.circle(0,0,.5*.039)
pins = [
Pin(-.05,-.025,_pad,'CLK',label_size=.02),
Pin( .00,-.025,_pad,'NC',label_size=.02),
Pin( .05,-.025,_pad,'DAT',label_size=.02),
Pin(-.05,.025,_pad,'VCC',label_size=.02),
Pin( .00,.025,_pad,'NC',label_size=.02),
Pin( .05,.025,_pad,'GND',label_size=.02)
]
vias = [
Via(-.1,0,_via),
Via(.1,0.04,_via),
Via(.1,-.04,_via),
]
class ATxmega16A4U(Component):
_padh = chamfered_rectangle(-.024,.024,-.007,.007,.003)
_padv = chamfered_rectangle(-.007,.007,-.024,.024,.003)
c= 11/25.4/2.
d = 0.8/25.4
names = [
'PA5','PA6','PA7','PB0','PB1','PB2','PB3','GND','VCC','PC0','PC1',
'PC2','PC3','PC4','PC5','PC6','PC7','GND2','VCC2','PD0','PD1','PD2',
'PD3','PD4','PD5','PD6','PD7','PE0','PE1','GND3','VCC3','PE2','PE3',
'PDI/DATA','RST/CLK','PR0','PR1','GND4','AVCC','PA0','PA1','PA2','PA3','PA4'
]
n_side = 11
pins = [Pin(-c,(5-i)*d,_padh,n,label_size=.025) for i,n in enumerate(names[:n_side])]
pins += [Pin((-5+i)*d,-c,_padv,n,label_size=.025,label_rot=-90) for i,n in enumerate(names[n_side:2*n_side])]
pins += [Pin(c,(-5+i)*d,_padh,n,label_size=.025) for i,n in enumerate(names[2*n_side:3*n_side])]
pins += [Pin((5-i)*d,c,_padv,n,label_size=.025,label_rot=-90) for i,n in enumerate(names[3*n_side:])]
vias = []
shadow = rectangle(-c+d,c-d,-c+d,c-d)
class ATxmegaE5(Component):
_padh = chamfered_rectangle(-.025,.025,-.007,.007,.002)
_padv = chamfered_rectangle(-.007,.007,-.025,.025,.002)
c=.18
d = 0.8/25.4
names = [
'1 GND','PA4','PA3','PA2','PA1','PA0','PDI/DATA','RST/CLK',
'PC7','PC6','PC5','PC4','PC3','PC2','PC1','PC0',
'VCC','GND','PR1','PR0','PD7','PD6','PD5','PD4',
'PD3','PD2','PD1','PD0','PA7','PA6','PA5','AVCC'
]
pins = [Pin(-c,(3.5-i)*d,_padh,n,label_size=.025) for i,n in enumerate(names[:8])]
pins += [Pin((-3.5+i)*d,-c,_padv,n,label_size=.025,label_rot=-90) for i,n in enumerate(names[8:16])]
pins += [Pin(c,(-3.5+i)*d,_padh,n,label_size=.025) for i,n in enumerate(names[16:24])]
pins += [Pin((3.5-i)*d,c,_padv,n,label_size=.025,label_rot=-90) for i,n in enumerate(names[24:])]
vias = []
shadow = rectangle(-c+d,c-d,-c+d,c-d)
class Regulator_SOT23(Component):
''' LM3480 100-mA, 3.3V
'''
_pad_SOT23 = s2d.rectangle(-.02,.02,-.012,.012)
pins = [
Pin(-0.045, -0.0375, _pad_SOT23,'IN'),
Pin(-0.045, 0.0375, _pad_SOT23,'OUT'),
Pin(0.045, 0, _pad_SOT23,'GND')
]
prefix = 'U'
vias = []
class Header_FTDI(Component):
''' For ftdi cable
'''
_pad_header = chamfered_rectangle(-0.06, 0.06, -0.025, 0.025,.007)
pins = [
#Pin(0, -0.25, _pad_header, 'RTS'),
Pin(0, -0.15, _pad_header, 'RX'),
Pin(0, -0.05, _pad_header, 'TX'),
Pin(0, 0.05, _pad_header, 'VCC'),
Pin(0, 0.15, _pad_header, 'CTS'),
Pin(0, 0.25, _pad_header, 'GND'),
]
prefix = 'J'
vias = []
shadow = s2d.rectangle(-.06,8/25.4,-.18,.28)
class AS5510(Component):
#Austrian Microsystems AS5510 linear magnetic encoder
_pad_SOIC = s2d.rectangle(-0.041, 0.041, -0.015, 0.015)
pins = []
y = 0.075
for t in ['NC', 'VSS', 'ADR', 'VDD']:
pins.append(Pin(-0.14, y, _pad_SOIC, t))
y -= 0.05
for p in ['TEST', 'SDA', 'SCL', 'NC']:
y += 0.05
pins.append(Pin(0.14, y, _pad_SOIC, p))
del y
prefix = 'U'
w = 5/25.4#3.90/25.4;
h = 4.9/25.4
vias = []
class AS5510_Flipped(Component):
#Austrian Microsystems AS5510 linear magnetic encoder
_pad_SOIC = s2d.rectangle(-0.041, 0.041, -0.015, 0.015)
pins = []
y = 0.075
for t in ['NC', 'VSS', 'ADR', 'VDD']:
pins.append(Pin(0.14, y, _pad_SOIC, t))
y -= 0.05
for p in ['TEST', 'SDA', 'SCL', 'NC']:
y += 0.05
pins.append(Pin(-0.14, y, _pad_SOIC, p))
del y
prefix = 'U'
w = 5/25.4#3.90/25.4;
h = 4.9/25.4
vias = [
Via(0,0,dogboned_rectangle_y(-.5*w,.5*w,-.5*h,.5*h,.016)) ]
class Hole(Component):
pins = [Pin(0,0,circle(0,0,0.01))]
vias = [Via(0,0,circle(0,0,.5*2.1/25.4))]
tap = circle(0,0,.5*1.9/25.5)
width = 1.5
height = 1.
pcb = PCB(0,0,width,height,chamfer_distance=.12)
def connectG(pin,dx,dy,width=.014):
'''
Convenience function for connecting to ground plane
'''
pcb.connectD(pin,[pin.x+dx,pin.y+dy],[pin.x+dx-.0001,pin.y+dy],width=width,sides=[0,1,1])
def connectS(pin,dx,dy,width=.014):
pcb.connectD(pin,[pin.x+dx+.0001,pin.y+dy],width=width)
def connectM(pin1,pin2,dx,width=.014):
pcb.connectD(pin1,[pin1.x+dx,pin1.y],pin2,width=width)
#pcb.custom_cutout = chamfered_rectangle(0,width,.5*height-.25,.5*height+.25,.05)
#pcb.custom_cutout += chamfered_rectangle(0,.6*width,0,height,.12)
xmega = ATxmegaE5(.45,.7,90-45,'Xmega\n8E5')
pcb += xmega
pdi = TagConnectPDI(xmega.x+.04,xmega.y-.36,180)
pcb += pdi
pcb.connectD(xmega['RST/CLK'],[pdi['CLK'].x,pdi['CLK'].y+.05],pdi['CLK'],width=.014)
#connectG(xmega['1 GND'],-.03,.05)
#connectG(xmega['GND'],.07,.05)
pcb.connectD(xmega['PDI/DATA'],[xmega['PDI/DATA'].x-.03,xmega['PDI/DATA'].y-.04],pdi['DAT'],width=.014)
C1 = C_0805(pdi.x,pdi.y-.08,180,'C1 1uF')
pcb += C1
C2 = C_0805(C1.x,C1.y-.07,180,'C2 .1uF')
pcb += C2
R1 = R_0805(pdi.x+.11,pdi.y+.085,0,'R1\n10k')
pcb += R1
pcb.connectD(xmega['1 GND'],[xmega['1 GND'].x-.03,xmega['1 GND'].y-.04],[C2[0].x-.14,C2[0].y+.1],C2[0],width=.014)
pcb.connectV(pdi['GND'],C1[0])
pcb.connectV(pdi['GND'],C2[0])
pcb.connectV(pdi['VCC'],C1[1])
pcb.connectV(pdi['VCC'],C2[1])
pcb.connectD(xmega['RST/CLK'],R1[1],width=.014)
pcb.connectD(xmega['AVCC'],[xmega['AVCC'].x+.188,xmega['AVCC'].y-.1],xmega['PC5'],R1[0],width=.014)
pcb.connectD(xmega['VCC'],[xmega.x-.105,xmega.y-.05],xmega['AVCC'],width=.014)
ftdi = Header_FTDI(xmega.x-.28,xmega.y-.35,180,'ftdi')
pcb += ftdi
reg = Regulator_SOT23(ftdi.x+.15,ftdi.y-.25,180,'3.3v')
pcb += reg
pcb.connectD(ftdi['VCC'],[ftdi.x+.05,ftdi['VCC'].y],reg['IN'],width=.02)
pcb.connectV(R1[0],C1[1],width=.018)
pcb.connectD(xmega['PD2'],[xmega['PD2'].x-.05,xmega['PD2'].y+.035],[xmega.x-.3,xmega.y-.07],[ftdi.x+.1,ftdi['TX'].y],ftdi['TX'],width=.014)
pcb.connectD(xmega['PD3'],[xmega['PD3'].x-.08,xmega['PD3'].y+.05],[xmega.x-.35,xmega.y-.1],ftdi['RX'],width=.014)
pcb.connectV(C2[0],ftdi['GND'])
pcb.connectV(reg['GND'],ftdi['GND'])
pcb.connectV(C1[1],reg['OUT'],width=.02)
pcb.connectD(xmega['GND'],[xmega.x,xmega['GND'].y-.03],[xmega.x,xmega.y+.2],[ftdi.x+.13,xmega.y+.29],[ftdi['GND'].x-.1,ftdi['GND'].y+.05],ftdi['GND'],width=.014)
hall = AS5510_Flipped(width-.3,height*.5,0,'AS5510')
pcb += hall
Chall = C_1206(hall.x+.24,hall['ADR'].y,-90,'100 nF')
pcb += Chall
pcb.connectV(hall['ADR'],hall['VSS']) #ground ADR to pick 1010110 as I2C address
pcb.connectH(hall['VSS'],Chall[1])
pcb.connectH(hall['VDD'],Chall[0])
#pcb.connectV(hall['TEST'],[Chall.x+.07,Chall.y-.12],Chall[1])
pcb.connectD(xmega['GND'],[xmega['GND'].x+.04,xmega['GND'].y+.03],[Chall.x-.05,hall.y+.15],Chall[1],width=.014)
pcb.connectD(xmega['PC0'],hall['SDA'],width=.014)
pcb.connectD(xmega['PC1'],[xmega['PC1'].x+.1,xmega['PC1'].y-.1],[xmega['PC1'].x+.15,xmega['PC1'].y-.05],hall['SCL'],width=.014).add_jumper([xmega['PC1'].x+.12,xmega['PC1'].y-.075],45)
RSCL = R_1206(R1.x+.12,R1.y-.05,90,'RSCL',label_size=.03)
pcb += RSCL
RSDA = R_1206(RSCL.x+.1,RSCL.y,90,'RSDA',label_size=.03)
pcb += RSDA
pcb.connectV(hall['VDD'],RSDA[1]).cut_corners([(1,.08)])
pcb.connectD(hall['TEST'],[RSCL.x+.25,hall['TEST'].y],[RSCL.x+.22,ftdi['GND'].y+.0],[ftdi['GND'].x+.05,ftdi['GND'].y-.08],ftdi['GND']).add_jumper([RSCL.x+.22,RSDA[1].y],90)
pcb.connectH(C1[1],RSCL[1])
pcb.connectH(C1[1],RSDA[1])
pcb.connectV(RSDA[0],hall['SDA'])
pcb.connectD(xmega['PC1'],RSCL[0],width=.014)
#soldering tails
connectS(xmega['PA7'],.04,-.04)
connectS(xmega['PA6'],.04,-.04)
connectS(xmega['PA5'],.04,-.04)
connectS(xmega['PD0'],.04,-.04)
connectS(xmega['PD1'],.04,-.04)
connectS(xmega['PA4'],.03,.03)
connectS(xmega['PA3'],.03,.03)
connectS(xmega['PA2'],.03,.03)
connectS(xmega['PA1'],.03,.03)
connectS(xmega['PA0'],.03,.03)
connectS(xmega['PD4'],.04,.04)
connectS(xmega['PD5'],.04,.04)
connectS(xmega['PD6'],.04,.04)
connectS(xmega['PD7'],.04,.04)
connectS(xmega['PR0'],.04,.04)
connectS(xmega['PR1'],.04,.04)
connectS(xmega['PC2'],.04,-.04)
connectS(xmega['PC3'],.04,-.04)
connectS(xmega['PC4'],.04,-.04)
connectS(xmega['PC6'],.03,-.03)
connectS(xmega['PC7'],.02,-.02)
wjw = 4
wjh = 1.2
fl = 1.25 #flexure length
ratio = 12.8 #length over flexure width
fth = fl/ratio#.06
fl_gap = .05
fw = wjh-2*fth-fl_gap
wj = chamfered_rectangle(-wjw+width,width,.5*height-.5*wjh,.5*height+.5*wjh,.1)
wj -= circle(hall.x,hall.y,4/25.4)
wj -= make_edges([
[hall.x-.25-fl,hall.y-.5*fw],
[hall.x-.25,hall.y-.5*fw],
[hall.x-.25,hall.y+.5*fw],
[hall.x-.25-fl,hall.y+.5*fw]
],fl_gap)
mount_pts = [[hall.x-.4,hall.y+.35],[hall.x-.4,hall.y-.35]]
for p in mount_pts:
h = Hole(p[0],p[1],0)
wj -= move(h.tap,p[0],p[1])
pcb += h
#wj -= pcb.cutout
#pcb.add_custom_layer("wj",wj,(250,0,100))
cad.shapes = pcb.layout
#cad.shape = pcb.traces+(pcb.cutout-pcb.cutout)
#cad.shape = pcb.cutout+(pcb.traces-pcb.traces)
#cad.shape = pcb.custom_layers['wj']['layer']
\ No newline at end of file
PROJECT=hall-encoder
SOURCES=$(PROJECT).c
MMCU=atxmega8e5
F_CPU = 32000000
TARGET = x8e5
PROGRAMMER= atmelice_pdi
CFLAGS=-mmcu=$(MMCU) -Wall -Os -DF_CPU=$(F_CPU)
$(PROJECT).hex: $(PROJECT).out
avr-objcopy -O ihex $(PROJECT).out $(PROJECT).c.hex;\
avr-size --mcu=$(MMCU) --format=avr $(PROJECT).out
$(PROJECT).out: $(SOURCES)
avr-gcc $(CFLAGS) -I./ -o $(PROJECT).out $(SOURCES)
program: $(PROJECT).hex
avrdude -p $(TARGET) -c $(PROGRAMMER) -U flash:w:$(PROJECT).c.hex
#
# hello.light.45.py
#
# receive and display light level
# hello.light.45.py serial_port
#
# Neil Gershenfeld
# CBA MIT 10/24/09
#
# (c) Massachusetts Institute of Technology 2009
# Permission granted for experimental and personal use;
# license for commercial sale available from MIT
#
#serial port seems like ttyUSB0
# or usb-FTDI_FT232R_USB_UART_A501JTMW-if00-port0
#or ../../ttyUSB0
from Tkinter import *
import serial,time
WINDOW = 600 # window size
eps = 0.5 # filter time constant
filter = 0.0 # filtered value
f = open('loadcell-as5011-samples.csv','w')
t0 = time.time()
def idle(parent,canvas):
global filter, eps
#
# idle routine
#
byte2 = 0
byte3 = 0
byte4 = 0
ser.flush()
while 1:
#
# find framing
#
byte1 = byte2
byte2 = byte3
byte3 = byte4
byte4 = ord(ser.read())
if ((byte1 == 1) & (byte2 == 2) & (byte3 == 3) & (byte4 == 4)):
break
low = ord(ser.read())
high = ord(ser.read())
#newvalue=ord(ser.read())
value = 256*high + low
print value
f.write("%f,%d\n"%(time.time()-t0,value) )
#print value#low,high
filter = (1-eps)*filter + eps*value
x = int(.2*WINDOW + (.9-.2)*WINDOW*filter/1024.0)
#canvas.itemconfigure("text",text="%.1f"%newvalue)
canvas.coords('rect1',.2*WINDOW,.05*WINDOW,x,.2*WINDOW)
canvas.coords('rect2',x,.05*WINDOW,.9*WINDOW,.2*WINDOW)
canvas.update()
parent.after_idle(idle,parent,canvas)
#
# check command line arguments
#
if (len(sys.argv) != 2):
print "command line: hello.light.44.py serial_port"
sys.exit()
port = sys.argv[1]
#
# open serial port
#
### CHANGE THIS FOR DIFFERENT BAUD FOR 44 INSTEAD OF 45?????
#or more relevantly, the clock issues? internal instead of external; 1 or 8?
#maybe messes up bit delays...
ser = serial.Serial(port,230400)
ser.flush()
#ser = serial.Serial(port,115200)
ser.setDTR()
#
# set up GUI
#
root = Tk()
root.title('hello.light.44.py (q to exit)')
root.bind('q','exit')
canvas = Canvas(root, width=WINDOW, height=.25*WINDOW, background='white')
canvas.create_text(.1*WINDOW,.125*WINDOW,text=".33",font=("Helvetica", 24),tags="text",fill="#0000b0")
canvas.create_rectangle(.2*WINDOW,.05*WINDOW,.3*WINDOW,.2*WINDOW, tags='rect1', fill='#b00000')
canvas.create_rectangle(.3*WINDOW,.05*WINDOW,.9*WINDOW,.2*WINDOW, tags='rect2', fill='#0000b0')
canvas.pack()
#
# start idle loop
#
root.after(100,idle,root,canvas)
root.mainloop()
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#define output(directions,pin) (directions |= pin) // set port direction for output
#define set(port,pin) (port |= pin) // set port pin
#define clear(port,pin) (port &= (~pin)) // clear port pin
#define pin_test(pins,pin) (pins & pin) // test for port pin
#define bit_test(byte,bit) (byte & (1 << bit)) // test for bit set
/* USART buffer defines. */
/* \brief Receive buffer size: 2,4,8,16,32,64,128 or 256 bytes. */
#define USART_RX_BUFFER_SIZE 128
/* \brief Transmit buffer size: 2,4,8,16,32,64,128 or 256 bytes */
#define USART_TX_BUFFER_SIZE 128
/* \brief Receive buffer mask. */
#define USART_RX_BUFFER_MASK ( USART_RX_BUFFER_SIZE - 1 )
/* \brief Transmit buffer mask. */
#define USART_TX_BUFFER_MASK ( USART_TX_BUFFER_SIZE - 1 )
#if ( USART_RX_BUFFER_SIZE & USART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif
#if ( USART_TX_BUFFER_SIZE & USART_TX_BUFFER_MASK )
#error TX buffer size is not a power of 2
#endif
/* \brief USART transmit and receive ring buffer. */
typedef struct USART_Buffer
{
/* \brief Receive buffer. */
volatile uint8_t RX[USART_RX_BUFFER_SIZE];
/* \brief Transmit buffer. */
volatile uint8_t TX[USART_TX_BUFFER_SIZE];
/* \brief Receive buffer head. */
volatile uint8_t RX_Head;
/* \brief Receive buffer tail. */
volatile uint8_t RX_Tail;
/* \brief Transmit buffer head. */
volatile uint8_t TX_Head;
/* \brief Transmit buffer tail. */
volatile uint8_t TX_Tail;
} USART_Buffer_t;
/*! \brief Struct used when interrupt driven driver is used.
*
* Struct containing pointer to a usart, a buffer and a location to store Data
* register interrupt level temporary.
*/
typedef struct Usart_and_buffer
{
/* \brief Pointer to USART module to use. */
USART_t * usart;
/* \brief Data register empty interrupt level. */
USART_DREINTLVL_t dreIntLevel;
/* \brief Data buffer. */
USART_Buffer_t buffer;
} USART_data_t;
#define USART_RxdInterruptLevel_Set(_usart, _rxdIntLevel) \
((_usart)->CTRLA = ((_usart)->CTRLA & ~USART_RXCINTLVL_gm) | _rxdIntLevel)
#define USART_Format_Set(_usart, _charSize, _parityMode, _twoStopBits) \
(_usart)->CTRLC = (uint8_t) _charSize | _parityMode | \
(_twoStopBits ? USART_SBMODE_bm : 0)
#define USART_Baudrate_Set(_usart, _bselValue, _bScaleFactor) \
(_usart)->BAUDCTRLA =(uint8_t)_bselValue; \
(_usart)->BAUDCTRLB =(_bScaleFactor << USART_BSCALE0_bp)|(_bselValue >> 8)
#define USART_Rx_Enable(_usart) ((_usart)->CTRLB |= USART_RXEN_bm)
#define USART_Rx_Disable(_usart) ((_usart)->CTRLB &= ~USART_RXEN_bm)
#define USART_Tx_Enable(_usart) ((_usart)->CTRLB |= USART_TXEN_bm)
#define USART_Tx_Disable(_usart) ((_usart)->CTRLB &= ~USART_TXEN_bm)
_Bool USART_TXBuffer_FreeSpace(USART_data_t * usart_data)
{
/* Make copies to make sure that volatile access is specified. */
uint8_t tempHead = (usart_data->buffer.TX_Head + 1) & USART_TX_BUFFER_MASK;
uint8_t tempTail = usart_data->buffer.TX_Tail;
/* There are data left in the buffer unless Head and Tail are equal. */
return (tempHead != tempTail);
}
_Bool USART_TXBuffer_PutByte(USART_data_t * usart_data, uint8_t data)
{
uint8_t tempCTRLA;
uint8_t tempTX_Head;
_Bool TXBuffer_FreeSpace;
USART_Buffer_t * TXbufPtr;
TXbufPtr = &usart_data->buffer;
TXBuffer_FreeSpace = USART_TXBuffer_FreeSpace(usart_data);
if(TXBuffer_FreeSpace)
{
tempTX_Head = TXbufPtr->TX_Head;
TXbufPtr->TX[tempTX_Head]= data;
/* Advance buffer head. */
TXbufPtr->TX_Head = (tempTX_Head + 1) & USART_TX_BUFFER_MASK;
/* Enable DRE interrupt. */
tempCTRLA = usart_data->usart->CTRLA;
tempCTRLA = (tempCTRLA & ~USART_DREINTLVL_gm) | usart_data->dreIntLevel;
usart_data->usart->CTRLA = tempCTRLA;
}
return TXBuffer_FreeSpace;
}
_Bool USART_RXBufferData_Available(USART_data_t * usart_data)
{
/* Make copies to make sure that volatile access is specified. */
uint8_t tempHead = usart_data->buffer.RX_Head;
uint8_t tempTail = usart_data->buffer.RX_Tail;
/* There are data left in the buffer unless Head and Tail are equal. */
return (tempHead != tempTail);
}
uint8_t USART_RXBuffer_GetByte(USART_data_t * usart_data)
{
USART_Buffer_t * bufPtr;
uint8_t ans;
bufPtr = &usart_data->buffer;
ans = (bufPtr->RX[bufPtr->RX_Tail]);
/* Advance buffer tail. */
bufPtr->RX_Tail = (bufPtr->RX_Tail + 1) & USART_RX_BUFFER_MASK;
return ans;
}
_Bool USART_RXComplete(USART_data_t * usart_data)
{
USART_Buffer_t * bufPtr;