Skip to content

Commit 0ea60fd

Browse files
committed
64bit Cleanup
This adds compatibility to 64Bit Linux, derived from work by @Kaiede in PR #76. Added a comment in the PWM section for what could be a source of issues when configuring the DMA on 64bit systems. Need to check the official docs for more info on this.
1 parent f1c9b44 commit 0ea60fd

File tree

2 files changed

+73
-73
lines changed

2 files changed

+73
-73
lines changed

Sources/PWM.swift

+61-61
Original file line numberDiff line numberDiff line change
@@ -91,12 +91,12 @@ public class RaspberryPWM: PWMOutput {
9191
let BCM2708_PHY_BASE: Int = 0x7e000000
9292
let PWM_PHY_BASE: Int
9393

94-
var gpioBasePointer: UnsafeMutablePointer<UInt>!
95-
var pwmBasePointer: UnsafeMutablePointer<UInt>!
96-
var clockBasePointer: UnsafeMutablePointer<UInt>!
97-
var dmaBasePointer: UnsafeMutablePointer<UInt>!
94+
var gpioBasePointer: UnsafeMutablePointer<UInt32>!
95+
var pwmBasePointer: UnsafeMutablePointer<UInt32>!
96+
var clockBasePointer: UnsafeMutablePointer<UInt32>!
97+
var dmaBasePointer: UnsafeMutablePointer<UInt32>!
9898
var dmaCallbackPointer: UnsafeMutablePointer<DMACallback>! = nil
99-
var pwmRawPointer: UnsafeMutablePointer<UInt>! = nil
99+
var pwmRawPointer: UnsafeMutablePointer<UInt32>! = nil
100100
var mailbox: MailBox! = nil
101101

102102
var zeroPattern: Int = 0
@@ -148,7 +148,7 @@ public class RaspberryPWM: PWMOutput {
148148
dma_addr -= pageOffset
149149

150150
let dma_map = UnsafeMutableRawPointer(memmap(from: mem_fd, at: dma_addr))
151-
dmaBasePointer = (dma_map + pageOffset).assumingMemoryBound(to: UInt.self)
151+
dmaBasePointer = (dma_map + pageOffset).assumingMemoryBound(to: UInt32.self)
152152

153153
close(mem_fd)
154154

@@ -165,10 +165,10 @@ public class RaspberryPWM: PWMOutput {
165165
usleep(10)
166166

167167
// If the required frequency is too high, this value reduces the number of samples (scale does the opposite)
168-
let highFreqSampleReduction: UInt = (ns < 750) ? 10 : 1
168+
let highFreqSampleReduction: UInt32 = (ns < 750) ? 10 : 1
169169

170-
let freq: UInt = (1_000_000_000/UInt(ns)) * 100 / highFreqSampleReduction
171-
let (idiv, scale) = calculateDIVI(base: .PLLD, desired: freq) //Using the faster (with known freq) available clock to reduce jitter
170+
let freq = UInt32( (1_000_000_000/UInt(ns)) * 100 / UInt(highFreqSampleReduction) )
171+
let (idiv, scale) = calculateDIVI(base: .PLLD, desired: UInt32(freq)) //Using the faster (with known freq) available clock to reduce jitter
172172

173173
// Configure the clock and divisor that will be used to generate the signal
174174
clockBasePointer.advanced(by: 41).pointee = CLKM_PASSWD | (idiv << CLKM_DIV_DIVI) //CM CTL DIV register: Set DIVI value
@@ -179,7 +179,7 @@ public class RaspberryPWM: PWMOutput {
179179
let RNG = (channel == 0) ? 4 : 8
180180
let DAT = (channel == 0) ? 5 : 9
181181
pwmBasePointer.advanced(by: RNG).pointee = 100 * scale / highFreqSampleReduction //RNG1 register
182-
pwmBasePointer.advanced(by: DAT).pointee = UInt((percent / Float(highFreqSampleReduction)) * Float(scale)) //DAT1 register
182+
pwmBasePointer.advanced(by: DAT).pointee = UInt32((percent / Float(highFreqSampleReduction)) * Float(scale)) //DAT1 register
183183
let PWMCTL_MSEN = (channel == 0) ? PWMCTL_MSEN1 : PWMCTL_MSEN2
184184
let PWMCTL_PWEN = (channel == 0) ? PWMCTL_PWEN1 : PWMCTL_PWEN2
185185
pwmBasePointer.pointee = PWMCTL_MSEN | PWMCTL_PWEN //PWM CTL register, channel enabled, M/S mode
@@ -190,7 +190,7 @@ public class RaspberryPWM: PWMOutput {
190190
}
191191

192192
/// Maps a block of memory and returns the pointer
193-
internal func memmap(from mem_fd: Int32, at offset: Int) -> UnsafeMutablePointer<UInt> {
193+
internal func memmap(from mem_fd: Int32, at offset: Int) -> UnsafeMutablePointer<UInt32> {
194194
let m = mmap(
195195
nil, //Any adddress in our space will do
196196
PAGE_SIZE, //Map length
@@ -204,17 +204,17 @@ public class RaspberryPWM: PWMOutput {
204204
perror("mmap error")
205205
abort()
206206
}
207-
let pointer = m.assumingMemoryBound(to: UInt.self)
207+
let pointer = m.assumingMemoryBound(to: UInt32.self)
208208

209209
return pointer
210210
}
211211

212212
/// Set the alternative function for this GPIO
213213
internal func setAlt() {
214-
let altid = (self.alt<=3) ? self.alt+4 : self.alt==4 ? 3 : 2
214+
let altid = (self.alt<=3) ? UInt32(self.alt+4) : self.alt==4 ? UInt32(3) : UInt32(2)
215215
let ptr = gpioBasePointer.advanced(by: Int(gpioId/10)) // GPFSELn 0..5
216-
ptr.pointee &= ~(7<<((gpioId%10)*3))
217-
ptr.pointee |= (altid<<((gpioId%10)*3))
216+
ptr.pointee &= ~(7<<((UInt32(gpioId)%10)*3))
217+
ptr.pointee |= (altid<<((UInt32(gpioId)%10)*3))
218218
}
219219

220220
/// Calculate the DIVI value that will divide the selected base clock frequency to obtain the desired frequency.
@@ -230,9 +230,9 @@ public class RaspberryPWM: PWMOutput {
230230
///
231231
/// - Returns: divi divisor value, and scale value as a multiple of ten
232232
///
233-
internal func calculateDIVI(base: ClockSource, desired: UInt) -> (divi: UInt, scale: UInt) {
234-
var divi: UInt = base.rawValue/desired
235-
var scale: UInt = 1
233+
internal func calculateDIVI(base: ClockSource, desired: UInt32) -> (divi: UInt32, scale: UInt32) {
234+
var divi: UInt32 = base.rawValue/desired
235+
var scale: UInt32 = 1
236236

237237
while divi > 0x800 {
238238
// Divisor too high (greater then half the limit), would not be generated properly
@@ -255,8 +255,8 @@ public class RaspberryPWM: PWMOutput {
255255
///
256256
/// - Returns: divi divisor value
257257
///
258-
internal func calculateUnscaledDIVI(base: ClockSource, desired: UInt) -> UInt {
259-
var divi: UInt = base.rawValue/desired
258+
internal func calculateUnscaledDIVI(base: ClockSource, desired: UInt32) -> UInt32 {
259+
var divi: UInt32 = base.rawValue/desired
260260

261261
if divi > 0x1000 {
262262
// Divisor too high (greater then half the limit), would not be generated properly
@@ -278,7 +278,7 @@ extension RaspberryPWM {
278278
dmaBasePointer.pointee = DMACS_RESET
279279
usleep(10)
280280
dmaBasePointer.pointee = DMACS_INT | DMACS_END
281-
dmaBasePointer.advanced(by: 1).pointee = address //CONBLK_AD
281+
dmaBasePointer.advanced(by: 1).pointee = UInt32(address) //CONBLK_AD //Verify this on 64bit
282282
dmaBasePointer.advanced(by: 8).pointee = 7 //DEBUG: clear debug error flags
283283
dmaBasePointer.pointee = DMACS_WAIT_OUTSTANDING_WRITES | (15 << DMACS_PANIC_PRIORITY) | (15 << DMACS_PRIORITY) | DMACS_ACTIVE
284284
}
@@ -340,7 +340,7 @@ extension RaspberryPWM {
340340
guard let mailbox = mailbox else {fatalError("Could allocate mailbox.")}
341341

342342
dmaCallbackPointer = mailbox.baseVirtualAddress.assumingMemoryBound(to: DMACallback.self)
343-
pwmRawPointer = (mailbox.baseVirtualAddress + MemoryLayout<DMACallback>.stride).assumingMemoryBound(to: UInt.self)
343+
pwmRawPointer = (mailbox.baseVirtualAddress + MemoryLayout<DMACallback>.stride).assumingMemoryBound(to: UInt32.self)
344344

345345
// Fill PWM buffer with zeros
346346
let rows = dataSize / MemoryLayout<UInt>.stride
@@ -358,7 +358,7 @@ extension RaspberryPWM {
358358
//while (clockBasePointer.advanced(by: 40).pointee & (1 << 7)) != 0 {}
359359

360360
// Configure clock
361-
let idiv = calculateUnscaledDIVI(base: .PLLD, desired: UInt(symbolBits * patternFrequency))
361+
let idiv = calculateUnscaledDIVI(base: .PLLD, desired: UInt32(symbolBits * patternFrequency))
362362
clockBasePointer.advanced(by: 41).pointee = CLKM_PASSWD | (idiv << CLKM_DIV_DIVI) //Set DIVI value
363363
clockBasePointer.advanced(by: 40).pointee = CLKM_PASSWD | CLKM_CTL_ENAB | CLKM_CTL_SRC_PLLD //Enable clock, MASH 0, source PLLD
364364
usleep(10)
@@ -551,34 +551,34 @@ extension RaspberryPWM {
551551
// MARK: - PWM Contants
552552

553553
// Constants for the Clock Manager General Purpose Control Register
554-
let CLKM_PASSWD: UInt = 0x5A000000
555-
let CLKM_CTL_KILL: UInt = (1 << 5)
556-
let CLKM_CTL_ENAB: UInt = (1 << 4)
557-
let CLKM_CTL_SRC_OSC: UInt = 1 // 19.2 MHz oscillator
558-
let CLKM_CTL_SRC_PLLA: UInt = 4 // ~393.216 MHz PLLA (Audio)
559-
let CLKM_CTL_SRC_PLLC: UInt = 5 // 1000 MHz PLLC (changes with overclock settings)
560-
let CLKM_CTL_SRC_PLLD: UInt = 6 // 500 MHz PLLD
561-
let CLKM_CTL_SRC_HDMI: UInt = 7 // 216 MHz HDMI auxiliary
554+
let CLKM_PASSWD: UInt32 = 0x5A000000
555+
let CLKM_CTL_KILL: UInt32 = (1 << 5)
556+
let CLKM_CTL_ENAB: UInt32 = (1 << 4)
557+
let CLKM_CTL_SRC_OSC: UInt32 = 1 // 19.2 MHz oscillator
558+
let CLKM_CTL_SRC_PLLA: UInt32 = 4 // ~393.216 MHz PLLA (Audio)
559+
let CLKM_CTL_SRC_PLLC: UInt32 = 5 // 1000 MHz PLLC (changes with overclock settings)
560+
let CLKM_CTL_SRC_PLLD: UInt32 = 6 // 500 MHz PLLD
561+
let CLKM_CTL_SRC_HDMI: UInt32 = 7 // 216 MHz HDMI auxiliary
562562
// Constants for the Clock Manager General Purpose Divisors Register
563-
let CLKM_DIV_DIVI: UInt = 12
564-
let CLKM_DIV_DIVF: UInt = 0
563+
let CLKM_DIV_DIVI: UInt32 = 12
564+
let CLKM_DIV_DIVF: UInt32 = 0
565565
// Constants for the PWM Control Register
566-
let PWMCTL_MSEN2: UInt = (1 << 15)
566+
let PWMCTL_MSEN2: UInt32 = (1 << 15)
567567
// No PWMCTL_CLRF2, the FIFO is shared
568-
let PWMCTL_USEF2: UInt = (1 << 13)
569-
let PWMCTL_POLA2: UInt = (1 << 12)
570-
let PWMCTL_SBIT2: UInt = (1 << 11)
571-
let PWMCTL_RPTL2: UInt = (1 << 10)
572-
let PWMCTL_MODE2: UInt = (1 << 9)
573-
let PWMCTL_PWEN2: UInt = (1 << 8)
574-
let PWMCTL_MSEN1: UInt = (1 << 7)
575-
let PWMCTL_CLRF1: UInt = (1 << 6)
576-
let PWMCTL_USEF1: UInt = (1 << 5)
577-
let PWMCTL_POLA1: UInt = (1 << 4)
578-
let PWMCTL_SBIT1: UInt = (1 << 3)
579-
let PWMCTL_RPTL1: UInt = (1 << 2)
580-
let PWMCTL_MODE1: UInt = (1 << 1)
581-
let PWMCTL_PWEN1: UInt = (1 << 0)
568+
let PWMCTL_USEF2: UInt32 = (1 << 13)
569+
let PWMCTL_POLA2: UInt32 = (1 << 12)
570+
let PWMCTL_SBIT2: UInt32 = (1 << 11)
571+
let PWMCTL_RPTL2: UInt32 = (1 << 10)
572+
let PWMCTL_MODE2: UInt32 = (1 << 9)
573+
let PWMCTL_PWEN2: UInt32 = (1 << 8)
574+
let PWMCTL_MSEN1: UInt32 = (1 << 7)
575+
let PWMCTL_CLRF1: UInt32 = (1 << 6)
576+
let PWMCTL_USEF1: UInt32 = (1 << 5)
577+
let PWMCTL_POLA1: UInt32 = (1 << 4)
578+
let PWMCTL_SBIT1: UInt32 = (1 << 3)
579+
let PWMCTL_RPTL1: UInt32 = (1 << 2)
580+
let PWMCTL_MODE1: UInt32 = (1 << 1)
581+
let PWMCTL_PWEN1: UInt32 = (1 << 0)
582582

583583
// Clock sources
584584
// 0 0 Hz Ground
@@ -590,7 +590,7 @@ let PWMCTL_PWEN1: UInt = (1 << 0)
590590
// 6 500 MHz PLLD
591591
// 7 216 MHz HDMI auxiliary
592592
// 8-15 0 Hz Ground
593-
enum ClockSource: UInt {
593+
enum ClockSource: UInt32 {
594594
case Oscillator = 19200000
595595
case PLLA = 393216000
596596
case PLLC = 1000000000
@@ -599,15 +599,15 @@ enum ClockSource: UInt {
599599
}
600600

601601
// DMA Register
602-
let DMACS_RESET: UInt = (1 << 31)
603-
let DMACS_ABORT: UInt = (1 << 30)
604-
let DMACS_WAIT_OUTSTANDING_WRITES: UInt = (1 << 28)
605-
let DMACS_PANIC_PRIORITY: UInt = 20 // <<
606-
let DMACS_PRIORITY: UInt = 16 // <<
607-
let DMACS_ERROR: UInt = (1 << 8)
608-
let DMACS_INT: UInt = (1 << 2)
609-
let DMACS_END: UInt = (1 << 1)
610-
let DMACS_ACTIVE: UInt = (1 << 0)
602+
let DMACS_RESET: UInt32 = (1 << 31)
603+
let DMACS_ABORT: UInt32 = (1 << 30)
604+
let DMACS_WAIT_OUTSTANDING_WRITES: UInt32 = (1 << 28)
605+
let DMACS_PANIC_PRIORITY: UInt32 = 20 // <<
606+
let DMACS_PRIORITY: UInt32 = 16 // <<
607+
let DMACS_ERROR: UInt32 = (1 << 8)
608+
let DMACS_INT: UInt32 = (1 << 2)
609+
let DMACS_END: UInt32 = (1 << 1)
610+
let DMACS_ACTIVE: UInt32 = (1 << 0)
611611

612612
/*
613613
* DMA Control Block in Main Memory
@@ -627,9 +627,9 @@ struct DMACallback {
627627
}
628628

629629
// PWM DMAC Register
630-
let PWMDMAC_ENAB: UInt = (1 << 31)
631-
let PWMDMAC_PANIC: UInt = 8
632-
let PWMDMAC_DREQ: UInt = 0
630+
let PWMDMAC_ENAB: UInt32 = (1 << 31)
631+
let PWMDMAC_PANIC: UInt32 = 8
632+
let PWMDMAC_DREQ: UInt32 = 0
633633

634634
// DMA Register
635635
let DMATI_NO_WIDE_BURSTS: UInt32 = (1 << 26)

Sources/SwiftyGPIO.swift

+12-12
Original file line numberDiff line numberDiff line change
@@ -280,20 +280,20 @@ extension GPIO: CustomStringConvertible {
280280

281281
public final class RaspberryGPIO: GPIO {
282282

283-
var setGetId: UInt = 0
283+
var setGetId: UInt32 = 0
284284
var baseAddr: Int = 0
285285
var inited = false
286286

287287
let BCM2708_PERI_BASE: Int
288288
let GPIO_BASE: Int
289289

290-
var gpioBasePointer: UnsafeMutablePointer<UInt>!
291-
var gpioGetPointer: UnsafeMutablePointer<UInt>!
292-
var gpioSetPointer: UnsafeMutablePointer<UInt>!
293-
var gpioClearPointer: UnsafeMutablePointer<UInt>!
290+
var gpioBasePointer: UnsafeMutablePointer<UInt32>!
291+
var gpioGetPointer: UnsafeMutablePointer<UInt32>!
292+
var gpioSetPointer: UnsafeMutablePointer<UInt32>!
293+
var gpioClearPointer: UnsafeMutablePointer<UInt32>!
294294

295295
public init(name: String, id: Int, baseAddr: Int) {
296-
self.setGetId = UInt(1<<id)
296+
self.setGetId = UInt32(1<<id)
297297
self.BCM2708_PERI_BASE = baseAddr
298298
self.GPIO_BASE = BCM2708_PERI_BASE + 0x200000 /* GPIO controller */
299299
super.init(name:name, id:id)
@@ -368,7 +368,7 @@ public final class RaspberryGPIO: GPIO {
368368
perror("mmap error")
369369
abort()
370370
}
371-
gpioBasePointer = gpio_map.assumingMemoryBound(to: UInt.self)
371+
gpioBasePointer = gpio_map.assumingMemoryBound(to: UInt32.self)
372372

373373
gpioGetPointer = gpioBasePointer.advanced(by: 13) // GPLEV0
374374
gpioSetPointer = gpioBasePointer.advanced(by: 7) // GPSET0
@@ -379,18 +379,18 @@ public final class RaspberryGPIO: GPIO {
379379

380380
private func gpioAsInput() {
381381
let ptr = gpioBasePointer.advanced(by: id/10) // GPFSELn 0..5
382-
ptr.pointee &= ~(7<<((UInt(id)%10)*3)) // SEL=000 input
382+
ptr.pointee &= ~(7<<((UInt32(id)%10)*3)) // SEL=000 input
383383
}
384384

385385
private func gpioAsOutput() {
386386
let ptr = gpioBasePointer.advanced(by: id/10) // GPFSELn 0..5
387-
ptr.pointee &= ~(7<<((UInt(id)%10)*3))
388-
ptr.pointee |= (1<<((UInt(id)%10)*3)) // SEL=001 output
387+
ptr.pointee &= ~(7<<((UInt32(id)%10)*3))
388+
ptr.pointee |= (1<<((UInt32(id)%10)*3)) // SEL=001 output
389389
}
390390

391391
private func gpioGetDirection() -> GPIODirection {
392392
let ptr = gpioBasePointer.advanced(by: id/10) // GPFSELn 0..5
393-
let d = (ptr.pointee & (7<<((UInt(id)%10)*3)))
393+
let d = (ptr.pointee & (7<<((UInt32(id)%10)*3)))
394394
return (d == 0) ? .IN : .OUT
395395
}
396396

@@ -521,7 +521,7 @@ public enum GPIOEdge: String {
521521
case BOTH="both"
522522
}
523523

524-
public enum GPIOPull: UInt {
524+
public enum GPIOPull: UInt32 {
525525
case neither = 0
526526
case down = 1
527527
case up = 2

0 commit comments

Comments
 (0)