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  }