github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_fe310.go (about) 1 //go:build fe310 2 3 package machine 4 5 import ( 6 "device/sifive" 7 "runtime/interrupt" 8 "unsafe" 9 ) 10 11 const deviceName = sifive.Device 12 13 func CPUFrequency() uint32 { 14 return 320000000 // 320MHz 15 } 16 17 const ( 18 PinInput PinMode = iota 19 PinOutput 20 PinPWM 21 PinSPI 22 PinI2C = PinSPI 23 ) 24 25 // Configure this pin with the given configuration. 26 func (p Pin) Configure(config PinConfig) { 27 sifive.GPIO0.INPUT_EN.SetBits(1 << uint8(p)) 28 switch config.Mode { 29 case PinOutput: 30 sifive.GPIO0.OUTPUT_EN.SetBits(1 << uint8(p)) 31 case PinPWM: 32 sifive.GPIO0.IOF_EN.SetBits(1 << uint8(p)) 33 sifive.GPIO0.IOF_SEL.SetBits(1 << uint8(p)) 34 case PinSPI: 35 sifive.GPIO0.IOF_EN.SetBits(1 << uint8(p)) 36 sifive.GPIO0.IOF_SEL.ClearBits(1 << uint8(p)) 37 } 38 } 39 40 // Set the pin to high or low. 41 func (p Pin) Set(high bool) { 42 if high { 43 sifive.GPIO0.PORT.SetBits(1 << uint8(p)) 44 } else { 45 sifive.GPIO0.PORT.ClearBits(1 << uint8(p)) 46 } 47 } 48 49 // Get returns the current value of a GPIO pin when the pin is configured as an 50 // input or as an output. 51 func (p Pin) Get() bool { 52 val := sifive.GPIO0.VALUE.Get() & (1 << uint8(p)) 53 return (val > 0) 54 } 55 56 // Return the register and mask to enable a given GPIO pin. This can be used to 57 // implement bit-banged drivers. 58 // 59 // Warning: only use this on an output pin! 60 func (p Pin) PortMaskSet() (*uint32, uint32) { 61 return (*uint32)(unsafe.Pointer(&sifive.GPIO0.PORT)), sifive.GPIO0.PORT.Get() | (1 << uint8(p)) 62 } 63 64 // Return the register and mask to disable a given GPIO pin. This can be used to 65 // implement bit-banged drivers. 66 // 67 // Warning: only use this on an output pin! 68 func (p Pin) PortMaskClear() (*uint32, uint32) { 69 return (*uint32)(unsafe.Pointer(&sifive.GPIO0.PORT)), sifive.GPIO0.PORT.Get() &^ (1 << uint8(p)) 70 } 71 72 type UART struct { 73 Bus *sifive.UART_Type 74 Buffer *RingBuffer 75 } 76 77 var ( 78 UART0 = &_UART0 79 _UART0 = UART{Bus: sifive.UART0, Buffer: NewRingBuffer()} 80 ) 81 82 func (uart *UART) Configure(config UARTConfig) { 83 if config.BaudRate == 0 { 84 config.BaudRate = 115200 85 } 86 // The divisor is: 87 // fbaud = fin / (div + 1) 88 // Restating to get the divisor: 89 // div = fin / fbaud - 1 90 // But we're using integers, so we should take care of rounding: 91 // div = (fin + fbaud/2) / fbaud - 1 92 divisor := (CPUFrequency()+config.BaudRate/2)/config.BaudRate - 1 93 sifive.UART0.DIV.Set(divisor) 94 sifive.UART0.TXCTRL.Set(sifive.UART_TXCTRL_ENABLE) 95 sifive.UART0.RXCTRL.Set(sifive.UART_RXCTRL_ENABLE) 96 sifive.UART0.IE.Set(sifive.UART_IE_RXWM) // enable the receive interrupt (only) 97 intr := interrupt.New(sifive.IRQ_UART0, _UART0.handleInterrupt) 98 intr.SetPriority(5) 99 intr.Enable() 100 } 101 102 func (uart *UART) handleInterrupt(interrupt.Interrupt) { 103 rxdata := uart.Bus.RXDATA.Get() 104 c := byte(rxdata) 105 if uint32(c) != rxdata { 106 // The rxdata has other bits set than just the low 8 bits. This probably 107 // means that the 'empty' flag is set, which indicates there is no data 108 // to be read and the byte is garbage. Ignore this byte. 109 return 110 } 111 uart.Receive(c) 112 } 113 114 func (uart *UART) writeByte(c byte) error { 115 for sifive.UART0.TXDATA.Get()&sifive.UART_TXDATA_FULL != 0 { 116 } 117 118 sifive.UART0.TXDATA.Set(uint32(c)) 119 return nil 120 } 121 122 func (uart *UART) flush() {} 123 124 // SPI on the FE310. The normal SPI0 is actually a quad-SPI meant for flash, so it is best 125 // to use SPI1 or SPI2 port for most applications. 126 type SPI struct { 127 Bus *sifive.QSPI_Type 128 } 129 130 // SPIConfig is used to store config info for SPI. 131 type SPIConfig struct { 132 Frequency uint32 133 SCK Pin 134 SDO Pin 135 SDI Pin 136 LSBFirst bool 137 Mode uint8 138 } 139 140 // Configure is intended to setup the SPI interface. 141 func (spi SPI) Configure(config SPIConfig) error { 142 // Use default pins if not set. 143 if config.SCK == 0 && config.SDO == 0 && config.SDI == 0 { 144 config.SCK = SPI0_SCK_PIN 145 config.SDO = SPI0_SDO_PIN 146 config.SDI = SPI0_SDI_PIN 147 } 148 149 // enable pins for SPI 150 config.SCK.Configure(PinConfig{Mode: PinSPI}) 151 config.SDO.Configure(PinConfig{Mode: PinSPI}) 152 config.SDI.Configure(PinConfig{Mode: PinSPI}) 153 154 // set default frequency 155 if config.Frequency == 0 { 156 config.Frequency = 4000000 // 4MHz 157 } 158 159 // div = (SPI_CFG(dev)->f_sys / (2 * frequency)) - 1; 160 div := CPUFrequency()/(2*config.Frequency) - 1 161 spi.Bus.DIV.Set(div) 162 163 // set mode 164 switch config.Mode { 165 case 0: 166 spi.Bus.MODE.ClearBits(sifive.QSPI_MODE_PHASE) 167 spi.Bus.MODE.ClearBits(sifive.QSPI_MODE_POLARITY) 168 case 1: 169 spi.Bus.MODE.SetBits(sifive.QSPI_MODE_PHASE) 170 spi.Bus.MODE.ClearBits(sifive.QSPI_MODE_POLARITY) 171 case 2: 172 spi.Bus.MODE.ClearBits(sifive.QSPI_MODE_PHASE) 173 spi.Bus.MODE.SetBits(sifive.QSPI_MODE_POLARITY) 174 case 3: 175 spi.Bus.MODE.SetBits(sifive.QSPI_MODE_PHASE | sifive.QSPI_MODE_POLARITY) 176 default: // to mode 0 177 spi.Bus.MODE.ClearBits(sifive.QSPI_MODE_PHASE) 178 spi.Bus.MODE.ClearBits(sifive.QSPI_MODE_POLARITY) 179 } 180 181 // frame length 182 spi.Bus.FMT.SetBits(8 << sifive.QSPI_FMT_LENGTH_Pos) 183 184 // Set single line operation, by clearing all bits 185 spi.Bus.FMT.ClearBits(sifive.QSPI_FMT_PROTOCOL_Msk) 186 187 // set bit transfer order 188 if config.LSBFirst { 189 spi.Bus.FMT.SetBits(sifive.QSPI_FMT_ENDIAN) 190 } else { 191 spi.Bus.FMT.ClearBits(sifive.QSPI_FMT_ENDIAN) 192 } 193 194 return nil 195 } 196 197 // Transfer writes/reads a single byte using the SPI interface. 198 func (spi SPI) Transfer(w byte) (byte, error) { 199 // wait for tx ready 200 for spi.Bus.TXDATA.HasBits(sifive.QSPI_TXDATA_FULL) { 201 } 202 203 // write data 204 spi.Bus.TXDATA.Set(uint32(w)) 205 206 // wait until receive has data 207 data := spi.Bus.RXDATA.Get() 208 for data&sifive.QSPI_RXDATA_EMPTY > 0 { 209 data = spi.Bus.RXDATA.Get() 210 } 211 212 // return data 213 return byte(data), nil 214 } 215 216 // I2C on the FE310-G002. 217 type I2C struct { 218 Bus sifive.I2C_Type 219 } 220 221 var ( 222 I2C0 = (*I2C)(unsafe.Pointer(sifive.I2C0)) 223 ) 224 225 // I2CConfig is used to store config info for I2C. 226 type I2CConfig struct { 227 Frequency uint32 228 SCL Pin 229 SDA Pin 230 } 231 232 var i2cClockFrequency uint32 = 32000000 233 234 // Configure is intended to setup the I2C interface. 235 func (i2c *I2C) Configure(config I2CConfig) error { 236 if config.Frequency == 0 { 237 config.Frequency = 100 * KHz 238 } 239 240 if config.SDA == 0 && config.SCL == 0 { 241 config.SDA = I2C0_SDA_PIN 242 config.SCL = I2C0_SCL_PIN 243 } 244 245 i2c.SetBaudRate(config.Frequency) 246 247 config.SDA.Configure(PinConfig{Mode: PinI2C}) 248 config.SCL.Configure(PinConfig{Mode: PinI2C}) 249 250 return nil 251 } 252 253 // SetBaudRate sets the communication speed for I2C. 254 func (i2c *I2C) SetBaudRate(br uint32) error { 255 var prescaler = i2cClockFrequency/(5*br) - 1 256 257 // disable controller before setting the prescale registers 258 i2c.Bus.CTR.ClearBits(sifive.I2C_CTR_EN) 259 260 // set prescaler registers 261 i2c.Bus.PRER_LO.Set(uint32(prescaler & 0xff)) 262 i2c.Bus.PRER_HI.Set(uint32((prescaler >> 8) & 0xff)) 263 264 // enable controller 265 i2c.Bus.CTR.SetBits(sifive.I2C_CTR_EN) 266 267 return nil 268 } 269 270 // Tx does a single I2C transaction at the specified address. 271 // It clocks out the given address, writes the bytes in w, reads back len(r) 272 // bytes and stores them in r, and generates a stop condition on the bus. 273 func (i2c *I2C) Tx(addr uint16, w, r []byte) error { 274 var err error 275 if len(w) != 0 { 276 // send start/address for write 277 i2c.sendAddress(addr, true) 278 279 // ACK received (0: ACK, 1: NACK) 280 if i2c.Bus.CR_SR.HasBits(sifive.I2C_SR_RX_ACK) { 281 return errI2CAckExpected 282 } 283 284 // write data 285 for _, b := range w { 286 err = i2c.writeByte(b) 287 if err != nil { 288 return err 289 } 290 } 291 } 292 if len(r) != 0 { 293 // send start/address for read 294 i2c.sendAddress(addr, false) 295 296 // ACK received (0: ACK, 1: NACK) 297 if i2c.Bus.CR_SR.HasBits(sifive.I2C_SR_RX_ACK) { 298 return errI2CAckExpected 299 } 300 301 // read first byte 302 r[0] = i2c.readByte() 303 for i := 1; i < len(r); i++ { 304 // send an ACK 305 i2c.Bus.CR_SR.Set(^uint32(sifive.I2C_CR_ACK)) 306 307 // read data and send the ACK 308 r[i] = i2c.readByte() 309 } 310 311 // send NACK to end transmission 312 i2c.Bus.CR_SR.Set(sifive.I2C_CR_ACK) 313 } 314 315 // generate stop condition 316 i2c.Bus.CR_SR.Set(sifive.I2C_CR_STO) 317 return nil 318 } 319 320 // Writes a single byte to the I2C bus. 321 func (i2c *I2C) writeByte(data byte) error { 322 // Send data byte 323 i2c.Bus.TXR_RXR.Set(uint32(data)) 324 325 i2c.Bus.CR_SR.Set(sifive.I2C_CR_WR) 326 327 // wait until transmission complete 328 for i2c.Bus.CR_SR.HasBits(sifive.I2C_SR_TIP) { 329 } 330 331 // ACK received (0: ACK, 1: NACK) 332 if i2c.Bus.CR_SR.HasBits(sifive.I2C_SR_RX_ACK) { 333 return errI2CAckExpected 334 } 335 336 return nil 337 } 338 339 // Reads a single byte from the I2C bus. 340 func (i2c *I2C) readByte() byte { 341 i2c.Bus.CR_SR.Set(sifive.I2C_CR_RD) 342 343 // wait until transmission complete 344 for i2c.Bus.CR_SR.HasBits(sifive.I2C_SR_TIP) { 345 } 346 347 return byte(i2c.Bus.TXR_RXR.Get()) 348 } 349 350 // Sends the address and start signal. 351 func (i2c *I2C) sendAddress(address uint16, write bool) error { 352 data := (address << 1) 353 if !write { 354 data |= 1 // set read flag in transmit register 355 } 356 357 // write address to transmit register 358 i2c.Bus.TXR_RXR.Set(uint32(data)) 359 360 // generate start condition 361 i2c.Bus.CR_SR.Set((sifive.I2C_CR_STA | sifive.I2C_CR_WR)) 362 363 // wait until transmission complete 364 for i2c.Bus.CR_SR.HasBits(sifive.I2C_SR_TIP) { 365 } 366 367 return nil 368 }