Last active
June 11, 2018 19:32
-
-
Save keybuk/e61d0354580e67f4ce310400b101578a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
import RaspberryPi | |
// Shutdown PWM1, clear FIFO | |
let pwm = try! PWM() | |
pwm[1].isEnabled = false | |
pwm.clearFifo() | |
// Stop the PWM clock | |
let clock = try! Clock() | |
clock[.pwm].isEnabled = false | |
while clock[.pwm].isRunning {} | |
// Grab DMA 4 | |
let dma = try! DMA() | |
dma[4].isActive = false | |
dma[4].reset() | |
// Set GPIO12 to output from PWM1 | |
let gpio = try! GPIO() | |
gpio[12].function = .alternateFunction0 | |
// Set PWM1 to use DMA + FIFO in 16-bit Serializer mode | |
pwm.isDMAEnabled = true | |
pwm[1].useFifo = true | |
pwm[1].mode = .serializer | |
pwm[1].range = 16 | |
// Set the PWM clock to 0.1ms ticks | |
clock[.pwm].source = .oscillator | |
clock[.pwm].mash = 0 | |
clock[.pwm].divisor = ClockDivisor(integer: 1_920, fractional: 0) | |
// Allocate a data area for control blocks and data | |
let memory = try! UncachedMemory(minimumSize: MemoryLayout<DMAControlBlock>.stride + MemoryLayout<UInt32>.stride * 256) | |
let controlBlocks = memory.pointer.bindMemory(to: DMAControlBlock.self, capacity: 1) | |
let words = memory.pointer.advanced(by: MemoryLayout<DMAControlBlock>.stride).bindMemory(to: UInt32.self, capacity: 256) | |
// Fill the memory with the binary of 0...255, shift left because PWM uses the MSB of the data. | |
// (We output 8-bits of number, and an 8-bit gap of 0 because the serializer range is 16-bits) | |
for i in 0..<256 { | |
words[i] = UInt32(i) << 24 | |
} | |
controlBlocks[0].peripheral = .pwm | |
controlBlocks[0].waitForWriteResponse = true | |
controlBlocks[0].sourceAddress = memory.busAddress + UInt32(MemoryLayout<DMAControlBlock>.stride) | |
controlBlocks[0].incrementSourceAddress = true | |
controlBlocks[0].destinationAddress = PWM.busAddress + 0x18 /* MemoryLayout.offset(of: \PWM.Registers.fifoInput) */ | |
controlBlocks[0].destinationWaitsForDataRequest = true | |
controlBlocks[0].transferLength = UInt32(MemoryLayout<UInt32>.stride) * 256 | |
controlBlocks[0].nextControlBlockAddress = memory.busAddress | |
// Enable the PWM | |
pwm[1].isEnabled = true | |
// Start the Clock | |
clock[.pwm].isEnabled = true | |
while !clock[.pwm].isRunning {} | |
// Enable the DMA | |
dma[4].controlBlockAddress = memory.busAddress | |
dma[4].isActive = true | |
debugPrint(gpio[12]) | |
debugPrint(pwm[1]) | |
debugPrint(clock[.pwm]) | |
debugPrint(dma[4]) | |
print("Running, press ENTER to stop") | |
let _ = readLine() | |
// Shutdown | |
dma[4].isActive = false | |
pwm[1].isEnabled = false | |
clock[.pwm].isEnabled = false | |
while clock[.pwm].isRunning {} | |
try! memory.deallocate() | |
print("Bye!") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment