mbed API for Raspberry Pi boards.

mbedPi

This is an attempt to implement a limited number of mbed APIs for Raspberry Pi single-board computers. The project was inspired by and based on the arduPi library developed for the Arduino by Cooking Hacks .

/media/uploads/hudakz/board01.jpg

Specifications

  • Chip: Broadcom BCM2836 SoC
  • Core architecture: Quad-core ARM Cortex-A7
  • CPU frequency: 900 MHz
  • GPU: Dual Core VideoCore IV® Multimedia Co-Processor
  • Memory: 1GB LPDDR2
  • Operating System: Boots from Micro SD card, running a version of the Linux operating system
  • Power: Micro USB socket 5V, 2A

Connectors

  • Ethernet: 10/100 BaseT Ethernet socket
  • Video Output: HDMI (rev 1.3 & 1.4)
  • Audio Output: 3.5mm jack, HDMI
  • USB: 4 x USB 2.0 Connector
  • GPIO Connector: 40-pin 2.54 mm (100 mil) expansion header: 2x20 strip providing 27 GPIO pins as well as +3.3 V, +5 V and GND supply lines
  • Camera Connector: 15-pin MIPI Camera Serial Interface (CSI-2)
  • JTAG: Not populated
  • Display Connector: Display Serial Interface (DSI) 15 way flat flex cable connector with two data lanes and a clock lane
  • Memory Card Slot: Micro SDIO

GPIO connector pinout

Zoom in /media/uploads/hudakz/mbedpi_pinout02.png

Information

Only the labels printed in blue/white or green/white (i.e. p3, gpio2 ...) must be used in your code. The other labels are given as information (alternate-functions, power pins, ...).


Building programs for the Raspberry Pi with mbedPi

I use Qt Creator for development, however you can use any other IDE available on the Raspberry Pi (e.g. Geany) if you like. For a quick try:

  • Install Qt and the Qt Creator onto your Raspberry Pi. Then create a new "Blinky" Plain non-Qt C++ Project as follows: /media/uploads/hudakz/newproject.png

  • Change the main code as below:

main.cpp

#include "mbedPi.h"

int main()
{
    DigitalOut  myled(p7);

    while(1) {
        myled = 1; // LED is ON
        wait(0.2); // 200 ms
        myled = 0; // LED is OFF
        wait(1.0); // 1 sec
        printf("Blink\r\n");
    }
}


  • Copy the mbedPi.zip file into your project's folder and unzip.
  • Add the mbedPi.h and mbedPi.cpp files to your project by right clicking on the "Blinky" project and then clicking on the "Add Existing Files..." option in the local menu:

    /media/uploads/hudakz/addfiles.png

    /media/uploads/hudakz/addfiles02.png

  • Double click on Blinky.pro to open it for editing and add new libraries by inserting a new line as follows:

    /media/uploads/hudakz/libs.png

  • Compile the project.

  • Connect an LED through a 1k resistor to pin 7 and the ground on the Raspberry Pi GPIO connector.

  • Run the binary as sudo (sudo ./Blinky) and you should see the LED blinking. /media/uploads/hudakz/mbedpi_run.png

  • Press Ctrl+c to stop running the application.
Committer:
hudakz
Date:
Tue Dec 20 12:16:18 2022 +0000
Revision:
2:131555dc6fb7
Parent:
1:1f2d9982fa8c
Mbed API for Raspberry Pi boards equipped with BCM2836 SoC.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hudakz 1:1f2d9982fa8c 1 /* bcm2835.h
hudakz 1:1f2d9982fa8c 2
hudakz 1:1f2d9982fa8c 3 C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi
hudakz 1:1f2d9982fa8c 4
hudakz 1:1f2d9982fa8c 5 Author: Mike McCauley
hudakz 1:1f2d9982fa8c 6 Copyright (C) 2011-2013 Mike McCauley
hudakz 1:1f2d9982fa8c 7 $Id: bcm2835.h,v 1.26 2020/01/11 05:07:13 mikem Exp mikem $
hudakz 1:1f2d9982fa8c 8 */
hudakz 1:1f2d9982fa8c 9
hudakz 1:1f2d9982fa8c 10 #ifndef _BCM2835_H_
hudakz 1:1f2d9982fa8c 11 #define _BCM2835_H_
hudakz 1:1f2d9982fa8c 12
hudakz 1:1f2d9982fa8c 13 /*$off*/
hudakz 1:1f2d9982fa8c 14 #include <errno.h>
hudakz 1:1f2d9982fa8c 15 #include <fcntl.h>
hudakz 1:1f2d9982fa8c 16 #include <netinet/in.h>
hudakz 1:1f2d9982fa8c 17 #include <signal.h>
hudakz 1:1f2d9982fa8c 18 #include <stdlib.h>
hudakz 1:1f2d9982fa8c 19 #include <stdio.h>
hudakz 1:1f2d9982fa8c 20 #include <sys/ipc.h>
hudakz 1:1f2d9982fa8c 21 #include <sys/sem.h>
hudakz 1:1f2d9982fa8c 22 #include <sys/socket.h>
hudakz 1:1f2d9982fa8c 23 #include <sys/time.h>
hudakz 1:1f2d9982fa8c 24 #include <sys/types.h>
hudakz 1:1f2d9982fa8c 25 #include <sys/wait.h>
hudakz 1:1f2d9982fa8c 26 #include <sys/mman.h>
hudakz 1:1f2d9982fa8c 27 #include <string.h>
hudakz 1:1f2d9982fa8c 28 #include <time.h>
hudakz 1:1f2d9982fa8c 29 #include <termios.h>
hudakz 1:1f2d9982fa8c 30 #include <ctype.h>
hudakz 1:1f2d9982fa8c 31 #include <sys/ioctl.h>
hudakz 1:1f2d9982fa8c 32 #include <limits.h>
hudakz 1:1f2d9982fa8c 33 #include <algorithm>
hudakz 1:1f2d9982fa8c 34 #include <limits.h>
hudakz 1:1f2d9982fa8c 35 #include <pthread.h>
hudakz 1:1f2d9982fa8c 36 #include <poll.h>
hudakz 1:1f2d9982fa8c 37 #include "PinNames.h"
hudakz 1:1f2d9982fa8c 38
hudakz 1:1f2d9982fa8c 39 #define BCM2835_PERI_BASE 0x20000000
hudakz 1:1f2d9982fa8c 40 #define BCM2835_PERI_SIZE 0x01000000
hudakz 1:1f2d9982fa8c 41
hudakz 1:1f2d9982fa8c 42 #define BCM2835_ST_BASE 0x3000
hudakz 1:1f2d9982fa8c 43 #define BCM2835_CLOCK_BASE 0x101000
hudakz 1:1f2d9982fa8c 44 #define BCM2835_GPIO_PWM 0x20C000
hudakz 1:1f2d9982fa8c 45 #define BCM2835_BSC1_BASE 0x804000
hudakz 1:1f2d9982fa8c 46 #define BCM2835_SPI0_BASE 0x204000
hudakz 1:1f2d9982fa8c 47
hudakz 1:1f2d9982fa8c 48 /* Defines for ST
hudakz 1:1f2d9982fa8c 49 GPIO register offsets from BCM2835_ST_BASE.
hudakz 1:1f2d9982fa8c 50 Offsets into the ST Peripheral block in bytes per 12.1 System Timer Registers
hudakz 1:1f2d9982fa8c 51 The System Timer peripheral provides four 32-bit timer channels and a single 64-bit free running counter.
hudakz 1:1f2d9982fa8c 52 BCM2835_ST_CLO is the System Timer Counter Lower bits register.
hudakz 1:1f2d9982fa8c 53 The system timer free-running counter lower register is a read-only register that returns the current value
hudakz 1:1f2d9982fa8c 54 of the lower 32-bits of the free running counter.
hudakz 1:1f2d9982fa8c 55 BCM2835_ST_CHI is the System Timer Counter Upper bits register.
hudakz 1:1f2d9982fa8c 56 The system timer free-running counter upper register is a read-only register that returns the current value
hudakz 1:1f2d9982fa8c 57 of the upper 32-bits of the free running counter.
hudakz 1:1f2d9982fa8c 58 */
hudakz 1:1f2d9982fa8c 59 #define BCM2835_ST_CS 0x0000 /*!< System Timer Control/Status */
hudakz 1:1f2d9982fa8c 60 #define BCM2835_ST_CLO 0x0004 /*!< System Timer Counter Lower 32 bits */
hudakz 1:1f2d9982fa8c 61 #define BCM2835_ST_CHI 0x0008 /*!< System Timer Counter Upper 32 bits */
hudakz 1:1f2d9982fa8c 62
hudakz 1:1f2d9982fa8c 63 // Defines for I2C
hudakz 1:1f2d9982fa8c 64 // GPIO register offsets from BCM2835_BSC*_BASE.
hudakz 1:1f2d9982fa8c 65 // Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map
hudakz 1:1f2d9982fa8c 66 #define BCM2835_BSC_C 0x0000 ///< BSC Master Control
hudakz 1:1f2d9982fa8c 67 #define BCM2835_BSC_S 0x0004 ///< BSC Master Status
hudakz 1:1f2d9982fa8c 68 #define BCM2835_BSC_DLEN 0x0008 ///< BSC Master Data Length
hudakz 1:1f2d9982fa8c 69 #define BCM2835_BSC_A 0x000c ///< BSC Master Slave Address
hudakz 1:1f2d9982fa8c 70 #define BCM2835_BSC_FIFO 0x0010 ///< BSC Master Data FIFO
hudakz 1:1f2d9982fa8c 71 #define BCM2835_BSC_DIV 0x0014 ///< BSC Master Clock Divider
hudakz 1:1f2d9982fa8c 72 #define BCM2835_BSC_DEL 0x0018 ///< BSC Master Data Delay
hudakz 1:1f2d9982fa8c 73 #define BCM2835_BSC_CLKT 0x001c ///< BSC Master Clock Stretch Timeout
hudakz 1:1f2d9982fa8c 74
hudakz 1:1f2d9982fa8c 75 // Register masks for BSC_C
hudakz 1:1f2d9982fa8c 76 #define BCM2835_BSC_C_I2CEN 0x00008000 ///< I2C Enable, 0 = disabled, 1 = enabled
hudakz 1:1f2d9982fa8c 77 #define BCM2835_BSC_C_INTR 0x00000400 ///< Interrupt on RX
hudakz 1:1f2d9982fa8c 78 #define BCM2835_BSC_C_INTT 0x00000200 ///< Interrupt on TX
hudakz 1:1f2d9982fa8c 79 #define BCM2835_BSC_C_INTD 0x00000100 ///< Interrupt on DONE
hudakz 1:1f2d9982fa8c 80 #define BCM2835_BSC_C_ST 0x00000080 ///< Start transfer, 1 = Start a new transfer
hudakz 1:1f2d9982fa8c 81 #define BCM2835_BSC_C_CLEAR_1 0x00000020 ///< Clear FIFO Clear
hudakz 1:1f2d9982fa8c 82 #define BCM2835_BSC_C_CLEAR_2 0x00000010 ///< Clear FIFO Clear
hudakz 1:1f2d9982fa8c 83 #define BCM2835_BSC_C_READ 0x00000001 ///< Read transfer
hudakz 1:1f2d9982fa8c 84
hudakz 1:1f2d9982fa8c 85 // Register masks for BSC_S
hudakz 1:1f2d9982fa8c 86 #define BCM2835_BSC_S_CLKT 0x00000200 ///< Clock stretch timeout
hudakz 1:1f2d9982fa8c 87 #define BCM2835_BSC_S_ERR 0x00000100 ///< ACK error
hudakz 1:1f2d9982fa8c 88 #define BCM2835_BSC_S_RXF 0x00000080 ///< RXF FIFO full, 0 = FIFO is not full, 1 = FIFO is full
hudakz 1:1f2d9982fa8c 89 #define BCM2835_BSC_S_TXE 0x00000040 ///< TXE FIFO full, 0 = FIFO is not full, 1 = FIFO is full
hudakz 1:1f2d9982fa8c 90 #define BCM2835_BSC_S_RXD 0x00000020 ///< RXD FIFO contains data
hudakz 1:1f2d9982fa8c 91 #define BCM2835_BSC_S_TXD 0x00000010 ///< TXD FIFO can accept data
hudakz 1:1f2d9982fa8c 92 #define BCM2835_BSC_S_RXR 0x00000008 ///< RXR FIFO needs reading (full)
hudakz 1:1f2d9982fa8c 93 #define BCM2835_BSC_S_TXW 0x00000004 ///< TXW FIFO needs writing (full)
hudakz 1:1f2d9982fa8c 94 #define BCM2835_BSC_S_DONE 0x00000002 ///< Transfer DONE
hudakz 1:1f2d9982fa8c 95 #define BCM2835_BSC_S_TA 0x00000001 ///< Transfer Active
hudakz 1:1f2d9982fa8c 96 #define BCM2835_BSC_FIFO_SIZE 16 ///< BSC FIFO size
hudakz 1:1f2d9982fa8c 97 #define BCM2835_CORE_CLK_HZ 250000000 ///< 250 MHz
hudakz 1:1f2d9982fa8c 98
hudakz 1:1f2d9982fa8c 99 /// \brief bcm2835I2CClockDivider
hudakz 1:1f2d9982fa8c 100 /// Specifies the divider used to generate the I2C clock from the system clock.
hudakz 1:1f2d9982fa8c 101 /// Clock divided is based on nominal base clock rate of 250MHz
hudakz 1:1f2d9982fa8c 102 typedef enum
hudakz 1:1f2d9982fa8c 103 {
hudakz 1:1f2d9982fa8c 104 BCM2835_I2C_CLOCK_DIVIDER_2500 = 2500, ///< 2500 = 10us = 100 kHz
hudakz 1:1f2d9982fa8c 105 BCM2835_I2C_CLOCK_DIVIDER_626 = 626, ///< 622 = 2.504us = 399.3610 kHz
hudakz 1:1f2d9982fa8c 106 BCM2835_I2C_CLOCK_DIVIDER_150 = 150, ///< 150 = 60ns = 1.666 MHz (default at reset)
hudakz 1:1f2d9982fa8c 107 BCM2835_I2C_CLOCK_DIVIDER_148 = 148, ///< 148 = 59ns = 1.689 MHz
hudakz 1:1f2d9982fa8c 108 } bcm2835I2CClockDivider;
hudakz 1:1f2d9982fa8c 109
hudakz 1:1f2d9982fa8c 110 /// \brief bcm2835I2CReasonCodes
hudakz 1:1f2d9982fa8c 111 /// Specifies the reason codes for the bcm2835_i2c_write and bcm2835_i2c_read functions.
hudakz 1:1f2d9982fa8c 112 typedef enum
hudakz 1:1f2d9982fa8c 113 {
hudakz 1:1f2d9982fa8c 114 BCM2835_I2C_REASON_OK = 0x00, ///< Success
hudakz 1:1f2d9982fa8c 115 BCM2835_I2C_REASON_ERROR_NACK = 0x01, ///< Received a NACK
hudakz 1:1f2d9982fa8c 116 BCM2835_I2C_REASON_ERROR_CLKT = 0x02, ///< Received Clock Stretch Timeout
hudakz 1:1f2d9982fa8c 117 BCM2835_I2C_REASON_ERROR_DATA = 0x04, ///< Not all data is sent / received
hudakz 1:1f2d9982fa8c 118 } bcm2835I2CReasonCodes;
hudakz 1:1f2d9982fa8c 119
hudakz 1:1f2d9982fa8c 120 typedef enum
hudakz 1:1f2d9982fa8c 121 {
hudakz 1:1f2d9982fa8c 122 RPI_V2_GPIO_P1_03 = 2, ///< Version 2, Pin P1-03
hudakz 1:1f2d9982fa8c 123 RPI_V2_GPIO_P1_05 = 3, ///< Version 2, Pin P1-05
hudakz 1:1f2d9982fa8c 124 } RPiGPIOPin;
hudakz 1:1f2d9982fa8c 125
hudakz 1:1f2d9982fa8c 126 #define BSC0_C *(bsc0.addr + 0x00)
hudakz 1:1f2d9982fa8c 127 #define BSC0_S *(bsc0.addr + 0x01)
hudakz 1:1f2d9982fa8c 128 #define BSC0_DLEN *(bsc0.addr + 0x02)
hudakz 1:1f2d9982fa8c 129 #define BSC0_A *(bsc0.addr + 0x03)
hudakz 1:1f2d9982fa8c 130 #define BSC0_FIFO *(bsc0.addr + 0x04)
hudakz 1:1f2d9982fa8c 131
hudakz 1:1f2d9982fa8c 132 #define BSC_C_I2CEN (1<< 15)
hudakz 1:1f2d9982fa8c 133 #define BSC_C_INTR (1<< 10)
hudakz 1:1f2d9982fa8c 134 #define BSC_C_INTT (1<< 9)
hudakz 1:1f2d9982fa8c 135 #define BSC_C_INTD (1<< 8)
hudakz 1:1f2d9982fa8c 136 #define BSC_C_ST (1<< 7)
hudakz 1:1f2d9982fa8c 137 #define BSC_C_CLEAR (1<< 4)
hudakz 1:1f2d9982fa8c 138 #define BSC_C_READ 1
hudakz 1:1f2d9982fa8c 139
hudakz 1:1f2d9982fa8c 140 #define START_READ BSC_C_I2CEN|BSC_C_ST|BSC_C_CLEAR|BSC_C_READ
hudakz 1:1f2d9982fa8c 141 #define START_WRITE BSC_C_I2CEN|BSC_C_ST
hudakz 1:1f2d9982fa8c 142
hudakz 1:1f2d9982fa8c 143 #define BSC_S_CLKT (1<< 9)
hudakz 1:1f2d9982fa8c 144 #define BSC_S_ERR (1<< 8)
hudakz 1:1f2d9982fa8c 145 #define BSC_S_RXF (1<< 7)
hudakz 1:1f2d9982fa8c 146 #define BSC_S_TXE (1<< 6)
hudakz 1:1f2d9982fa8c 147 #define BSC_S_RXD (1<< 5)
hudakz 1:1f2d9982fa8c 148 #define BSC_S_TXD (1<< 4)
hudakz 1:1f2d9982fa8c 149 #define BSC_S_RXR (1<< 3)
hudakz 1:1f2d9982fa8c 150 #define BSC_S_TXW (1<< 2)
hudakz 1:1f2d9982fa8c 151 #define BSC_S_DONE (1<< 1)
hudakz 1:1f2d9982fa8c 152 #define BSC_S_TA 1
hudakz 1:1f2d9982fa8c 153
hudakz 1:1f2d9982fa8c 154 #define CLEAR_STATUS BSC_S_CLKT|BSC_S_ERR|BSC_S_DONE
hudakz 1:1f2d9982fa8c 155
hudakz 1:1f2d9982fa8c 156 #define GPFSEL0 *(gpio.addr + 0)
hudakz 1:1f2d9982fa8c 157 #define GPFSEL1 *(gpio.addr + 1)
hudakz 1:1f2d9982fa8c 158 #define GPFSEL2 *(gpio.addr + 2)
hudakz 1:1f2d9982fa8c 159 #define GPFSEL3 *(gpio.addr + 3)
hudakz 1:1f2d9982fa8c 160 #define GPFSEL4 *(gpio.addr + 4)
hudakz 1:1f2d9982fa8c 161 #define GPFSEL5 *(gpio.addr + 5)
hudakz 1:1f2d9982fa8c 162 // Reserved @ word offset 6
hudakz 1:1f2d9982fa8c 163 #define GPSET0 *(gpio.addr + 7)
hudakz 1:1f2d9982fa8c 164 #define GPSET1 *(gpio.addr + 8)
hudakz 1:1f2d9982fa8c 165 // Reserved @ word offset 9
hudakz 1:1f2d9982fa8c 166 #define GPCLR0 *(gpio.addr + 10)
hudakz 1:1f2d9982fa8c 167 #define GPCLR1 *(gpio.addr + 11)
hudakz 1:1f2d9982fa8c 168 // Reserved @ word offset 12
hudakz 1:1f2d9982fa8c 169 #define GPLEV0 *(gpio.addr + 13)
hudakz 1:1f2d9982fa8c 170 #define GPLEV1 *(gpio.addr + 14)
hudakz 1:1f2d9982fa8c 171
hudakz 1:1f2d9982fa8c 172 #define PAGESIZE 4096
hudakz 1:1f2d9982fa8c 173 #define BLOCK_SIZE 4096
hudakz 1:1f2d9982fa8c 174
hudakz 1:1f2d9982fa8c 175 /// Defines for SPI
hudakz 1:1f2d9982fa8c 176 /// GPIO register offsets from BCM2835_SPI0_BASE.
hudakz 1:1f2d9982fa8c 177 /// Offsets into the SPI Peripheral block in bytes per 10.5 SPI Register Map
hudakz 1:1f2d9982fa8c 178 #define BCM2835_SPI0_CS 0x0000 ///< SPI Master Control and Status
hudakz 1:1f2d9982fa8c 179 #define BCM2835_SPI0_FIFO 0x0004 ///< SPI Master TX and RX FIFOs
hudakz 1:1f2d9982fa8c 180 #define BCM2835_SPI0_CLK 0x0008 ///< SPI Master Clock Divider
hudakz 1:1f2d9982fa8c 181 #define BCM2835_SPI0_DLEN 0x000c ///< SPI Master Data Length
hudakz 1:1f2d9982fa8c 182 #define BCM2835_SPI0_LTOH 0x0010 ///< SPI LOSSI mode TOH
hudakz 1:1f2d9982fa8c 183 #define BCM2835_SPI0_DC 0x0014 ///< SPI DMA DREQ Controls
hudakz 1:1f2d9982fa8c 184
hudakz 1:1f2d9982fa8c 185 // Register masks for SPI0_CS
hudakz 1:1f2d9982fa8c 186 #define BCM2835_SPI0_CS_LEN_LONG 0x02000000 ///< Enable Long data word in Lossi mode if DMA_LEN is set
hudakz 1:1f2d9982fa8c 187 #define BCM2835_SPI0_CS_DMA_LEN 0x01000000 ///< Enable DMA mode in Lossi mode
hudakz 1:1f2d9982fa8c 188 #define BCM2835_SPI0_CS_CSPOL2 0x00800000 ///< Chip Select 2 Polarity
hudakz 1:1f2d9982fa8c 189 #define BCM2835_SPI0_CS_CSPOL1 0x00400000 ///< Chip Select 1 Polarity
hudakz 1:1f2d9982fa8c 190 #define BCM2835_SPI0_CS_CSPOL0 0x00200000 ///< Chip Select 0 Polarity
hudakz 1:1f2d9982fa8c 191 #define BCM2835_SPI0_CS_RXF 0x00100000 ///< RXF - RX FIFO Full
hudakz 1:1f2d9982fa8c 192 #define BCM2835_SPI0_CS_RXR 0x00080000 ///< RXR RX FIFO needs Reading ( full)
hudakz 1:1f2d9982fa8c 193 #define BCM2835_SPI0_CS_TXD 0x00040000 ///< TXD TX FIFO can accept Data
hudakz 1:1f2d9982fa8c 194 #define BCM2835_SPI0_CS_RXD 0x00020000 ///< RXD RX FIFO contains Data
hudakz 1:1f2d9982fa8c 195 #define BCM2835_SPI0_CS_DONE 0x00010000 ///< Done transfer Done
hudakz 1:1f2d9982fa8c 196 #define BCM2835_SPI0_CS_TE_EN 0x00008000 ///< Unused
hudakz 1:1f2d9982fa8c 197 #define BCM2835_SPI0_CS_LMONO 0x00004000 ///< Unused
hudakz 1:1f2d9982fa8c 198 #define BCM2835_SPI0_CS_LEN 0x00002000 ///< LEN LoSSI enable
hudakz 1:1f2d9982fa8c 199 #define BCM2835_SPI0_CS_REN 0x00001000 ///< REN Read Enable
hudakz 1:1f2d9982fa8c 200 #define BCM2835_SPI0_CS_ADCS 0x00000800 ///< ADCS Automatically Deassert Chip Select
hudakz 1:1f2d9982fa8c 201 #define BCM2835_SPI0_CS_INTR 0x00000400 ///< INTR Interrupt on RXR
hudakz 1:1f2d9982fa8c 202 #define BCM2835_SPI0_CS_INTD 0x00000200 ///< INTD Interrupt on Done
hudakz 1:1f2d9982fa8c 203 #define BCM2835_SPI0_CS_DMAEN 0x00000100 ///< DMAEN DMA Enable
hudakz 1:1f2d9982fa8c 204 #define BCM2835_SPI0_CS_TA 0x00000080 ///< Transfer Active
hudakz 1:1f2d9982fa8c 205 #define BCM2835_SPI0_CS_CSPOL 0x00000040 ///< Chip Select Polarity
hudakz 1:1f2d9982fa8c 206 #define BCM2835_SPI0_CS_CLEAR 0x00000030 ///< Clear FIFO Clear RX and TX
hudakz 1:1f2d9982fa8c 207 #define BCM2835_SPI0_CS_CLEAR_RX 0x00000020 ///< Clear FIFO Clear RX
hudakz 1:1f2d9982fa8c 208 #define BCM2835_SPI0_CS_CLEAR_TX 0x00000010 ///< Clear FIFO Clear TX
hudakz 1:1f2d9982fa8c 209 #define BCM2835_SPI0_CS_CPOL 0x00000008 ///< Clock Polarity
hudakz 1:1f2d9982fa8c 210 #define BCM2835_SPI0_CS_CPHA 0x00000004 ///< Clock Phase
hudakz 1:1f2d9982fa8c 211 #define BCM2835_SPI0_CS_CS 0x00000003 ///< Chip Select
hudakz 1:1f2d9982fa8c 212
hudakz 1:1f2d9982fa8c 213 #define BCM2835_GPFSEL0 0x0000 ///< GPIO Function Select 0
hudakz 1:1f2d9982fa8c 214
hudakz 1:1f2d9982fa8c 215 #define BCM2835_GPEDS0 0x0040 ///< GPIO Pin Event Detect Status 0
hudakz 1:1f2d9982fa8c 216 #define BCM2835_GPREN0 0x004c ///< GPIO Pin Rising Edge Detect Enable 0
hudakz 1:1f2d9982fa8c 217 #define BCM2835_GPFEN0 0x0048 ///< GPIO Pin Falling Edge Detect Enable 0
hudakz 1:1f2d9982fa8c 218 #define BCM2835_GPHEN0 0x0064 ///< GPIO Pin High Detect Enable 0
hudakz 1:1f2d9982fa8c 219 #define BCM2835_GPLEN0 0x0070 ///< GPIO Pin Low Detect Enable 0
hudakz 1:1f2d9982fa8c 220
hudakz 1:1f2d9982fa8c 221 /* Defines for PWM, word offsets (ie 4 byte multiples) */
hudakz 1:1f2d9982fa8c 222 #define BCM2835_PWM_CONTROL 0
hudakz 1:1f2d9982fa8c 223 #define BCM2835_PWM_STATUS 1
hudakz 1:1f2d9982fa8c 224 #define BCM2835_PWM_DMAC 2
hudakz 1:1f2d9982fa8c 225 #define BCM2835_PWM0_RANGE 4
hudakz 1:1f2d9982fa8c 226 #define BCM2835_PWM0_DATA 5
hudakz 1:1f2d9982fa8c 227 #define BCM2835_PWM_FIF1 6
hudakz 1:1f2d9982fa8c 228 #define BCM2835_PWM1_RANGE 8
hudakz 1:1f2d9982fa8c 229 #define BCM2835_PWM1_DATA 9
hudakz 1:1f2d9982fa8c 230
hudakz 1:1f2d9982fa8c 231 /* Defines for PWM Clock, word offsets (ie 4 byte multiples) */
hudakz 1:1f2d9982fa8c 232 #define BCM2835_PWMCLK_CNTL 40
hudakz 1:1f2d9982fa8c 233 #define BCM2835_PWMCLK_DIV 41
hudakz 1:1f2d9982fa8c 234 #define BCM2835_PWM_PASSWRD (0x5A << 24) /*!< Password to enable setting PWM clock */
hudakz 1:1f2d9982fa8c 235
hudakz 1:1f2d9982fa8c 236 #define BCM2835_PWM1_MS_MODE 0x8000 /*!< Run in Mark/Space mode */
hudakz 1:1f2d9982fa8c 237 #define BCM2835_PWM1_USEFIFO 0x2000 /*!< Data from FIFO */
hudakz 1:1f2d9982fa8c 238 #define BCM2835_PWM1_REVPOLAR 0x1000 /*!< Reverse polarity */
hudakz 1:1f2d9982fa8c 239 #define BCM2835_PWM1_OFFSTATE 0x0800 /*!< Ouput Off state */
hudakz 1:1f2d9982fa8c 240 #define BCM2835_PWM1_REPEATFF 0x0400 /*!< Repeat last value if FIFO empty */
hudakz 1:1f2d9982fa8c 241 #define BCM2835_PWM1_SERIAL 0x0200 /*!< Run in serial mode */
hudakz 1:1f2d9982fa8c 242 #define BCM2835_PWM1_ENABLE 0x0100 /*!< Channel Enable */
hudakz 1:1f2d9982fa8c 243
hudakz 1:1f2d9982fa8c 244 #define BCM2835_PWM0_MS_MODE 0x0080 /*!< Run in Mark/Space mode */
hudakz 1:1f2d9982fa8c 245 #define BCM2835_PWM_CLEAR_FIFO 0x0040 /*!< Clear FIFO */
hudakz 1:1f2d9982fa8c 246 #define BCM2835_PWM0_USEFIFO 0x0020 /*!< Data from FIFO */
hudakz 1:1f2d9982fa8c 247 #define BCM2835_PWM0_REVPOLAR 0x0010 /*!< Reverse polarity */
hudakz 1:1f2d9982fa8c 248 #define BCM2835_PWM0_OFFSTATE 0x0008 /*!< Ouput Off state */
hudakz 1:1f2d9982fa8c 249 #define BCM2835_PWM0_REPEATFF 0x0004 /*!< Repeat last value if FIFO empty */
hudakz 1:1f2d9982fa8c 250 #define BCM2835_PWM0_SERIAL 0x0002 /*!< Run in serial mode */
hudakz 1:1f2d9982fa8c 251 #define BCM2835_PWM0_ENABLE 0x0001 /*!< Channel Enable */
hudakz 1:1f2d9982fa8c 252
hudakz 1:1f2d9982fa8c 253 #define PWM_CHANNEL 0
hudakz 1:1f2d9982fa8c 254
hudakz 1:1f2d9982fa8c 255 /// \brief bcm2835SPIBitOrder
hudakz 1:1f2d9982fa8c 256 /// Specifies the SPI data bit ordering
hudakz 1:1f2d9982fa8c 257 typedef enum
hudakz 1:1f2d9982fa8c 258 {
hudakz 1:1f2d9982fa8c 259 LSBFIRST = 0, ///< LSB First
hudakz 1:1f2d9982fa8c 260 MSBFIRST = 1///< MSB First
hudakz 1:1f2d9982fa8c 261 } bcm2835SPIBitOrder;
hudakz 1:1f2d9982fa8c 262
hudakz 1:1f2d9982fa8c 263 /// \brief bcm2835SPIMode
hudakz 1:1f2d9982fa8c 264 /// Specify the SPI data mode
hudakz 1:1f2d9982fa8c 265 typedef enum
hudakz 1:1f2d9982fa8c 266 {
hudakz 1:1f2d9982fa8c 267 SPI_MODE0 = 0, ///< CPOL = 0, CPHA = 0
hudakz 1:1f2d9982fa8c 268 SPI_MODE1 = 1, ///< CPOL = 0, CPHA = 1
hudakz 1:1f2d9982fa8c 269 SPI_MODE2 = 2, ///< CPOL = 1, CPHA = 0
hudakz 1:1f2d9982fa8c 270 SPI_MODE3 = 3, ///< CPOL = 1, CPHA = 1
hudakz 1:1f2d9982fa8c 271 } bcm2835SPIMode;
hudakz 1:1f2d9982fa8c 272
hudakz 1:1f2d9982fa8c 273 /// \brief bcm2835SPIChipSelect
hudakz 1:1f2d9982fa8c 274 /// Specify the SPI chip select pin(s)
hudakz 1:1f2d9982fa8c 275 typedef enum
hudakz 1:1f2d9982fa8c 276 {
hudakz 1:1f2d9982fa8c 277 SPI_CS0 = 0, ///< Chip Select 0
hudakz 1:1f2d9982fa8c 278 SPI_CS1 = 1, ///< Chip Select 1
hudakz 1:1f2d9982fa8c 279 SPI_CS2 = 2, ///< Chip Select 2 (ie pins CS1 and CS2 are asserted)
hudakz 1:1f2d9982fa8c 280 SPI_CS_NONE = 3, ///< No CS, control it yourself
hudakz 1:1f2d9982fa8c 281 } bcm2835SPIChipSelect;
hudakz 1:1f2d9982fa8c 282
hudakz 1:1f2d9982fa8c 283 /// \brief bcm2835SPIClockDivider
hudakz 1:1f2d9982fa8c 284 /// Specifies the divider used to generate the SPI clock from the system clock.
hudakz 1:1f2d9982fa8c 285 /// Figures below give the divider, clock period and clock frequency.
hudakz 1:1f2d9982fa8c 286 typedef enum
hudakz 1:1f2d9982fa8c 287 {
hudakz 1:1f2d9982fa8c 288 SPI_CLOCK_DIV65536 = 0, ///< 65536 = 256us = 4kHz
hudakz 1:1f2d9982fa8c 289 SPI_CLOCK_DIV32768 = 32768, ///< 32768 = 126us = 8kHz
hudakz 1:1f2d9982fa8c 290 SPI_CLOCK_DIV16384 = 16384, ///< 16384 = 64us = 15.625kHz
hudakz 1:1f2d9982fa8c 291 SPI_CLOCK_DIV8192 = 8192, ///< 8192 = 32us = 31.25kHz
hudakz 1:1f2d9982fa8c 292 SPI_CLOCK_DIV4096 = 4096, ///< 4096 = 16us = 62.5kHz
hudakz 1:1f2d9982fa8c 293 SPI_CLOCK_DIV2048 = 2048, ///< 2048 = 8us = 125kHz
hudakz 1:1f2d9982fa8c 294 SPI_CLOCK_DIV1024 = 1024, ///< 1024 = 4us = 250kHz
hudakz 1:1f2d9982fa8c 295 SPI_CLOCK_DIV512 = 512, ///< 512 = 2us = 500kHz
hudakz 1:1f2d9982fa8c 296 SPI_CLOCK_DIV256 = 256, ///< 256 = 1us = 1MHz
hudakz 1:1f2d9982fa8c 297 SPI_CLOCK_DIV128 = 128, ///< 128 = 500ns = = 2MHz
hudakz 1:1f2d9982fa8c 298 SPI_CLOCK_DIV64 = 64, ///< 64 = 250ns = 4MHz
hudakz 1:1f2d9982fa8c 299 SPI_CLOCK_DIV32 = 32, ///< 32 = 125ns = 8MHz
hudakz 1:1f2d9982fa8c 300 SPI_CLOCK_DIV16 = 16, ///< 16 = 50ns = 20MHz
hudakz 1:1f2d9982fa8c 301 SPI_CLOCK_DIV8 = 8, ///< 8 = 25ns = 40MHz
hudakz 1:1f2d9982fa8c 302 SPI_CLOCK_DIV4 = 4, ///< 4 = 12.5ns 80MHz
hudakz 1:1f2d9982fa8c 303 SPI_CLOCK_DIV2 = 2, ///< 2 = 6.25ns = 160MHz
hudakz 1:1f2d9982fa8c 304 SPI_CLOCK_DIV1 = 1, ///< 0 = 256us = 4kHz
hudakz 1:1f2d9982fa8c 305 } bcm2835SPIClockDivider;
hudakz 1:1f2d9982fa8c 306
hudakz 1:1f2d9982fa8c 307 /*! \brief bcm2835PWMClockDivider
hudakz 1:1f2d9982fa8c 308 Specifies the divider used to generate the PWM clock from the system clock.
hudakz 1:1f2d9982fa8c 309 Figures below give the divider, clock period and clock frequency.
hudakz 1:1f2d9982fa8c 310 Clock divided is based on nominal PWM base clock rate of 19.2MHz
hudakz 1:1f2d9982fa8c 311 The frequencies shown for each divider have been confirmed by measurement
hudakz 1:1f2d9982fa8c 312 */
hudakz 1:1f2d9982fa8c 313 typedef enum
hudakz 1:1f2d9982fa8c 314 {
hudakz 1:1f2d9982fa8c 315 BCM2835_PWM_CLOCK_DIVIDER_4096 = 4096, /*!< 4096 = 4.6875kHz */
hudakz 1:1f2d9982fa8c 316 BCM2835_PWM_CLOCK_DIVIDER_2048 = 2048, /*!< 2048 = 9.375kHz */
hudakz 1:1f2d9982fa8c 317 BCM2835_PWM_CLOCK_DIVIDER_1024 = 1024, /*!< 1024 = 18.75kHz */
hudakz 1:1f2d9982fa8c 318 BCM2835_PWM_CLOCK_DIVIDER_512 = 512, /*!< 512 = 37.5kHz */
hudakz 1:1f2d9982fa8c 319 BCM2835_PWM_CLOCK_DIVIDER_256 = 256, /*!< 256 = 75kHz */
hudakz 1:1f2d9982fa8c 320 BCM2835_PWM_CLOCK_DIVIDER_128 = 128, /*!< 128 = 150kHz */
hudakz 1:1f2d9982fa8c 321 BCM2835_PWM_CLOCK_DIVIDER_64 = 64, /*!< 64 = 300kHz */
hudakz 1:1f2d9982fa8c 322 BCM2835_PWM_CLOCK_DIVIDER_32 = 32, /*!< 32 = 600.0kHz */
hudakz 1:1f2d9982fa8c 323 BCM2835_PWM_CLOCK_DIVIDER_16 = 16, /*!< 16 = 1.2MHz */
hudakz 1:1f2d9982fa8c 324 BCM2835_PWM_CLOCK_DIVIDER_8 = 8, /*!< 8 = 2.4MHz */
hudakz 1:1f2d9982fa8c 325 BCM2835_PWM_CLOCK_DIVIDER_4 = 4, /*!< 4 = 4.8MHz */
hudakz 1:1f2d9982fa8c 326 BCM2835_PWM_CLOCK_DIVIDER_2 = 2, /*!< 2 = 9.6MHz, fastest you can get */
hudakz 1:1f2d9982fa8c 327 BCM2835_PWM_CLOCK_DIVIDER_1 = 1 /*!< 1 = 4.6875kHz, same as divider 4096 */
hudakz 1:1f2d9982fa8c 328 } bcm2835PWMClockDivider;
hudakz 1:1f2d9982fa8c 329
hudakz 1:1f2d9982fa8c 330 /*! \brief bcm2835PWMClockDivider
hudakz 1:1f2d9982fa8c 331 Specifies the divider used to generate the PWM clock from the system clock.
hudakz 1:1f2d9982fa8c 332 Figures below give the divider, clock period and clock frequency.
hudakz 1:1f2d9982fa8c 333 Clock divided is based on nominal PWM base clock rate of 19.2MHz
hudakz 1:1f2d9982fa8c 334 The frequencies shown for each divider have been confirmed by measurement
hudakz 1:1f2d9982fa8c 335 */
hudakz 1:1f2d9982fa8c 336 typedef enum
hudakz 1:1f2d9982fa8c 337 {
hudakz 1:1f2d9982fa8c 338 BCM2835_PWM_PERIOD_212_US = 4096, /*!< 213.33 us = 4.6875kHz */
hudakz 1:1f2d9982fa8c 339 BCM2835_PWM_PERIOD_107_US = 2048, /*!< 106.66 us = 9.375kHz */
hudakz 1:1f2d9982fa8c 340 BCM2835_PWM_PERIOD_53_US = 1024, /*!< 53.33 us = 18.75kHz */
hudakz 1:1f2d9982fa8c 341 BCM2835_PWM_PERIOD_27_US = 512, /*!< 26.66 us = 37.5kHz */
hudakz 1:1f2d9982fa8c 342 BCM2835_PWM_PERIOD_13_US = 256, /*!< 13.33 us = 75kHz */
hudakz 1:1f2d9982fa8c 343 BCM2835_PWM_PERIOD_6_6_US = 128, /*!< 6.66 us = 150kHz */
hudakz 1:1f2d9982fa8c 344 BCM2835_PWM_PERIOD_3_3_US = 64, /*!< 3.33 us = 300kHz */
hudakz 1:1f2d9982fa8c 345 BCM2835_PWM_PERIOD_1_7_US = 32, /*!< 1.66 us = 600.0kHz */
hudakz 1:1f2d9982fa8c 346 BCM2835_PWM_PERIOD_833_NS = 16, /*!< 833.33 ns = 1.2MHz */
hudakz 1:1f2d9982fa8c 347 BCM2835_PWM_PERIOD_417_NS = 8, /*!< 416.66 ns = 2.4MHz */
hudakz 1:1f2d9982fa8c 348 BCM2835_PWM_PERIOD_208_NS = 4, /*!< 208.33 ns = 4.8MHz */
hudakz 1:1f2d9982fa8c 349 BCM2835_PWM_PERIOD_104_NS = 2, /*!< 104.16 ns = 9.6MHz, */
hudakz 1:1f2d9982fa8c 350 } bcm2835_PWM_PulsePeriod;
hudakz 1:1f2d9982fa8c 351
hudakz 1:1f2d9982fa8c 352 typedef enum
hudakz 1:1f2d9982fa8c 353 {
hudakz 1:1f2d9982fa8c 354 BCM2835_GPIO_FSEL_INPT = 0b000, ///< Input
hudakz 1:1f2d9982fa8c 355 BCM2835_GPIO_FSEL_OUTP = 0b001, ///< Output
hudakz 1:1f2d9982fa8c 356 BCM2835_GPIO_FSEL_ALT0 = 0b100, ///< Alternate function 0
hudakz 1:1f2d9982fa8c 357 BCM2835_GPIO_FSEL_ALT1 = 0b101, ///< Alternate function 1
hudakz 1:1f2d9982fa8c 358 BCM2835_GPIO_FSEL_ALT2 = 0b110, ///< Alternate function 2
hudakz 1:1f2d9982fa8c 359 BCM2835_GPIO_FSEL_ALT3 = 0b111, ///< Alternate function 3
hudakz 1:1f2d9982fa8c 360 BCM2835_GPIO_FSEL_ALT4 = 0b011, ///< Alternate function 4
hudakz 1:1f2d9982fa8c 361 BCM2835_GPIO_FSEL_ALT5 = 0b010, ///< Alternate function 5
hudakz 1:1f2d9982fa8c 362 BCM2835_GPIO_FSEL_MASK = 0b111 ///< Function select bits mask
hudakz 1:1f2d9982fa8c 363 } bcm2835FunctionSelect;
hudakz 1:1f2d9982fa8c 364
hudakz 1:1f2d9982fa8c 365 namespace unistd {
hudakz 1:1f2d9982fa8c 366 //All functions of unistd.h must be called like this: unistd::the_function()
hudakz 1:1f2d9982fa8c 367 #include <unistd.h>
hudakz 1:1f2d9982fa8c 368 }
hudakz 1:1f2d9982fa8c 369
hudakz 1:1f2d9982fa8c 370 enum Representation{
hudakz 1:1f2d9982fa8c 371 BIN,
hudakz 1:1f2d9982fa8c 372 OCT,
hudakz 1:1f2d9982fa8c 373 DEC,
hudakz 1:1f2d9982fa8c 374 HEX,
hudakz 1:1f2d9982fa8c 375 BYTE
hudakz 1:1f2d9982fa8c 376 };
hudakz 1:1f2d9982fa8c 377
hudakz 1:1f2d9982fa8c 378 typedef enum {
hudakz 1:1f2d9982fa8c 379 LOW = 0,
hudakz 1:1f2d9982fa8c 380 HIGH = 1,
hudakz 1:1f2d9982fa8c 381 RISING = 2,
hudakz 1:1f2d9982fa8c 382 FALLING = 3,
hudakz 1:1f2d9982fa8c 383 BOTH = 4
hudakz 1:1f2d9982fa8c 384 } Digivalue;
hudakz 1:1f2d9982fa8c 385 //
hudakz 1:1f2d9982fa8c 386 /*$on*/
hudakz 1:1f2d9982fa8c 387 //
hudakz 1:1f2d9982fa8c 388 typedef bool boolean;
hudakz 1:1f2d9982fa8c 389 typedef unsigned char byte;
hudakz 1:1f2d9982fa8c 390
hudakz 1:1f2d9982fa8c 391 struct bcm2835_peripheral
hudakz 1:1f2d9982fa8c 392 {
hudakz 1:1f2d9982fa8c 393 unsigned long addr_p;
hudakz 1:1f2d9982fa8c 394 int mem_fd;
hudakz 1:1f2d9982fa8c 395 void* map;
hudakz 1:1f2d9982fa8c 396 volatile unsigned int* addr;
hudakz 1:1f2d9982fa8c 397 };
hudakz 1:1f2d9982fa8c 398
hudakz 1:1f2d9982fa8c 399
hudakz 1:1f2d9982fa8c 400
hudakz 1:1f2d9982fa8c 401 /* Helper functions */
hudakz 1:1f2d9982fa8c 402 int getBoardRev();
hudakz 1:1f2d9982fa8c 403 uint32_t* mapmem(const char* msg, size_t size, int fd, off_t off);
hudakz 1:1f2d9982fa8c 404 void setBoardRev(int rev);
hudakz 1:1f2d9982fa8c 405 pthread_t* getThreadIdFromPin(int pin);
hudakz 1:1f2d9982fa8c 406 void* threadFunction(void* args);
hudakz 1:1f2d9982fa8c 407 uint32_t bcm2835_peri_read(volatile uint32_t* paddr);
hudakz 1:1f2d9982fa8c 408 uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr);
hudakz 1:1f2d9982fa8c 409 void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value);
hudakz 1:1f2d9982fa8c 410 void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value);
hudakz 1:1f2d9982fa8c 411 void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask);
hudakz 1:1f2d9982fa8c 412 void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode);
hudakz 1:1f2d9982fa8c 413 uint64_t bcm2835_systimer_read(void);
hudakz 1:1f2d9982fa8c 414 void bcm2835_delay (unsigned int millis);
hudakz 1:1f2d9982fa8c 415 void bcm2835_pwm_set_clock(uint32_t divisor);
hudakz 1:1f2d9982fa8c 416 void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled);
hudakz 1:1f2d9982fa8c 417 void bcm2835_pwm_set_range(uint8_t channel, uint32_t range);
hudakz 1:1f2d9982fa8c 418 void bcm2835_pwm_set_data(uint8_t channel, uint32_t data);
hudakz 1:1f2d9982fa8c 419 void gpio_dir(PinName pin, PinDirection direction);
hudakz 1:1f2d9982fa8c 420 void gpio_mode(PinName pin, PinMode mode);
hudakz 1:1f2d9982fa8c 421 void gpio_write(PinName pin, int value);
hudakz 1:1f2d9982fa8c 422 int gpio_read(PinName pin);
hudakz 1:1f2d9982fa8c 423 uint8_t shiftIn(PinName dPin, PinName cPin, bcm2835SPIBitOrder order);
hudakz 1:1f2d9982fa8c 424 void shiftOut(PinName dPin, PinName cPin, bcm2835SPIBitOrder order, uint8_t val);
hudakz 1:1f2d9982fa8c 425 void attachInterrupt(PinName p, void (*f) (), Digivalue m);
hudakz 1:1f2d9982fa8c 426 void detachInterrupt(PinName p);
hudakz 1:1f2d9982fa8c 427
hudakz 1:1f2d9982fa8c 428 typedef void (*FunctionPointer) ();
hudakz 1:1f2d9982fa8c 429
hudakz 1:1f2d9982fa8c 430 static int REV = 0;
hudakz 1:1f2d9982fa8c 431
hudakz 1:1f2d9982fa8c 432 #endif // _BCM2835_H_
hudakz 1:1f2d9982fa8c 433