github.com/aykevl/tinygo@v0.5.0/src/machine/machine_nrf52840.go (about) 1 // +build nrf52840 2 3 package machine 4 5 import ( 6 "device/nrf" 7 "unsafe" 8 ) 9 10 const CPU_FREQUENCY = 64000000 11 12 // Get peripheral and pin number for this GPIO pin. 13 func (p GPIO) getPortPin() (*nrf.GPIO_Type, uint8) { 14 if p.Pin >= 32 { 15 return nrf.P1, p.Pin - 32 16 } else { 17 return nrf.P0, p.Pin 18 } 19 } 20 21 func (uart UART) setPins(tx, rx uint32) { 22 nrf.UART0.PSEL.TXD = nrf.RegValue(tx) 23 nrf.UART0.PSEL.RXD = nrf.RegValue(rx) 24 } 25 26 //go:export UARTE0_UART0_IRQHandler 27 func handleUART0() { 28 UART0.handleInterrupt() 29 } 30 31 func (i2c I2C) setPins(scl, sda uint8) { 32 i2c.Bus.PSEL.SCL = nrf.RegValue(scl) 33 i2c.Bus.PSEL.SDA = nrf.RegValue(sda) 34 } 35 36 // SPI 37 func (spi SPI) setPins(sck, mosi, miso uint8) { 38 if sck == 0 { 39 sck = SPI0_SCK_PIN 40 } 41 if mosi == 0 { 42 mosi = SPI0_MOSI_PIN 43 } 44 if miso == 0 { 45 miso = SPI0_MISO_PIN 46 } 47 spi.Bus.PSEL.SCK = nrf.RegValue(sck) 48 spi.Bus.PSEL.MOSI = nrf.RegValue(mosi) 49 spi.Bus.PSEL.MISO = nrf.RegValue(miso) 50 } 51 52 // InitADC initializes the registers needed for ADC. 53 func InitADC() { 54 return // no specific setup on nrf52840 machine. 55 } 56 57 // Configure configures an ADC pin to be able to read analog data. 58 func (a ADC) Configure() { 59 return // no pin specific setup on nrf52840 machine. 60 } 61 62 // Get returns the current value of a ADC pin in the range 0..0xffff. 63 func (a ADC) Get() uint16 { 64 var pwmPin uint32 65 var value int16 66 67 switch a.Pin { 68 case 2: 69 pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput0 70 71 case 3: 72 pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput1 73 74 case 4: 75 pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput2 76 77 case 5: 78 pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput3 79 80 case 28: 81 pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput4 82 83 case 29: 84 pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput5 85 86 case 30: 87 pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput6 88 89 case 31: 90 pwmPin = nrf.SAADC_CH_PSELP_PSELP_AnalogInput7 91 92 default: 93 return 0 94 } 95 96 nrf.SAADC.RESOLUTION = nrf.SAADC_RESOLUTION_VAL_12bit 97 98 // Enable ADC. 99 nrf.SAADC.ENABLE = (nrf.SAADC_ENABLE_ENABLE_Enabled << nrf.SAADC_ENABLE_ENABLE_Pos) 100 for i := 0; i < 8; i++ { 101 nrf.SAADC.CH[i].PSELN = nrf.SAADC_CH_PSELP_PSELP_NC 102 nrf.SAADC.CH[i].PSELP = nrf.SAADC_CH_PSELP_PSELP_NC 103 } 104 105 // Configure ADC. 106 nrf.SAADC.CH[0].CONFIG = ((nrf.SAADC_CH_CONFIG_RESP_Bypass << nrf.SAADC_CH_CONFIG_RESP_Pos) & nrf.SAADC_CH_CONFIG_RESP_Msk) | 107 ((nrf.SAADC_CH_CONFIG_RESP_Bypass << nrf.SAADC_CH_CONFIG_RESN_Pos) & nrf.SAADC_CH_CONFIG_RESN_Msk) | 108 ((nrf.SAADC_CH_CONFIG_GAIN_Gain1_5 << nrf.SAADC_CH_CONFIG_GAIN_Pos) & nrf.SAADC_CH_CONFIG_GAIN_Msk) | 109 ((nrf.SAADC_CH_CONFIG_REFSEL_Internal << nrf.SAADC_CH_CONFIG_REFSEL_Pos) & nrf.SAADC_CH_CONFIG_REFSEL_Msk) | 110 ((nrf.SAADC_CH_CONFIG_TACQ_3us << nrf.SAADC_CH_CONFIG_TACQ_Pos) & nrf.SAADC_CH_CONFIG_TACQ_Msk) | 111 ((nrf.SAADC_CH_CONFIG_MODE_SE << nrf.SAADC_CH_CONFIG_MODE_Pos) & nrf.SAADC_CH_CONFIG_MODE_Msk) 112 113 // Set pin to read. 114 nrf.SAADC.CH[0].PSELN = nrf.RegValue(pwmPin) 115 nrf.SAADC.CH[0].PSELP = nrf.RegValue(pwmPin) 116 117 // Destination for sample result. 118 nrf.SAADC.RESULT.PTR = nrf.RegValue(uintptr(unsafe.Pointer(&value))) 119 nrf.SAADC.RESULT.MAXCNT = 1 // One sample 120 121 // Start tasks. 122 nrf.SAADC.TASKS_START = 1 123 for nrf.SAADC.EVENTS_STARTED == 0 { 124 } 125 nrf.SAADC.EVENTS_STARTED = 0x00 126 127 // Start the sample task. 128 nrf.SAADC.TASKS_SAMPLE = 1 129 130 // Wait until the sample task is done. 131 for nrf.SAADC.EVENTS_END == 0 { 132 } 133 nrf.SAADC.EVENTS_END = 0x00 134 135 // Stop the ADC 136 nrf.SAADC.TASKS_STOP = 1 137 for nrf.SAADC.EVENTS_STOPPED == 0 { 138 } 139 nrf.SAADC.EVENTS_STOPPED = 0 140 141 // Disable the ADC. 142 nrf.SAADC.ENABLE = (nrf.SAADC_ENABLE_ENABLE_Disabled << nrf.SAADC_ENABLE_ENABLE_Pos) 143 144 if value < 0 { 145 value = 0 146 } 147 148 // Return 16-bit result from 12-bit value. 149 return uint16(value << 4) 150 } 151 152 // PWM 153 var ( 154 pwmChannelPins = [4]uint32{0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} 155 pwms = [4]*nrf.PWM_Type{nrf.PWM0, nrf.PWM1, nrf.PWM2, nrf.PWM3} 156 pwmChannelSequence [4]uint16 157 ) 158 159 // InitPWM initializes the registers needed for PWM. 160 func InitPWM() { 161 return 162 } 163 164 // Configure configures a PWM pin for output. 165 func (pwm PWM) Configure() { 166 } 167 168 // Set turns on the duty cycle for a PWM pin using the provided value. 169 func (pwm PWM) Set(value uint16) { 170 for i := 0; i < 4; i++ { 171 if pwmChannelPins[i] == 0xFFFFFFFF || pwmChannelPins[i] == uint32(pwm.Pin) { 172 pwmChannelPins[i] = uint32(pwm.Pin) 173 pwmChannelSequence[i] = (value >> 2) | 0x8000 // set bit 15 to invert polarity 174 175 p := pwms[i] 176 177 p.PSEL.OUT[0] = nrf.RegValue(pwm.Pin) 178 p.PSEL.OUT[1] = nrf.RegValue(pwm.Pin) 179 p.PSEL.OUT[2] = nrf.RegValue(pwm.Pin) 180 p.PSEL.OUT[3] = nrf.RegValue(pwm.Pin) 181 p.ENABLE = (nrf.PWM_ENABLE_ENABLE_Enabled << nrf.PWM_ENABLE_ENABLE_Pos) 182 p.PRESCALER = nrf.PWM_PRESCALER_PRESCALER_DIV_2 183 p.MODE = nrf.PWM_MODE_UPDOWN_Up 184 p.COUNTERTOP = 16384 // frequency 185 p.LOOP = 0 186 p.DECODER = (nrf.PWM_DECODER_LOAD_Common << nrf.PWM_DECODER_LOAD_Pos) | (nrf.PWM_DECODER_MODE_RefreshCount << nrf.PWM_DECODER_MODE_Pos) 187 p.SEQ[0].PTR = nrf.RegValue(uintptr(unsafe.Pointer(&pwmChannelSequence[i]))) 188 p.SEQ[0].CNT = 1 189 p.SEQ[0].REFRESH = 1 190 p.SEQ[0].ENDDELAY = 0 191 p.TASKS_SEQSTART[0] = 1 192 193 break 194 } 195 } 196 }