avr: initial implementation for PWM

Signed-off-by: Ron Evans <ron@hybridgroup.com>

Edited slightly by Ayke van Laethem
Этот коммит содержится в:
Ron Evans 2018-09-14 14:42:47 +02:00 коммит произвёл Ayke van Laethem
родитель 94358959f5
коммит fc0ff3a987
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: E97FF5335DFDFDED
5 изменённых файлов: 142 добавлений и 6 удалений

54
src/examples/pwm/pwm.go Обычный файл
Просмотреть файл

@ -0,0 +1,54 @@
package main
import (
"machine"
"time"
)
// This example assumes that an RGB LED is connected to pins 3, 5 and 6 on an Arduino.
// Change the values below to use different pins.
const (
redPin = 3
greenPin = 5
bluePin = 6
)
// cycleColor is just a placeholder until math/rand or some equivalent is working.
func cycleColor(color uint8) uint8 {
if color < 10 {
return color + 1
} else if color < 200 {
return color + 10
} else {
return 0
}
}
func main() {
machine.InitPWM()
red := machine.PWM{redPin}
red.Configure()
green := machine.PWM{greenPin}
green.Configure()
blue := machine.PWM{bluePin}
blue.Configure()
var rc uint8
var gc uint8 = 20
var bc uint8 = 30
for {
rc = cycleColor(rc)
gc = cycleColor(gc)
bc = cycleColor(bc)
red.Set(uint16(rc) << 8)
green.Set(uint16(gc) << 8)
blue.Set(uint16(bc) << 8)
time.Sleep(time.Millisecond * 500)
}
}

Просмотреть файл

@ -15,3 +15,7 @@ func (p GPIO) High() {
func (p GPIO) Low() {
p.Set(false)
}
type PWM struct {
Pin uint8
}

Просмотреть файл

@ -58,3 +58,69 @@ func (p GPIO) Get() bool {
return (val > 0)
}
}
// InitPWM initializes the registers needed for PWM.
func InitPWM() {
// use waveform generation
*avr.TCCR0A |= avr.TCCR0A_WGM00
// set timer 0 prescale factor to 64
*avr.TCCR0B |= avr.TCCR0B_CS01 | avr.TCCR0B_CS00
// set timer 1 prescale factor to 64
*avr.TCCR1B |= avr.TCCR1B_CS11
// put timer 1 in 8-bit phase correct pwm mode
*avr.TCCR1A |= avr.TCCR1A_WGM10
// set timer 2 prescale factor to 64
*avr.TCCR2B |= avr.TCCR2B_CS22
// configure timer 2 for phase correct pwm (8-bit)
*avr.TCCR2A |= avr.TCCR2A_WGM20
}
// Configure configures a PWM pin for output.
func (pwm PWM) Configure() {
if pwm.Pin < 8 {
*avr.DDRD |= 1 << pwm.Pin
} else {
*avr.DDRB |= 1 << (pwm.Pin - 8)
}
}
// 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 := value >> 8
switch pwm.Pin {
case 3:
// connect pwm to pin on timer 2, channel B
*avr.TCCR2A |= avr.TCCR2A_COM2B1
*avr.OCR2B = avr.RegValue(value8) // set pwm duty
case 5:
// connect pwm to pin on timer 0, channel B
*avr.TCCR0A |= avr.TCCR0A_COM0B1
*avr.OCR0B = avr.RegValue(value8) // set pwm duty
case 6:
// connect pwm to pin on timer 0, channel A
*avr.TCCR0A |= avr.TCCR0A_COM0A1
*avr.OCR0A = avr.RegValue(value8) // set pwm duty
case 9:
// connect pwm to pin on timer 1, channel A
*avr.TCCR1A |= avr.TCCR1A_COM1A1
// this is a 16-bit value, but we only currently allow the low order bits to be set
*avr.OCR1AL = avr.RegValue(value8) // set pwm duty
case 10:
// connect pwm to pin on timer 1, channel B
*avr.TCCR1A |= avr.TCCR1A_COM1B1
// this is a 16-bit value, but we only currently allow the low order bits to be set
*avr.OCR1BL = avr.RegValue(value8) // set pwm duty
case 11:
// connect pwm to pin on timer 2, channel A
*avr.TCCR2A |= avr.TCCR2A_COM2A1
*avr.OCR2A = avr.RegValue(value8) // set pwm duty
default:
panic("Invalid PWM pin")
}
}

Просмотреть файл

@ -57,7 +57,7 @@ func initUART() {
*avr.UBRR0H = 0
*avr.UBRR0L = 8
*avr.UCSR0B = avr.UCSR0B_RXEN0 | avr.UCSR0B_TXEN0 // enable RX and TX
*avr.UCSR0C = avr.UCSR0C_UCSZ0 // 8-bits data
*avr.UCSR0C = avr.UCSR0C_UCSZ01 | avr.UCSR0C_UCSZ00 // 8-bits data
}
func putchar(c byte) {

Просмотреть файл

@ -183,10 +183,22 @@ const (
out.write(': {description}'.format(**register))
out.write('\n')
for bitfield in register['bitfields']:
name = bitfield['name']
value = bitfield['value']
if '{:08b}'.format(value).count('1') == 1:
out.write('\t{name} = 0x{value:x}'.format(**bitfield))
if bitfield['description']:
out.write(' // {description}'.format(**bitfield))
out.write('\n')
else:
n = 0
for i in range(8):
if (value >> i) & 1 == 0: continue
out.write('\t{}{} = 0x{:x}'.format(name, n, 1 << i))
if bitfield['description']:
out.write(' // {description}'.format(**bitfield))
n += 1
out.write('\n')
out.write(')\n')
def writeLD(outdir, device):