mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-16 02:33:28 +00:00
machine/atmega328pb: refactor to enable extra uart
This commit is contained in:
@@ -4,10 +4,105 @@ package machine
|
||||
|
||||
import (
|
||||
"device/avr"
|
||||
"runtime/interrupt"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
const irq_USART0_RX = avr.IRQ_USART0_RX
|
||||
const irq_USART1_RX = avr.IRQ_USART1_RX
|
||||
|
||||
var (
|
||||
UART1 = &_UART1
|
||||
_UART1 = UART{
|
||||
Buffer: NewRingBuffer(),
|
||||
|
||||
dataReg: avr.UDR1,
|
||||
baudRegH: avr.UBRR1H,
|
||||
baudRegL: avr.UBRR1L,
|
||||
statusRegA: avr.UCSR1A,
|
||||
statusRegB: avr.UCSR1B,
|
||||
statusRegC: avr.UCSR1C,
|
||||
}
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Register the UART interrupt.
|
||||
interrupt.New(irq_USART1_RX, _UART1.handleInterrupt)
|
||||
}
|
||||
|
||||
// I2C0 is the only I2C interface on most AVRs.
|
||||
var I2C0 = &I2C{
|
||||
srReg: avr.TWSR0,
|
||||
brReg: avr.TWBR0,
|
||||
crReg: avr.TWCR0,
|
||||
drReg: avr.TWDR0,
|
||||
srPS0: avr.TWSR0_TWPS0,
|
||||
srPS1: avr.TWSR0_TWPS1,
|
||||
crEN: avr.TWCR0_TWEN,
|
||||
crINT: avr.TWCR0_TWINT,
|
||||
crSTO: avr.TWCR0_TWSTO,
|
||||
crEA: avr.TWCR0_TWEA,
|
||||
crSTA: avr.TWCR0_TWSTA,
|
||||
}
|
||||
|
||||
var I2C1 = &I2C{
|
||||
srReg: avr.TWSR1,
|
||||
brReg: avr.TWBR1,
|
||||
crReg: avr.TWCR1,
|
||||
drReg: avr.TWDR1,
|
||||
srPS0: avr.TWSR1_TWPS10,
|
||||
srPS1: avr.TWSR1_TWPS11,
|
||||
crEN: avr.TWCR1_TWEN1,
|
||||
crINT: avr.TWCR1_TWINT1,
|
||||
crSTO: avr.TWCR1_TWSTO1,
|
||||
crEA: avr.TWCR1_TWEA1,
|
||||
crSTA: avr.TWCR1_TWSTA1,
|
||||
}
|
||||
|
||||
// SPI configuration
|
||||
var SPI0 = SPI{
|
||||
spcr: avr.SPCR0,
|
||||
spdr: avr.SPDR0,
|
||||
spsr: avr.SPSR0,
|
||||
|
||||
spcrR0: avr.SPCR0_SPR0,
|
||||
spcrR1: avr.SPCR0_SPR1,
|
||||
spcrCPHA: avr.SPCR0_CPHA,
|
||||
spcrCPOL: avr.SPCR0_CPOL,
|
||||
spcrDORD: avr.SPCR0_DORD,
|
||||
spcrSPE: avr.SPCR0_SPE,
|
||||
spcrMSTR: avr.SPCR0_MSTR,
|
||||
|
||||
spsrI2X: avr.SPSR0_SPI2X,
|
||||
spsrSPIF: avr.SPSR0_SPIF,
|
||||
|
||||
sck: PB5,
|
||||
sdo: PB3,
|
||||
sdi: PB4,
|
||||
cs: PB2,
|
||||
}
|
||||
|
||||
var SPI1 = SPI{
|
||||
spcr: avr.SPCR1,
|
||||
spdr: avr.SPDR1,
|
||||
spsr: avr.SPSR1,
|
||||
|
||||
spcrR0: avr.SPCR1_SPR10,
|
||||
spcrR1: avr.SPCR1_SPR11,
|
||||
spcrCPHA: avr.SPCR1_CPHA1,
|
||||
spcrCPOL: avr.SPCR1_CPOL1,
|
||||
spcrDORD: avr.SPCR1_DORD1,
|
||||
spcrSPE: avr.SPCR1_SPE1,
|
||||
spcrMSTR: avr.SPCR1_MSTR1,
|
||||
|
||||
spsrI2X: avr.SPSR1_SPI2X1,
|
||||
spsrSPIF: avr.SPSR1_SPIF1,
|
||||
|
||||
sck: PC1,
|
||||
sdo: PE3,
|
||||
sdi: PC0,
|
||||
cs: PE2,
|
||||
}
|
||||
|
||||
// getPortMask returns the PORTx register and mask for the pin.
|
||||
func (p Pin) getPortMask() (*volatile.Register8, uint8) {
|
||||
@@ -16,94 +111,9 @@ func (p Pin) getPortMask() (*volatile.Register8, uint8) {
|
||||
return avr.PORTB, 1 << uint8(p-portB)
|
||||
case p >= PC0 && p <= PC7: // port C
|
||||
return avr.PORTC, 1 << uint8(p-portC)
|
||||
default: // port D
|
||||
case p >= PD0 && p <= PD7: // port D
|
||||
return avr.PORTD, 1 << uint8(p-portD)
|
||||
default: // port E
|
||||
return avr.PORTE, 1 << uint8(p-portE)
|
||||
}
|
||||
}
|
||||
|
||||
// InitPWM initializes the registers needed for PWM.
|
||||
func InitPWM() {
|
||||
// use waveform generation
|
||||
avr.TCCR0A.SetBits(avr.TCCR0A_WGM00)
|
||||
|
||||
// set timer 0 prescale factor to 64
|
||||
avr.TCCR0B.SetBits(avr.TCCR0B_CS01 | avr.TCCR0B_CS00)
|
||||
|
||||
// set timer 1 prescale factor to 64
|
||||
avr.TCCR1B.SetBits(avr.TCCR1B_CS11)
|
||||
|
||||
// put timer 1 in 8-bit phase correct pwm mode
|
||||
avr.TCCR1A.SetBits(avr.TCCR1A_WGM10)
|
||||
|
||||
// set timer 2 prescale factor to 64
|
||||
avr.TCCR2B.SetBits(avr.TCCR2B_CS22)
|
||||
|
||||
// configure timer 2 for phase correct pwm (8-bit)
|
||||
avr.TCCR2A.SetBits(avr.TCCR2A_WGM20)
|
||||
}
|
||||
|
||||
// Configure configures a PWM pin for output.
|
||||
func (pwm PWM) Configure() error {
|
||||
switch pwm.Pin / 8 {
|
||||
case 0: // port B
|
||||
avr.DDRB.SetBits(1 << uint8(pwm.Pin))
|
||||
case 2: // port D
|
||||
avr.DDRD.SetBits(1 << uint8(pwm.Pin-16))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Set turns on the duty cycle for a PWM pin using the provided value. On the AVR this is normally a
|
||||
// 8-bit value ranging from 0 to 255.
|
||||
func (pwm PWM) Set(value uint16) {
|
||||
value8 := uint8(value >> 8)
|
||||
switch pwm.Pin {
|
||||
case PD3:
|
||||
// connect pwm to pin on timer 2, channel B
|
||||
avr.TCCR2A.SetBits(avr.TCCR2A_COM2B1)
|
||||
avr.OCR2B.Set(value8) // set pwm duty
|
||||
case PD5:
|
||||
// connect pwm to pin on timer 0, channel B
|
||||
avr.TCCR0A.SetBits(avr.TCCR0A_COM0B1)
|
||||
avr.OCR0B.Set(value8) // set pwm duty
|
||||
case PD6:
|
||||
// connect pwm to pin on timer 0, channel A
|
||||
avr.TCCR0A.SetBits(avr.TCCR0A_COM0A1)
|
||||
avr.OCR0A.Set(value8) // set pwm duty
|
||||
case PB1:
|
||||
// connect pwm to pin on timer 1, channel A
|
||||
avr.TCCR1A.SetBits(avr.TCCR1A_COM1A1)
|
||||
// this is a 16-bit value, but we only currently allow the low order bits to be set
|
||||
avr.OCR1AL.Set(value8) // set pwm duty
|
||||
case PB2:
|
||||
// connect pwm to pin on timer 1, channel B
|
||||
avr.TCCR1A.SetBits(avr.TCCR1A_COM1B1)
|
||||
// this is a 16-bit value, but we only currently allow the low order bits to be set
|
||||
avr.OCR1BL.Set(value8) // set pwm duty
|
||||
case PB3:
|
||||
// connect pwm to pin on timer 2, channel A
|
||||
avr.TCCR2A.SetBits(avr.TCCR2A_COM2A1)
|
||||
avr.OCR2A.Set(value8) // set pwm duty
|
||||
default:
|
||||
panic("Invalid PWM pin")
|
||||
}
|
||||
}
|
||||
|
||||
// SPI configuration
|
||||
var SPI0 = SPI{
|
||||
spcr: avr.SPCR0,
|
||||
spdr: avr.SPDR0,
|
||||
spsr: avr.SPSR0,
|
||||
sck: PB5,
|
||||
sdo: PB3,
|
||||
sdi: PB4,
|
||||
cs: PB2}
|
||||
|
||||
var SPI1 = SPI{
|
||||
spcr: avr.SPCR1,
|
||||
spdr: avr.SPDR1,
|
||||
spsr: avr.SPSR1,
|
||||
sck: PC1,
|
||||
sdo: PE3,
|
||||
sdi: PC0,
|
||||
cs: PE2}
|
||||
|
||||
Reference in New Issue
Block a user