commit 43332ea12503aa67dd4e2d91bf60795eca99d4bf Author: tmeissner Date: Sun Jan 12 01:31:58 2014 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d239463 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +.idea +*.swp +*.*#* diff --git a/st7565-lcd/ada/bcm2835.c b/st7565-lcd/ada/bcm2835.c new file mode 100644 index 0000000..4db1a34 --- /dev/null +++ b/st7565-lcd/ada/bcm2835.c @@ -0,0 +1,1199 @@ +// bcm2835.c +// C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi +// http://elinux.org/RPi_Low-level_peripherals +// http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf +// +// Author: Mike McCauley +// Copyright (C) 2011-2013 Mike McCauley +// $Id: bcm2835.c,v 1.12 2013/09/01 00:56:56 mikem Exp mikem $ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "bcm2835.h" + +// This define enables a little test program (by default a blinking output on pin RPI_GPIO_PIN_11) +// You can do some safe, non-destructive testing on any platform with: +// gcc bcm2835.c -D BCM2835_TEST +// ./a.out +//#define BCM2835_TEST + +// Uncommenting this define compiles alternative I2C code for the version 1 RPi +// The P1 header I2C pins are connected to SDA0 and SCL0 on V1. +// By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected. +// #define I2C_V1 + +// Pointers to the hardware register bases +volatile uint32_t *bcm2835_gpio = MAP_FAILED; +volatile uint32_t *bcm2835_pwm = MAP_FAILED; +volatile uint32_t *bcm2835_clk = MAP_FAILED; +volatile uint32_t *bcm2835_pads = MAP_FAILED; +volatile uint32_t *bcm2835_spi0 = MAP_FAILED; +volatile uint32_t *bcm2835_bsc0 = MAP_FAILED; +volatile uint32_t *bcm2835_bsc1 = MAP_FAILED; +volatile uint32_t *bcm2835_st = MAP_FAILED; + + +// This variable allows us to test on hardware other than RPi. +// It prevents access to the kernel memory, and does not do any peripheral access +// Instead it prints out what it _would_ do if debug were 0 +static uint8_t debug = 0; + +// I2C The time needed to transmit one byte. In microseconds. +static int i2c_byte_wait_us = 0; + +// +// Low level register access functions +// + +void bcm2835_set_debug(uint8_t d) +{ + debug = d; +} + +// safe read from peripheral +uint32_t bcm2835_peri_read(volatile uint32_t* paddr) +{ + if (debug) + { + printf("bcm2835_peri_read paddr %08X\n", (unsigned) paddr); + return 0; + } + else + { + // Make sure we dont return the _last_ read which might get lost + // if subsequent code changes to a different peripheral + uint32_t ret = *paddr; + *paddr; // Read without assigneing to an unused variable + return ret; + } +} + +// read from peripheral without the read barrier +uint32_t bcm2835_peri_read_nb(volatile uint32_t* paddr) +{ + if (debug) + { + printf("bcm2835_peri_read_nb paddr %08X\n", (unsigned) paddr); + return 0; + } + else + { + return *paddr; + } +} + +// safe write to peripheral +void bcm2835_peri_write(volatile uint32_t* paddr, uint32_t value) +{ + if (debug) + { + printf("bcm2835_peri_write paddr %08X, value %08X\n", (unsigned) paddr, value); + } + else + { + // Make sure we don't rely on the first write, which may get + // lost if the previous access was to a different peripheral. + *paddr = value; + *paddr = value; + } +} + +// write to peripheral without the write barrier +void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value) +{ + if (debug) + { + printf("bcm2835_peri_write_nb paddr %08X, value %08X\n", + (unsigned) paddr, value); + } + else + { + *paddr = value; + } +} + +// Set/clear only the bits in value covered by the mask +void bcm2835_peri_set_bits(volatile uint32_t* paddr, uint32_t value, uint32_t mask) +{ + uint32_t v = bcm2835_peri_read(paddr); + v = (v & ~mask) | (value & mask); + bcm2835_peri_write(paddr, v); +} + +// +// Low level convenience functions +// + +// Function select +// pin is a BCM2835 GPIO pin number NOT RPi pin number +// There are 6 control registers, each control the functions of a block +// of 10 pins. +// Each control register has 10 sets of 3 bits per GPIO pin: +// +// 000 = GPIO Pin X is an input +// 001 = GPIO Pin X is an output +// 100 = GPIO Pin X takes alternate function 0 +// 101 = GPIO Pin X takes alternate function 1 +// 110 = GPIO Pin X takes alternate function 2 +// 111 = GPIO Pin X takes alternate function 3 +// 011 = GPIO Pin X takes alternate function 4 +// 010 = GPIO Pin X takes alternate function 5 +// +// So the 3 bits for port X are: +// X / 10 + ((X % 10) * 3) +void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode) +{ + // Function selects are 10 pins per 32 bit word, 3 bits per pin + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFSEL0/4 + (pin/10); + uint8_t shift = (pin % 10) * 3; + uint32_t mask = BCM2835_GPIO_FSEL_MASK << shift; + uint32_t value = mode << shift; + bcm2835_peri_set_bits(paddr, value, mask); +} + +// Set output pin +void bcm2835_gpio_set(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPSET0/4 + pin/32; + uint8_t shift = pin % 32; + bcm2835_peri_write(paddr, 1 << shift); +} + +// Clear output pin +void bcm2835_gpio_clr(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPCLR0/4 + pin/32; + uint8_t shift = pin % 32; + bcm2835_peri_write(paddr, 1 << shift); +} + +// Set all output pins in the mask +void bcm2835_gpio_set_multi(uint32_t mask) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPSET0/4; + bcm2835_peri_write(paddr, mask); +} + +// Clear all output pins in the mask +void bcm2835_gpio_clr_multi(uint32_t mask) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPCLR0/4; + bcm2835_peri_write(paddr, mask); +} + +// Read input pin +uint8_t bcm2835_gpio_lev(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEV0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = bcm2835_peri_read(paddr); + return (value & (1 << shift)) ? HIGH : LOW; +} + +// See if an event detection bit is set +// Sigh cant support interrupts yet +uint8_t bcm2835_gpio_eds(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = bcm2835_peri_read(paddr); + return (value & (1 << shift)) ? HIGH : LOW; +} + +// Write a 1 to clear the bit in EDS +void bcm2835_gpio_set_eds(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPEDS0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_write(paddr, value); +} + +// Rising edge detect enable +void bcm2835_gpio_ren(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPREN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, value, value); +} +void bcm2835_gpio_clr_ren(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPREN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, 0, value); +} + +// Falling edge detect enable +void bcm2835_gpio_fen(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFEN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, value, value); +} +void bcm2835_gpio_clr_fen(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPFEN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, 0, value); +} + +// High detect enable +void bcm2835_gpio_hen(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPHEN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, value, value); +} +void bcm2835_gpio_clr_hen(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPHEN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, 0, value); +} + +// Low detect enable +void bcm2835_gpio_len(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, value, value); +} +void bcm2835_gpio_clr_len(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPLEN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, 0, value); +} + +// Async rising edge detect enable +void bcm2835_gpio_aren(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAREN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, value, value); +} +void bcm2835_gpio_clr_aren(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAREN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, 0, value); +} + +// Async falling edge detect enable +void bcm2835_gpio_afen(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAFEN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, value, value); +} +void bcm2835_gpio_clr_afen(uint8_t pin) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPAFEN0/4 + pin/32; + uint8_t shift = pin % 32; + uint32_t value = 1 << shift; + bcm2835_peri_set_bits(paddr, 0, value); +} + +// Set pullup/down +void bcm2835_gpio_pud(uint8_t pud) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUD/4; + bcm2835_peri_write(paddr, pud); +} + +// Pullup/down clock +// Clocks the value of pud into the GPIO pin +void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on) +{ + volatile uint32_t* paddr = bcm2835_gpio + BCM2835_GPPUDCLK0/4 + pin/32; + uint8_t shift = pin % 32; + bcm2835_peri_write(paddr, (on ? 1 : 0) << shift); +} + +// Read GPIO pad behaviour for groups of GPIOs +uint32_t bcm2835_gpio_pad(uint8_t group) +{ + volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group*2; + return bcm2835_peri_read(paddr); +} + +// Set GPIO pad behaviour for groups of GPIOs +// powerup value for al pads is +// BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA +void bcm2835_gpio_set_pad(uint8_t group, uint32_t control) +{ + volatile uint32_t* paddr = bcm2835_pads + BCM2835_PADS_GPIO_0_27/4 + group*2; + bcm2835_peri_write(paddr, control | BCM2835_PAD_PASSWRD); +} + +// Some convenient arduino-like functions +// milliseconds +void bcm2835_delay(unsigned int millis) +{ + struct timespec sleeper; + + sleeper.tv_sec = (time_t)(millis / 1000); + sleeper.tv_nsec = (long)(millis % 1000) * 1000000; + nanosleep(&sleeper, NULL); +} + +// microseconds +void bcm2835_delayMicroseconds(uint64_t micros) +{ + struct timespec t1; + uint64_t start; + + // Calling nanosleep() takes at least 100-200 us, so use it for + // long waits and use a busy wait on the System Timer for the rest. + start = bcm2835_st_read(); + + if (micros > 450) + { + t1.tv_sec = 0; + t1.tv_nsec = 1000 * (long)(micros - 200); + nanosleep(&t1, NULL); + } + + bcm2835_st_delay(start, micros); +} + +// +// Higher level convenience functions +// + +// Set the state of an output +void bcm2835_gpio_write(uint8_t pin, uint8_t on) +{ + if (on) + bcm2835_gpio_set(pin); + else + bcm2835_gpio_clr(pin); +} + +// Set the state of a all 32 outputs in the mask to on or off +void bcm2835_gpio_write_multi(uint32_t mask, uint8_t on) +{ + if (on) + bcm2835_gpio_set_multi(mask); + else + bcm2835_gpio_clr_multi(mask); +} + +// Set the state of a all 32 outputs in the mask to the values in value +void bcm2835_gpio_write_mask(uint32_t value, uint32_t mask) +{ + bcm2835_gpio_set_multi(value & mask); + bcm2835_gpio_clr_multi((~value) & mask); +} + +// Set the pullup/down resistor for a pin +// +// The GPIO Pull-up/down Clock Registers control the actuation of internal pull-downs on +// the respective GPIO pins. These registers must be used in conjunction with the GPPUD +// register to effect GPIO Pull-up/down changes. The following sequence of events is +// required: +// 1. Write to GPPUD to set the required control signal (i.e. Pull-up or Pull-Down or neither +// to remove the current Pull-up/down) +// 2. Wait 150 cycles ? this provides the required set-up time for the control signal +// 3. Write to GPPUDCLK0/1 to clock the control signal into the GPIO pads you wish to +// modify ? NOTE only the pads which receive a clock will be modified, all others will +// retain their previous state. +// 4. Wait 150 cycles ? this provides the required hold time for the control signal +// 5. Write to GPPUD to remove the control signal +// 6. Write to GPPUDCLK0/1 to remove the clock +// +// RPi has P1-03 and P1-05 with 1k8 pullup resistor +void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud) +{ + bcm2835_gpio_pud(pud); + delayMicroseconds(10); + bcm2835_gpio_pudclk(pin, 1); + delayMicroseconds(10); + bcm2835_gpio_pud(BCM2835_GPIO_PUD_OFF); + bcm2835_gpio_pudclk(pin, 0); +} + +void bcm2835_spi_begin(void) +{ + // Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them + bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); // CE1 + bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); // CE0 + bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_ALT0); // MISO + bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_ALT0); // MOSI + bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_ALT0); // CLK + + // Set the SPI CS register to the some sensible defaults + volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; + bcm2835_peri_write(paddr, 0); // All 0s + + // Clear TX and RX fifos + bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR); +} + +void bcm2835_spi_end(void) +{ + // Set all the SPI0 pins back to input + bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_INPT); // CE1 + bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_INPT); // CE0 + bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_INPT); // MISO + bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_INPT); // MOSI + bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_INPT); // CLK +} + +void bcm2835_spi_setBitOrder(uint8_t order) +{ + // BCM2835_SPI_BIT_ORDER_MSBFIRST is the only one suported by SPI0 +} + +// defaults to 0, which means a divider of 65536. +// The divisor must be a power of 2. Odd numbers +// rounded down. The maximum SPI clock rate is +// of the APB clock +void bcm2835_spi_setClockDivider(uint16_t divider) +{ + volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CLK/4; + bcm2835_peri_write(paddr, divider); +} + +void bcm2835_spi_setDataMode(uint8_t mode) +{ + volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; + // Mask in the CPO and CPHA bits of CS + bcm2835_peri_set_bits(paddr, mode << 2, BCM2835_SPI0_CS_CPOL | BCM2835_SPI0_CS_CPHA); +} + +// Writes (and reads) a single byte to SPI +uint8_t bcm2835_spi_transfer(uint8_t value) +{ + volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; + volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; + + // This is Polled transfer as per section 10.6.1 + // BUG ALERT: what happens if we get interupted in this section, and someone else + // accesses a different peripheral? + // Clear TX and RX fifos + bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); + + // Set TA = 1 + bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); + + // Maybe wait for TXD + while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD)) + ; + + // Write to FIFO, no barrier + bcm2835_peri_write_nb(fifo, value); + + // Wait for DONE to be set + while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) + ; + + // Read any byte that was sent back by the slave while we sere sending to it + uint32_t ret = bcm2835_peri_read_nb(fifo); + + // Set TA = 0, and also set the barrier + bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); + + return ret; +} + +// Writes (and reads) an number of bytes to SPI +void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len) +{ + volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; + volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; + + // This is Polled transfer as per section 10.6.1 + // BUG ALERT: what happens if we get interupted in this section, and someone else + // accesses a different peripheral? + + // Clear TX and RX fifos + bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); + + // Set TA = 1 + bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); + + uint32_t i; + for (i = 0; i < len; i++) + { + // Maybe wait for TXD + while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD)) + ; + + // Write to FIFO, no barrier + bcm2835_peri_write_nb(fifo, tbuf[i]); + + // Wait for RXD + while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD)) + ; + + // then read the data byte + rbuf[i] = bcm2835_peri_read_nb(fifo); + } + // Wait for DONE to be set + while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) + ; + + // Set TA = 0, and also set the barrier + bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); +} + +// Writes an number of bytes to SPI +void bcm2835_spi_writenb(char* tbuf, uint32_t len) +{ + volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; + volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; + + // This is Polled transfer as per section 10.6.1 + // BUG ALERT: what happens if we get interupted in this section, and someone else + // accesses a different peripheral? + + // Clear TX and RX fifos + bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR); + + // Set TA = 1 + bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_TA, BCM2835_SPI0_CS_TA); + + uint32_t i; + for (i = 0; i < len; i++) + { + // Maybe wait for TXD + while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD)) + ; + + // Write to FIFO, no barrier + bcm2835_peri_write_nb(fifo, tbuf[i]); + + // Read from FIFO to prevent stalling + while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD) + (void) bcm2835_peri_read_nb(fifo); + } + + // Wait for DONE to be set + while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) { + while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD) + (void) bcm2835_peri_read_nb(fifo); + }; + + // Set TA = 0, and also set the barrier + bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); +} + +// Writes (and reads) an number of bytes to SPI +// Read bytes are copied over onto the transmit buffer +void bcm2835_spi_transfern(char* buf, uint32_t len) +{ + bcm2835_spi_transfernb(buf, buf, len); +} + +void bcm2835_spi_chipSelect(uint8_t cs) +{ + volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; + // Mask in the CS bits of CS + bcm2835_peri_set_bits(paddr, cs, BCM2835_SPI0_CS_CS); +} + +void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active) +{ + volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; + uint8_t shift = 21 + cs; + // Mask in the appropriate CSPOLn bit + bcm2835_peri_set_bits(paddr, active << shift, 1 << shift); +} + +void bcm2835_i2c_begin(void) +{ +#ifdef I2C_V1 + volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_DIV/4; + // Set the I2C/BSC0 pins to the Alt 0 function to enable I2C access on them + bcm2835_gpio_fsel(RPI_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); // SDA + bcm2835_gpio_fsel(RPI_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); // SCL +#else + volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4; + // Set the I2C/BSC1 pins to the Alt 0 function to enable I2C access on them + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); // SDA + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); // SCL +#endif + + // Read the clock divider register + uint16_t cdiv = bcm2835_peri_read(paddr); + // Calculate time for transmitting one byte + // 1000000 = micros seconds in a second + // 9 = Clocks per byte : 8 bits + ACK + i2c_byte_wait_us = ((float)cdiv / BCM2835_CORE_CLK_HZ) * 1000000 * 9; +} + +void bcm2835_i2c_end(void) +{ +#ifdef I2C_V1 + // Set all the I2C/BSC0 pins back to input + bcm2835_gpio_fsel(RPI_GPIO_P1_03, BCM2835_GPIO_FSEL_INPT); // SDA + bcm2835_gpio_fsel(RPI_GPIO_P1_05, BCM2835_GPIO_FSEL_INPT); // SCL +#else + // Set all the I2C/BSC1 pins back to input + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_INPT); // SDA + bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_INPT); // SCL +#endif +} + +void bcm2835_i2c_setSlaveAddress(uint8_t addr) +{ + // Set I2C Device Address +#ifdef I2C_V1 + volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_A/4; +#else + volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_A/4; +#endif + bcm2835_peri_write(paddr, addr); +} + +// defaults to 0x5dc, should result in a 166.666 kHz I2C clock frequency. +// The divisor must be a power of 2. Odd numbers +// rounded down. +void bcm2835_i2c_setClockDivider(uint16_t divider) +{ +#ifdef I2C_V1 + volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_DIV/4; +#else + volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4; +#endif + bcm2835_peri_write(paddr, divider); + // Calculate time for transmitting one byte + // 1000000 = micros seconds in a second + // 9 = Clocks per byte : 8 bits + ACK + i2c_byte_wait_us = ((float)divider / BCM2835_CORE_CLK_HZ) * 1000000 * 9; +} + +// set I2C clock divider by means of a baudrate number +void bcm2835_i2c_set_baudrate(uint32_t baudrate) +{ + uint32_t divider; + // use 0xFFFE mask to limit a max value and round down any odd number + divider = (BCM2835_CORE_CLK_HZ / baudrate) & 0xFFFE; + bcm2835_i2c_setClockDivider( (uint16_t)divider ); +} + +// Writes an number of bytes to I2C +uint8_t bcm2835_i2c_write(const char * buf, uint32_t len) +{ +#ifdef I2C_V1 + volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4; + volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4; + volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4; + volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4; +#else + volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4; + volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4; + volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4; + volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4; +#endif + + uint32_t remaining = len; + uint32_t i = 0; + uint8_t reason = BCM2835_I2C_REASON_OK; + + // Clear FIFO + bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 ); + // Clear Status + bcm2835_peri_write_nb(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); + // Set Data Length + bcm2835_peri_write_nb(dlen, len); + // pre populate FIFO with max buffer + while( remaining && ( i < BCM2835_BSC_FIFO_SIZE ) ) + { + bcm2835_peri_write_nb(fifo, buf[i]); + i++; + remaining--; + } + + // Enable device and start transfer + bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST); + + // Transfer is over when BCM2835_BSC_S_DONE + while(!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE )) + { + while ( remaining && (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_TXD )) + { + // Write to FIFO, no barrier + bcm2835_peri_write_nb(fifo, buf[i]); + i++; + remaining--; + } + } + + // Received a NACK + if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR) + { + reason = BCM2835_I2C_REASON_ERROR_NACK; + } + + // Received Clock Stretch Timeout + else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT) + { + reason = BCM2835_I2C_REASON_ERROR_CLKT; + } + + // Not all data is sent + else if (remaining) + { + reason = BCM2835_I2C_REASON_ERROR_DATA; + } + + bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); + + return reason; +} + +// Read an number of bytes from I2C +uint8_t bcm2835_i2c_read(char* buf, uint32_t len) +{ +#ifdef I2C_V1 + volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4; + volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4; + volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4; + volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4; +#else + volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4; + volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4; + volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4; + volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4; +#endif + + uint32_t remaining = len; + uint32_t i = 0; + uint8_t reason = BCM2835_I2C_REASON_OK; + + // Clear FIFO + bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 ); + // Clear Status + bcm2835_peri_write_nb(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); + // Set Data Length + bcm2835_peri_write_nb(dlen, len); + // Start read + bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ); + + // wait for transfer to complete + while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE)) + { + // we must empty the FIFO as it is populated and not use any delay + while (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD) + { + // Read from FIFO, no barrier + buf[i] = bcm2835_peri_read_nb(fifo); + i++; + remaining--; + } + } + + // transfer has finished - grab any remaining stuff in FIFO + while (remaining && (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD)) + { + // Read from FIFO, no barrier + buf[i] = bcm2835_peri_read_nb(fifo); + i++; + remaining--; + } + + // Received a NACK + if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR) + { + reason = BCM2835_I2C_REASON_ERROR_NACK; + } + + // Received Clock Stretch Timeout + else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT) + { + reason = BCM2835_I2C_REASON_ERROR_CLKT; + } + + // Not all data is received + else if (remaining) + { + reason = BCM2835_I2C_REASON_ERROR_DATA; + } + + bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); + + return reason; +} + +// Read an number of bytes from I2C sending a repeated start after writing +// the required register. Only works if your device supports this mode +uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len) +{ +#ifdef I2C_V1 + volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4; + volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4; + volatile uint32_t* status = bcm2835_bsc0 + BCM2835_BSC_S/4; + volatile uint32_t* control = bcm2835_bsc0 + BCM2835_BSC_C/4; +#else + volatile uint32_t* dlen = bcm2835_bsc1 + BCM2835_BSC_DLEN/4; + volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4; + volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4; + volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4; +#endif + uint32_t remaining = len; + uint32_t i = 0; + uint8_t reason = BCM2835_I2C_REASON_OK; + + // Clear FIFO + bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 ); + // Clear Status + bcm2835_peri_write_nb(status, BCM2835_BSC_S_CLKT | BCM2835_BSC_S_ERR | BCM2835_BSC_S_DONE); + // Set Data Length + bcm2835_peri_write_nb(dlen, 1); + // Enable device and start transfer + bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN); + bcm2835_peri_write_nb(fifo, regaddr[0]); + bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST); + + // poll for transfer has started + while ( !( bcm2835_peri_read_nb(status) & BCM2835_BSC_S_TA ) ) + { + // Linux may cause us to miss entire transfer stage + if(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE) + break; + } + + // Send a repeated start with read bit set in address + bcm2835_peri_write_nb(dlen, len); + bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ ); + + // Wait for write to complete and first byte back. + bcm2835_delayMicroseconds(i2c_byte_wait_us * 3); + + // wait for transfer to complete + while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE)) + { + // we must empty the FIFO as it is populated and not use any delay + while (remaining && bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD) + { + // Read from FIFO, no barrier + buf[i] = bcm2835_peri_read_nb(fifo); + i++; + remaining--; + } + } + + // transfer has finished - grab any remaining stuff in FIFO + while (remaining && (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD)) + { + // Read from FIFO, no barrier + buf[i] = bcm2835_peri_read_nb(fifo); + i++; + remaining--; + } + + // Received a NACK + if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR) + { + reason = BCM2835_I2C_REASON_ERROR_NACK; + } + + // Received Clock Stretch Timeout + else if (bcm2835_peri_read(status) & BCM2835_BSC_S_CLKT) + { + reason = BCM2835_I2C_REASON_ERROR_CLKT; + } + + // Not all data is sent + else if (remaining) + { + reason = BCM2835_I2C_REASON_ERROR_DATA; + } + + bcm2835_peri_set_bits(control, BCM2835_BSC_S_DONE , BCM2835_BSC_S_DONE); + + return reason; +} + +// Read the System Timer Counter (64-bits) +uint64_t bcm2835_st_read(void) +{ + volatile uint32_t* paddr; + uint64_t st; + paddr = bcm2835_st + BCM2835_ST_CHI/4; + st = bcm2835_peri_read(paddr); + st <<= 32; + paddr = bcm2835_st + BCM2835_ST_CLO/4; + st += bcm2835_peri_read(paddr); + return st; +} + +// Delays for the specified number of microseconds with offset +void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros) +{ + uint64_t compare = offset_micros + micros; + + while(bcm2835_st_read() < compare) + ; +} + +// PWM + +void bcm2835_pwm_set_clock(uint32_t divisor) +{ + // From Gerts code + divisor &= 0xfff; + // Stop PWM clock + bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x01); + bcm2835_delay(110); // Prevents clock going slow + // Wait for the clock to be not busy + while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0) + bcm2835_delay(1); + // set the clock divider and enable PWM clock + bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisor << 12)); + bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x11); // Source=osc and enable +} + +void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled) +{ + uint32_t control = bcm2835_peri_read(bcm2835_pwm + BCM2835_PWM_CONTROL); + + if (channel == 0) + { + if (markspace) + control |= BCM2835_PWM0_MS_MODE; + else + control &= ~BCM2835_PWM0_MS_MODE; + if (enabled) + control |= BCM2835_PWM0_ENABLE; + else + control &= ~BCM2835_PWM0_ENABLE; + } + else if (channel == 1) + { + if (markspace) + control |= BCM2835_PWM1_MS_MODE; + else + control &= ~BCM2835_PWM1_MS_MODE; + if (enabled) + control |= BCM2835_PWM1_ENABLE; + else + control &= ~BCM2835_PWM1_ENABLE; + } + + // If you use the barrier here, wierd things happen, and the commands dont work + bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM_CONTROL, control); + // bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM_CONTROL, BCM2835_PWM0_ENABLE | BCM2835_PWM1_ENABLE | BCM2835_PWM0_MS_MODE | BCM2835_PWM1_MS_MODE); + +} + +void bcm2835_pwm_set_range(uint8_t channel, uint32_t range) +{ + if (channel == 0) + bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM0_RANGE, range); + else if (channel == 1) + bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM1_RANGE, range); +} + +void bcm2835_pwm_set_data(uint8_t channel, uint32_t data) +{ + if (channel == 0) + bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM0_DATA, data); + else if (channel == 1) + bcm2835_peri_write_nb(bcm2835_pwm + BCM2835_PWM1_DATA, data); +} + +// Allocate page-aligned memory. +void *malloc_aligned(size_t size) +{ + void *mem; + errno = posix_memalign(&mem, BCM2835_PAGE_SIZE, size); + return (errno ? NULL : mem); +} + +// Map 'size' bytes starting at 'off' in file 'fd' to memory. +// Return mapped address on success, MAP_FAILED otherwise. +// On error print message. +static void *mapmem(const char *msg, size_t size, int fd, off_t off) +{ + void *map = mmap(NULL, size, (PROT_READ | PROT_WRITE), MAP_SHARED, fd, off); + if (MAP_FAILED == map) + fprintf(stderr, "bcm2835_init: %s mmap failed: %s\n", msg, strerror(errno)); + return map; +} + +static void unmapmem(void **pmem, size_t size) +{ + if (*pmem == MAP_FAILED) return; + munmap(*pmem, size); + *pmem = MAP_FAILED; +} + +// Initialise this library. +int bcm2835_init(void) +{ + if (debug) + { + bcm2835_pads = (uint32_t*)BCM2835_GPIO_PADS; + bcm2835_clk = (uint32_t*)BCM2835_CLOCK_BASE; + bcm2835_gpio = (uint32_t*)BCM2835_GPIO_BASE; + bcm2835_pwm = (uint32_t*)BCM2835_GPIO_PWM; + bcm2835_spi0 = (uint32_t*)BCM2835_SPI0_BASE; + bcm2835_bsc0 = (uint32_t*)BCM2835_BSC0_BASE; + bcm2835_bsc1 = (uint32_t*)BCM2835_BSC1_BASE; + bcm2835_st = (uint32_t*)BCM2835_ST_BASE; + return 1; // Success + } + int memfd = -1; + int ok = 0; + // Open the master /dev/memory device + if ((memfd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0) + { + fprintf(stderr, "bcm2835_init: Unable to open /dev/mem: %s\n", + strerror(errno)) ; + goto exit; + } + + // GPIO: + bcm2835_gpio = mapmem("gpio", BCM2835_BLOCK_SIZE, memfd, BCM2835_GPIO_BASE); + if (bcm2835_gpio == MAP_FAILED) goto exit; + + // PWM + bcm2835_pwm = mapmem("pwm", BCM2835_BLOCK_SIZE, memfd, BCM2835_GPIO_PWM); + if (bcm2835_pwm == MAP_FAILED) goto exit; + + // Clock control (needed for PWM) + bcm2835_clk = mapmem("clk", BCM2835_BLOCK_SIZE, memfd, BCM2835_CLOCK_BASE); + if (bcm2835_clk == MAP_FAILED) goto exit; + + bcm2835_pads = mapmem("pads", BCM2835_BLOCK_SIZE, memfd, BCM2835_GPIO_PADS); + if (bcm2835_pads == MAP_FAILED) goto exit; + + bcm2835_spi0 = mapmem("spi0", BCM2835_BLOCK_SIZE, memfd, BCM2835_SPI0_BASE); + if (bcm2835_spi0 == MAP_FAILED) goto exit; + + // I2C + bcm2835_bsc0 = mapmem("bsc0", BCM2835_BLOCK_SIZE, memfd, BCM2835_BSC0_BASE); + if (bcm2835_bsc0 == MAP_FAILED) goto exit; + + bcm2835_bsc1 = mapmem("bsc1", BCM2835_BLOCK_SIZE, memfd, BCM2835_BSC1_BASE); + if (bcm2835_bsc1 == MAP_FAILED) goto exit; + + // ST + bcm2835_st = mapmem("st", BCM2835_BLOCK_SIZE, memfd, BCM2835_ST_BASE); + if (bcm2835_st == MAP_FAILED) goto exit; + + ok = 1; + +exit: + if (memfd >= 0) + close(memfd); + + if (!ok) + bcm2835_close(); + + return ok; +} + +// Close this library and deallocate everything +int bcm2835_close(void) +{ + if (debug) return 1; // Success + unmapmem((void**) &bcm2835_gpio, BCM2835_BLOCK_SIZE); + unmapmem((void**) &bcm2835_pwm, BCM2835_BLOCK_SIZE); + unmapmem((void**) &bcm2835_clk, BCM2835_BLOCK_SIZE); + unmapmem((void**) &bcm2835_spi0, BCM2835_BLOCK_SIZE); + unmapmem((void**) &bcm2835_bsc0, BCM2835_BLOCK_SIZE); + unmapmem((void**) &bcm2835_bsc1, BCM2835_BLOCK_SIZE); + unmapmem((void**) &bcm2835_st, BCM2835_BLOCK_SIZE); + unmapmem((void**) &bcm2835_pads, BCM2835_BLOCK_SIZE); + return 1; // Success +} + +#ifdef BCM2835_TEST +// this is a simple test program that prints out what it will do rather than +// actually doing it +int main(int argc, char **argv) +{ + // Be non-destructive + bcm2835_set_debug(1); + + if (!bcm2835_init()) + return 1; + + // Configure some GPIO pins fo some testing + // Set RPI pin P1-11 to be an output + bcm2835_gpio_fsel(RPI_GPIO_P1_11, BCM2835_GPIO_FSEL_OUTP); + // Set RPI pin P1-15 to be an input + bcm2835_gpio_fsel(RPI_GPIO_P1_15, BCM2835_GPIO_FSEL_INPT); + // with a pullup + bcm2835_gpio_set_pud(RPI_GPIO_P1_15, BCM2835_GPIO_PUD_UP); + // And a low detect enable + bcm2835_gpio_len(RPI_GPIO_P1_15); + // and input hysteresis disabled on GPIOs 0 to 27 + bcm2835_gpio_set_pad(BCM2835_PAD_GROUP_GPIO_0_27, BCM2835_PAD_SLEW_RATE_UNLIMITED|BCM2835_PAD_DRIVE_8mA); + +#if 1 + // Blink + while (1) + { + // Turn it on + bcm2835_gpio_write(RPI_GPIO_P1_11, HIGH); + + // wait a bit + bcm2835_delay(500); + + // turn it off + bcm2835_gpio_write(RPI_GPIO_P1_11, LOW); + + // wait a bit + bcm2835_delay(500); + } +#endif + +#if 0 + // Read input + while (1) + { + // Read some data + uint8_t value = bcm2835_gpio_lev(RPI_GPIO_P1_15); + printf("read from pin 15: %d\n", value); + + // wait a bit + bcm2835_delay(500); + } +#endif + +#if 0 + // Look for a low event detection + // eds will be set whenever pin 15 goes low + while (1) + { + if (bcm2835_gpio_eds(RPI_GPIO_P1_15)) + { + // Now clear the eds flag by setting it to 1 + bcm2835_gpio_set_eds(RPI_GPIO_P1_15); + printf("low event detect for pin 15\n"); + } + + // wait a bit + bcm2835_delay(500); + } +#endif + + if (!bcm2835_close()) + return 1; + + return 0; +} +#endif diff --git a/st7565-lcd/ada/bcm2835_h.ads b/st7565-lcd/ada/bcm2835_h.ads new file mode 100644 index 0000000..193dbeb --- /dev/null +++ b/st7565-lcd/ada/bcm2835_h.ads @@ -0,0 +1,1408 @@ +with Interfaces.C; use Interfaces.C; +with stdint_h; +with Interfaces.C.Strings; + + +package bcm2835_h is + + -- bcm2835.h + -- C and C++ support for Broadcom BCM 2835 as used in Raspberry Pi + -- Author: Mike McCauley + -- Copyright (C) 2011-2013 Mike McCauley + -- $Id: bcm2835.h,v 1.12 2013/10/30 03:09:31 mikem Exp mikem $ + --/ \mainpage C library for Broadcom BCM 2835 as used in Raspberry Pi + --/ + --/ This is a C library for Raspberry Pi (RPi). It provides access to + --/ GPIO and other IO functions on the Broadcom BCM 2835 chip, + --/ allowing access to the GPIO pins on the + --/ 26 pin IDE plug on the RPi board so you can control and interface with various external devices. + --/ + --/ It provides functions for reading digital inputs and setting digital outputs, using SPI and I2C, + --/ and for accessing the system timers. + --/ Pin event detection is supported by polling (interrupts are not supported). + --/ + --/ It is C++ compatible, and installs as a header file and non-shared library on + --/ any Linux-based distro (but clearly is no use except on Raspberry Pi or another board with + --/ BCM 2835). + --/ + --/ The version of the package that this documentation refers to can be downloaded + --/ from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.32.tar.gz + --/ You can find the latest version at http://www.airspayce.com/mikem/bcm2835 + --/ + --/ Several example programs are provided. + --/ + --/ Based on data in http://elinux.org/RPi_Low-level_peripherals and + --/ http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf + --/ and http://www.scribd.com/doc/101830961/GPIO-Pads-Control2 + --/ + --/ You can also find online help and discussion at http://groups.google.com/group/bcm2835 + --/ Please use that group for all questions and discussions on this topic. + --/ Do not contact the author directly, unless it is to discuss commercial licensing. + --/ + --/ Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian + --/ and Occidentalisv01 + --/ CAUTION: it has been observed that when detect enables such as bcm2835_gpio_len() + --/ are used and the pin is pulled LOW + --/ it can cause temporary hangs on 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian + --/ and Occidentalisv01. + --/ Reason for this is not yet determined, but we suspect that an interrupt handler is + --/ hitting a hard loop on those OSs. + --/ If you must use bcm2835_gpio_len() and friends, make sure you disable the pins with + --/ bcm2835_gpio_clr_len() and friends after use. + --/ + --/ \par Installation + --/ + --/ This library consists of a single non-shared library and header file, which will be + --/ installed in the usual places by make install + --/ + --/ \code + --/ # download the latest version of the library, say bcm2835-1.xx.tar.gz, then: + --/ tar zxvf bcm2835-1.xx.tar.gz + --/ cd bcm2835-1.xx + --/ ./configure + --/ make + --/ sudo make check + --/ sudo make install + --/ \endcode + --/ + --/ \par Physical Addresses + --/ + --/ The functions bcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_set_bits() + --/ are low level peripheral register access functions. They are designed to use + --/ physical addresses as described in section 1.2.3 ARM physical addresses + --/ of the BCM2835 ARM Peripherals manual. + --/ Physical addresses range from 0x20000000 to 0x20FFFFFF for peripherals. The bus + --/ addresses for peripherals are set up to map onto the peripheral bus address range starting at + --/ 0x7E000000. Thus a peripheral advertised in the manual at bus address 0x7Ennnnnn is available at + --/ physical address 0x20nnnnnn. + --/ + --/ The base address of the various peripheral registers are available with the following + --/ externals: + --/ bcm2835_gpio + --/ bcm2835_pwm + --/ bcm2835_clk + --/ bcm2835_pads + --/ bcm2835_spio0 + --/ bcm2835_st + --/ bcm2835_bsc0 + --/ bcm2835_bsc1 + --/ + --/ \par Pin Numbering + --/ + --/ The GPIO pin numbering as used by RPi is different to and inconsistent with the underlying + --/ BCM 2835 chip pin numbering. http://elinux.org/RPi_BCM2835_GPIOs + --/ + --/ RPi has a 26 pin IDE header that provides access to some of the GPIO pins on the BCM 2835, + --/ as well as power and ground pins. Not all GPIO pins on the BCM 2835 are available on the + --/ IDE header. + --/ + --/ RPi Version 2 also has a P5 connector with 4 GPIO pins, 5V, 3.3V and Gnd. + --/ + --/ The functions in this library are designed to be passed the BCM 2835 GPIO pin number and _not_ + --/ the RPi pin number. There are symbolic definitions for each of the available pins + --/ that you should use for convenience. See \ref RPiGPIOPin. + --/ + --/ \par SPI Pins + --/ + --/ The bcm2835_spi_* functions allow you to control the BCM 2835 SPI0 interface, + --/ allowing you to send and received data by SPI (Serial Peripheral Interface). + --/ For more information about SPI, see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus + --/ + --/ When bcm2835_spi_begin() is called it changes the bahaviour of the SPI interface pins from their + --/ default GPIO behaviour in order to support SPI. While SPI is in use, you will not be able + --/ to control the state of the SPI pins through the usual bcm2835_spi_gpio_write(). + --/ When bcm2835_spi_end() is called, the SPI pins will all revert to inputs, and can then be + --/ configured and controled with the usual bcm2835_gpio_* calls. + --/ + --/ The Raspberry Pi GPIO pins used for SPI are: + --/ + --/ - P1-19 (MOSI) + --/ - P1-21 (MISO) + --/ - P1-23 (CLK) + --/ - P1-24 (CE0) + --/ - P1-26 (CE1) + --/ + --/ \par I2C Pins + --/ + --/ The bcm2835_i2c_* functions allow you to control the BCM 2835 BSC interface, + --/ allowing you to send and received data by I2C ("eye-squared cee"; generically referred to as "two-wire interface") . + --/ For more information about I?C, see http://en.wikipedia.org/wiki/I%C2%B2C + --/ + --/ The Raspberry Pi V2 GPIO pins used for I2C are: + --/ + --/ - P1-03 (SDA) + --/ - P1-05 (SLC) + --/ + --/ \par PWM + --/ + --/ The BCM2835 supports hardware PWM on a limited subset of GPIO pins. This bcm2835 library provides + --/ functions for configuring and controlling PWM output on these pins. + --/ + --/ The BCM2835 contains 2 independent PWM channels (0 and 1), each of which be connnected to a limited subset of + --/ GPIO pins. The following GPIO pins may be connected to the following PWM channels (from section 9.5): + --/ \code + --/ GPIO PIN RPi pin PWM Channel ALT FUN + --/ 12 0 0 + --/ 13 1 0 + --/ 18 1-12 0 5 + --/ 19 1 5 + --/ 40 0 0 + --/ 41 1 0 + --/ 45 1 0 + --/ 52 0 1 + --/ 53 1 1 + --/ \endcode + --/ In order for a GPIO pin to emit output from its PWM channel, it must be set to the Alt Function given above. + --/ Note carefully that current versions of the Raspberry Pi only expose one of these pins (GPIO 18 = RPi Pin 1-12) + --/ on the IO headers, and therefore this is the only IO pin on the RPi that can be used for PWM. + --/ Further it must be set to ALT FUN 5 to get PWM output. + --/ + --/ Both PWM channels are driven by the same PWM clock, whose clock dvider can be varied using + --/ bcm2835_pwm_set_clock(). Each channel can be separately enabled with bcm2835_pwm_set_mode(). + --/ The average output of the PWM channel is determined by the ratio of DATA/RANGE for that channel. + --/ Use bcm2835_pwm_set_range() to set the range and bcm2835_pwm_set_data() to set the data in that ratio + --/ + --/ Each PWM channel can run in either Balanced or Mark-Space mode. In Balanced mode, the hardware + --/ sends a combination of clock pulses that results in an overall DATA pulses per RANGE pulses. + --/ In Mark-Space mode, the hardware sets the output HIGH for DATA clock pulses wide, followed by + --/ LOW for RANGE-DATA clock pulses. + --/ + --/ The PWM clock can be set to control the PWM pulse widths. The PWM clock is derived from + --/ a 19.2MHz clock. You can set any divider, but some common ones are provided by the BCM2835_PWM_CLOCK_DIVIDER_* + --/ values of \ref bcm2835PWMClockDivider. + --/ + --/ For example, say you wanted to drive a DC motor with PWM at about 1kHz, + --/ and control the speed in 1/1024 increments from + --/ 0/1024 (stopped) through to 1024/1024 (full on). In that case you might set the + --/ clock divider to be 16, and the RANGE to 1024. The pulse repetition frequency will be + --/ 1.2MHz/1024 = 1171.875Hz. + --/ + --/ \par Real Time performance constraints + --/ + --/ The bcm2835 is a library for user programs (i.e. they run in 'userland'). + --/ Such programs are not part of the kernel and are usually + --/ subject to paging and swapping by the kernel while it does other things besides running your program. + --/ This means that you should not expect to get real-time performance or + --/ real-time timing constraints from such programs. In particular, there is no guarantee that the + --/ bcm2835_delay() and bcm2835_delayMicroseconds() will return after exactly the time requested. + --/ In fact, depending on other activity on the host, IO etc, you might get significantly longer delay times + --/ than the one you asked for. So please dont expect to get exactly the time delay you request. + --/ + --/ Arjan reports that you can prevent swapping on Linux with the following code fragment: + --/ + --/ \code + --/ struct sched_param sp; + --/ memset(&sp, 0, sizeof(sp)); + --/ sp.sched_priority = sched_get_priority_max(SCHED_FIFO); + --/ sched_setscheduler(0, SCHED_FIFO, &sp); + --/ mlockall(MCL_CURRENT | MCL_FUTURE); + --/ \endcode + --/ + --/ \par Bindings to other languages + --/ + --/ mikem has made Perl bindings available at CPAN: + --/ http://search.cpan.org/~mikem/Device-BCM2835-1.9/lib/Device/BCM2835.pm + --/ Matthew Baker has kindly made Python bindings available at: + --/ https://github.com/mubeta06/py-libbcm2835 + --/ Gary Marks has created a Serial Peripheral Interface (SPI) command-line utility + --/ for Raspberry Pi, based on the bcm2835 library. The + --/ utility, spincl, is licensed under Open Source GNU GPLv3 by iP Solutions (http://ipsolutionscorp.com), as a + --/ free download with source included: http://ipsolutionscorp.com/raspberry-pi-spi-utility/ + --/ + --/ \par Open Source Licensing GPL V2 + --/ + --/ This is the appropriate option if you want to share the source code of your + --/ application with everyone you distribute it to, and you also want to give them + --/ the right to share who uses it. If you wish to use this software under Open + --/ Source Licensing, you must contribute all your source code to the open source + --/ community in accordance with the GPL Version 2 when your application is + --/ distributed. See http://www.gnu.org/copyleft/gpl.html and COPYING + --/ + --/ \par Acknowledgements + --/ + --/ Some of this code has been inspired by Dom and Gert. + --/ The I2C code has been inspired by Alan Barr. + --/ + --/ \par Revision History + --/ + --/ \version 1.0 Initial release + --/ \version 1.1 Minor bug fixes + --/ \version 1.2 Added support for SPI + --/ \version 1.3 Added bcm2835_spi_transfern() + --/ \version 1.4 Fixed a problem that prevented SPI CE1 being used. Reported by David Robinson. + --/ \version 1.5 Added bcm2835_close() to deinit the library. Suggested by C?sar Ortiz + --/ \version 1.6 Document testing on 2012-07-15-wheezy-raspbian and Occidentalisv01 + --/ Functions bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen() + --/ bcm2835_gpio_len(), bcm2835_gpio_aren() and bcm2835_gpio_afen() now + --/ changes only the pin specified. Other pins that were already previously + --/ enabled stay enabled. + --/ Added bcm2835_gpio_clr_ren(), bcm2835_gpio_clr_fen(), bcm2835_gpio_clr_hen() + --/ bcm2835_gpio_clr_len(), bcm2835_gpio_clr_aren(), bcm2835_gpio_clr_afen() + --/ to clear the enable for individual pins, suggested by Andreas Sundstrom. + --/ \version 1.7 Added bcm2835_spi_transfernb to support different buffers for read and write. + --/ \version 1.8 Improvements to read barrier, as suggested by maddin. + --/ \version 1.9 Improvements contributed by mikew: + --/ I noticed that it was mallocing memory for the mmaps on /dev/mem. + --/ It's not necessary to do that, you can just mmap the file directly, + --/ so I've removed the mallocs (and frees). + --/ I've also modified delayMicroseconds() to use nanosleep() for long waits, + --/ and a busy wait on a high resolution timer for the rest. This is because + --/ I've found that calling nanosleep() takes at least 100-200 us. + --/ You need to link using '-lrt' using this version. + --/ I've added some unsigned casts to the debug prints to silence compiler + --/ warnings I was getting, fixed some typos, and changed the value of + --/ BCM2835_PAD_HYSTERESIS_ENABLED to 0x08 as per Gert van Loo's doc at + --/ http://www.scribd.com/doc/101830961/GPIO-Pads-Control2 + --/ Also added a define for the passwrd value that Gert says is needed to + --/ change pad control settings. + --/ \version 1.10 Changed the names of the delay functions to bcm2835_delay() + --/ and bcm2835_delayMicroseconds() to prevent collisions with wiringPi. + --/ Macros to map delay()-> bcm2835_delay() and + --/ Macros to map delayMicroseconds()-> bcm2835_delayMicroseconds(), which + --/ can be disabled by defining BCM2835_NO_DELAY_COMPATIBILITY + --/ \version 1.11 Fixed incorrect link to download file + --/ \version 1.12 New GPIO pin definitions for RPi version 2 (which has a different GPIO mapping) + --/ \version 1.13 New GPIO pin definitions for RPi version 2 plug P5 + --/ Hardware base pointers are now available (after initialisation) externally as bcm2835_gpio + --/ bcm2835_pwm bcm2835_clk bcm2835_pads bcm2835_spi0. + --/ \version 1.14 Now compiles even if CLOCK_MONOTONIC_RAW is not available, uses CLOCK_MONOTONIC instead. + --/ Fixed errors in documentation of SPI divider frequencies based on 250MHz clock. + --/ Reported by Ben Simpson. + --/ \version 1.15 Added bcm2835_close() to end of examples as suggested by Mark Wolfe. + --/ \version 1.16 Added bcm2835_gpio_set_multi, bcm2835_gpio_clr_multi and bcm2835_gpio_write_multi + --/ to allow a mask of pins to be set all at once. Requested by Sebastian Loncar. + --/ \version 1.17 Added bcm2835_gpio_write_mask. Requested by Sebastian Loncar. + --/ \version 1.18 Added bcm2835_i2c_* functions. Changes to bcm2835_delayMicroseconds: + --/ now uses the RPi system timer counter, instead of clock_gettime, for improved accuracy. + --/ No need to link with -lrt now. Contributed by Arjan van Vught. + --/ \version 1.19 Removed inlines added by previous patch since they don't seem to work everywhere. + --/ Reported by olly. + --/ \version 1.20 Patch from Mark Dootson to close /dev/mem after access to the peripherals has been granted. + --/ \version 1.21 delayMicroseconds is now not susceptible to 32 bit timer overruns. + --/ Patch courtesy Jeremy Mortis. + --/ \version 1.22 Fixed incorrect definition of BCM2835_GPFEN0 which broke the ability to set + --/ falling edge events. Reported by Mark Dootson. + --/ \version 1.23 Added bcm2835_i2c_set_baudrate and bcm2835_i2c_read_register_rs. + --/ Improvements to bcm2835_i2c_read and bcm2835_i2c_write functions + --/ to fix ocasional reads not completing. Patched by Mark Dootson. + --/ \version 1.24 Mark Dootson p[atched a problem with his previously submitted code + --/ under high load from other processes. + --/ \version 1.25 Updated author and distribution location details to airspayce.com + --/ \version 1.26 Added missing unmapmem for pads in bcm2835_close to prevent a memory leak. + --/ Reported by Hartmut Henkel. + --/ \version 1.27 bcm2835_gpio_set_pad() no longer needs BCM2835_PAD_PASSWRD: it is + --/ now automatically included. + --/ Added suport for PWM mode with bcm2835_pwm_* functions. + --/ \version 1.28 Fixed a problem where bcm2835_spi_writenb() would have problems with transfers of more than + --/ 64 bytes dues to read buffer filling. Patched by Peter Würtz. + --/ \version 1.29 Further fix to SPI from Peter Würtz. + --/ \version 1.30 10 microsecond delays from bcm2835_spi_transfer and bcm2835_spi_transfern for + --/ significant performance improvements, Patch by Alan Watson. + --/ \version 1.31 Fix a GCC warning about dummy variable, patched by Alan Watson. Thanks. + --/ \version 1.32 Added option I2C_V1 definition to compile for version 1 RPi. + --/ By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected. + --/ Contributed by Malcolm Wiles. + --/ + --/ \author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS + -- Defines for BCM2835 + --/ \defgroup constants Constants for passing to and from library functions + --/ The values here are designed to be passed to various functions in the bcm2835 library. + --/ @{ + --/ This means pin HIGH, true, 3.3volts on a pin. + --/ This means pin LOW, false, 0volts on a pin. + --/ Speed of the core clock core_clk + -- Physical addresses for various peripheral register sets + --/ Base Physical Address of the BCM 2835 peripheral registers + --/ Base Physical Address of the System Timer registers + --/ Base Physical Address of the Pads registers + --/ Base Physical Address of the Clock/timer registers + --/ Base Physical Address of the GPIO registers + --/ Base Physical Address of the SPI0 registers + --/ Base Physical Address of the BSC0 registers + --/ Base Physical Address of the PWM registers + --/ Base Physical Address of the BSC1 registers + + -- manual converted + HIGH : constant unsigned := 16#1#; + LOW : constant unsigned := 16#0#; + BCM2835_CORE_CLK_HZ : constant unsigned := 250000000; + BCM2835_PERI_BASE : constant unsigned := 16#20000000#; + BCM2835_ST_BASE : constant unsigned := (BCM2835_PERI_BASE + 16#3000#); + BCM2835_GPIO_PADS : constant unsigned := (BCM2835_PERI_BASE + 16#100000#); + BCM2835_CLOCK_BASE : constant unsigned := (BCM2835_PERI_BASE + 16#101000#); + BCM2835_GPIO_BASE : constant unsigned := (BCM2835_PERI_BASE + 16#200000#); + BCM2835_SPI0_BASE : constant unsigned := (BCM2835_PERI_BASE + 16#204000#); + BCM2835_BSC0_BASE : constant unsigned := (BCM2835_PERI_BASE + 16#205000#); + BCM2835_GPIO_PWM : constant unsigned := (BCM2835_PERI_BASE + 16#20C000#); + BCM2835_BSC1_BASE : constant unsigned := (BCM2835_PERI_BASE + 16#804000#); + BCM2835_PAGE_SIZE : constant unsigned := (4*1024); + BCM2835_BLOCK_SIZE : constant unsigned := (4*1024); + BCM2835_GPFSEL0 : constant unsigned := 16#0000#; + BCM2835_GPFSEL1 : constant unsigned := 16#0004#; + BCM2835_GPFSEL2 : constant unsigned := 16#0008#; + BCM2835_GPFSEL3 : constant unsigned := 16#000c#; + BCM2835_GPFSEL4 : constant unsigned := 16#0010#; + BCM2835_GPFSEL5 : constant unsigned := 16#0014#; + BCM2835_GPSET0 : constant unsigned := 16#001c#; + BCM2835_GPSET1 : constant unsigned := 16#0020#; + BCM2835_GPCLR0 : constant unsigned := 16#0028#; + BCM2835_GPCLR1 : constant unsigned := 16#002c#; + BCM2835_GPLEV0 : constant unsigned := 16#0034#; + BCM2835_GPLEV1 : constant unsigned := 16#0038#; + BCM2835_GPEDS0 : constant unsigned := 16#0040#; + BCM2835_GPEDS1 : constant unsigned := 16#0044#; + BCM2835_GPREN0 : constant unsigned := 16#004c#; + BCM2835_GPREN1 : constant unsigned := 16#0050#; + BCM2835_GPFEN0 : constant unsigned := 16#0058#; + BCM2835_GPFEN1 : constant unsigned := 16#005c#; + BCM2835_GPHEN0 : constant unsigned := 16#0064#; + BCM2835_GPHEN1 : constant unsigned := 16#0068#; + BCM2835_GPLEN0 : constant unsigned := 16#0070#; + BCM2835_GPLEN1 : constant unsigned := 16#0074#; + BCM2835_GPAREN0 : constant unsigned := 16#007c#; + BCM2835_GPAREN1 : constant unsigned := 16#0080#; + BCM2835_GPAFEN0 : constant unsigned := 16#0088#; + BCM2835_GPAFEN1 : constant unsigned := 16#008c#; + BCM2835_GPPUD : constant unsigned := 16#0094#; + BCM2835_GPPUDCLK0 : constant unsigned := 16#0098#; + BCM2835_GPPUDCLK1 : constant unsigned := 16#009c#; + BCM2835_PADS_GPIO_0_27 : constant unsigned := 16#002c#; + BCM2835_PADS_GPIO_28_45 : constant unsigned := 16#0030#; + BCM2835_PADS_GPIO_46_53 : constant unsigned := 16#0034#; + BCM2835_PAD_PASSWRD : constant unsigned := 16#5A000000#; + BCM2835_PAD_SLEW_RATE_UNLIMITED : constant unsigned := 16#10#; + BCM2835_PAD_HYSTERESIS_ENABLED : constant unsigned := 16#08#; + BCM2835_PAD_DRIVE_2mA : constant unsigned := 16#00#; + BCM2835_PAD_DRIVE_4mA : constant unsigned := 16#01#; + BCM2835_PAD_DRIVE_6mA : constant unsigned := 16#02#; + BCM2835_PAD_DRIVE_8mA : constant unsigned := 16#03#; + BCM2835_PAD_DRIVE_10mA : constant unsigned := 16#04#; + BCM2835_PAD_DRIVE_12mA : constant unsigned := 16#05#; + BCM2835_PAD_DRIVE_14mA : constant unsigned := 16#06#; + BCM2835_PAD_DRIVE_16mA : constant unsigned := 16#07#; + BCM2835_SPI0_CS : constant unsigned := 16#0000#; + BCM2835_SPI0_FIFO : constant unsigned := 16#0004#; + BCM2835_SPI0_CLK : constant unsigned := 16#0008#; + BCM2835_SPI0_DLEN : constant unsigned := 16#000c#; + BCM2835_SPI0_LTOH : constant unsigned := 16#0010#; + BCM2835_SPI0_DC : constant unsigned := 16#0014#; + BCM2835_SPI0_CS_LEN_LONG : constant unsigned := 16#02000000#; + BCM2835_SPI0_CS_DMA_LEN : constant unsigned := 16#01000000#; + BCM2835_SPI0_CS_CSPOL2 : constant unsigned := 16#00800000#; + BCM2835_SPI0_CS_CSPOL1 : constant unsigned := 16#00400000#; + BCM2835_SPI0_CS_CSPOL0 : constant unsigned := 16#00200000#; + BCM2835_SPI0_CS_RXF : constant unsigned := 16#00100000#; + BCM2835_SPI0_CS_RXR : constant unsigned := 16#00080000#; + BCM2835_SPI0_CS_TXD : constant unsigned := 16#00040000#; + BCM2835_SPI0_CS_RXD : constant unsigned := 16#00020000#; + BCM2835_SPI0_CS_DONE : constant unsigned := 16#00010000#; + BCM2835_SPI0_CS_TE_EN : constant unsigned := 16#00008000#; + BCM2835_SPI0_CS_LMONO : constant unsigned := 16#00004000#; + BCM2835_SPI0_CS_LEN : constant unsigned := 16#00002000#; + BCM2835_SPI0_CS_REN : constant unsigned := 16#00001000#; + BCM2835_SPI0_CS_ADCS : constant unsigned := 16#00000800#; + BCM2835_SPI0_CS_INTR : constant unsigned := 16#00000400#; + BCM2835_SPI0_CS_INTD : constant unsigned := 16#00000200#; + BCM2835_SPI0_CS_DMAEN : constant unsigned := 16#00000100#; + BCM2835_SPI0_CS_TA : constant unsigned := 16#00000080#; + BCM2835_SPI0_CS_CSPOL : constant unsigned := 16#00000040#; + BCM2835_SPI0_CS_CLEAR : constant unsigned := 16#00000030#; + BCM2835_SPI0_CS_CLEAR_RX : constant unsigned := 16#00000020#; + BCM2835_SPI0_CS_CLEAR_TX : constant unsigned := 16#00000010#; + BCM2835_SPI0_CS_CPOL : constant unsigned := 16#00000008#; + BCM2835_SPI0_CS_CPHA : constant unsigned := 16#00000004#; + BCM2835_SPI0_CS_CS : constant unsigned := 16#00000003#; + BCM2835_BSC_C : constant unsigned := 16#0000#; + BCM2835_BSC_S : constant unsigned := 16#0004#; + BCM2835_BSC_DLEN : constant unsigned := 16#0008#; + BCM2835_BSC_A : constant unsigned := 16#000c#; + BCM2835_BSC_FIFO : constant unsigned := 16#0010#; + BCM2835_BSC_DIV : constant unsigned := 16#0014#; + BCM2835_BSC_DEL : constant unsigned := 16#0018#; + BCM2835_BSC_CLKT : constant unsigned := 16#001c#; + BCM2835_BSC_C_I2CEN : constant unsigned := 16#00008000#; + BCM2835_BSC_C_INTR : constant unsigned := 16#00000400#; + BCM2835_BSC_C_INTT : constant unsigned := 16#00000200#; + BCM2835_BSC_C_INTD : constant unsigned := 16#00000100#; + BCM2835_BSC_C_ST : constant unsigned := 16#00000080#; + BCM2835_BSC_C_CLEAR_1 : constant unsigned := 16#00000020#; + BCM2835_BSC_C_CLEAR_2 : constant unsigned := 16#00000010#; + BCM2835_BSC_C_READ : constant unsigned := 16#00000001#; + BCM2835_BSC_S_CLKT : constant unsigned := 16#00000200#; + BCM2835_BSC_S_ERR : constant unsigned := 16#00000100#; + BCM2835_BSC_S_RXF : constant unsigned := 16#00000080#; + BCM2835_BSC_S_TXE : constant unsigned := 16#00000040#; + BCM2835_BSC_S_RXD : constant unsigned := 16#00000020#; + BCM2835_BSC_S_TXD : constant unsigned := 16#00000010#; + BCM2835_BSC_S_RXR : constant unsigned := 16#00000008#; + BCM2835_BSC_S_TXW : constant unsigned := 16#00000004#; + BCM2835_BSC_S_DONE : constant unsigned := 16#00000002#; + BCM2835_BSC_S_TA : constant unsigned := 16#00000001#; + BCM2835_BSC_FIFO_SIZE : constant unsigned := 16; + BCM2835_ST_CS : constant unsigned := 16#0000#; + BCM2835_ST_CLO : constant unsigned := 16#0004#; + BCM2835_ST_CHI : constant unsigned := 16#0008#; + BCM2835_PWM_CONTROL : constant unsigned := 0; + BCM2835_PWM_STATUS : constant unsigned := 1; + BCM2835_PWM_DMAC : constant unsigned := 2; + BCM2835_PWM0_RANGE : constant unsigned := 4; + BCM2835_PWM0_DATA : constant unsigned := 5; + BCM2835_PWM_FIF1 : constant unsigned := 6; + BCM2835_PWM1_RANGE : constant unsigned := 8; + BCM2835_PWM1_DATA : constant unsigned := 9; + BCM2835_PWMCLK_CNTL : constant unsigned := 40; + BCM2835_PWMCLK_DIV : constant unsigned := 41; + BCM2835_PWM_PASSWRD : constant unsigned := 16#5A000000#; + BCM2835_PWM1_MS_MODE : constant unsigned := 16#8000#; + BCM2835_PWM1_USEFIFO : constant unsigned := 16#2000#; + BCM2835_PWM1_REVPOLAR : constant unsigned := 16#1000#; + BCM2835_PWM1_OFFSTATE : constant unsigned := 16#0800#; + BCM2835_PWM1_REPEATFF : constant unsigned := 16#0400#; + BCM2835_PWM1_SERIAL : constant unsigned := 16#0200#; + BCM2835_PWM1_ENABLE : constant unsigned := 16#0100#; + BCM2835_PWM0_MS_MODE : constant unsigned := 16#0080#; + BCM2835_PWM_CLEAR_FIFO : constant unsigned := 16#0040#; + BCM2835_PWM0_USEFIFO : constant unsigned := 16#0020#; + BCM2835_PWM0_REVPOLAR : constant unsigned := 16#0010#; + BCM2835_PWM0_OFFSTATE : constant unsigned := 16#0008#; + BCM2835_PWM0_REPEATFF : constant unsigned := 16#0004#; + BCM2835_PWM0_SERIAL : constant unsigned := 16#0002#; + BCM2835_PWM0_ENABLE : constant unsigned := 16#0001#; + -- arg-macro: procedure delay (x) + -- bcm2835_delay(x) + -- arg-macro: procedure delayMicroseconds (x) + -- bcm2835_delayMicroseconds(x) + + + --/ Base of the ST (System Timer) registers. + --/ Available after bcm2835_init has been called + bcm2835_st : access stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:348 + pragma Import (C, bcm2835_st, "bcm2835_st"); + + --/ Base of the GPIO registers. + --/ Available after bcm2835_init has been called + bcm2835_gpio : access stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:352 + pragma Import (C, bcm2835_gpio, "bcm2835_gpio"); + + --/ Base of the PWM registers. + --/ Available after bcm2835_init has been called + bcm2835_pwm : access stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:356 + pragma Import (C, bcm2835_pwm, "bcm2835_pwm"); + + --/ Base of the CLK registers. + --/ Available after bcm2835_init has been called + bcm2835_clk : access stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:360 + pragma Import (C, bcm2835_clk, "bcm2835_clk"); + + --/ Base of the PADS registers. + --/ Available after bcm2835_init has been called + bcm2835_pads : access stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:364 + pragma Import (C, bcm2835_pads, "bcm2835_pads"); + + --/ Base of the SPI0 registers. + --/ Available after bcm2835_init has been called + bcm2835_spi0 : access stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:368 + pragma Import (C, bcm2835_spi0, "bcm2835_spi0"); + + --/ Base of the BSC0 registers. + --/ Available after bcm2835_init has been called + bcm2835_bsc0 : access stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:372 + pragma Import (C, bcm2835_bsc0, "bcm2835_bsc0"); + + --/ Base of the BSC1 registers. + --/ Available after bcm2835_init has been called + bcm2835_bsc1 : access stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:376 + pragma Import (C, bcm2835_bsc1, "bcm2835_bsc1"); + + --/ Size of memory page on RPi + --/ Size of memory block on RPi + -- Defines for GPIO + -- The BCM2835 has 54 GPIO pins. + -- BCM2835 data sheet, Page 90 onwards. + --/ GPIO register offsets from BCM2835_GPIO_BASE. Offsets into the GPIO Peripheral block in bytes per 6.1 Register View + --/ \brief bcm2835PortFunction + --/ Port function select modes for bcm2835_gpio_fsel() + --/< Input + --/< Output + --/< Alternate function 0 + --/< Alternate function 1 + --/< Alternate function 2 + --/< Alternate function 3 + --/< Alternate function 4 + --/< Alternate function 5 + --/< Function select bits mask + subtype bcm2835FunctionSelect is unsigned; + BCM2835_GPIO_FSEL_INPT : constant bcm2835FunctionSelect := 0; + BCM2835_GPIO_FSEL_OUTP : constant bcm2835FunctionSelect := 1; + BCM2835_GPIO_FSEL_ALT0 : constant bcm2835FunctionSelect := 4; + BCM2835_GPIO_FSEL_ALT1 : constant bcm2835FunctionSelect := 5; + BCM2835_GPIO_FSEL_ALT2 : constant bcm2835FunctionSelect := 6; + BCM2835_GPIO_FSEL_ALT3 : constant bcm2835FunctionSelect := 7; + BCM2835_GPIO_FSEL_ALT4 : constant bcm2835FunctionSelect := 3; + BCM2835_GPIO_FSEL_ALT5 : constant bcm2835FunctionSelect := 2; + BCM2835_GPIO_FSEL_MASK : constant bcm2835FunctionSelect := 7; -- /usr/local/include/bcm2835.h:431 + + --/ \brief bcm2835PUDControl + --/ Pullup/Pulldown defines for bcm2835_gpio_pud() + --/< Off ? disable pull-up/down + --/< Enable Pull Down control + --/< Enable Pull Up control + type bcm2835PUDControl is + (BCM2835_GPIO_PUD_OFF, + BCM2835_GPIO_PUD_DOWN, + BCM2835_GPIO_PUD_UP); + pragma Convention (C, bcm2835PUDControl); -- /usr/local/include/bcm2835.h:440 + + + --BCM2835_GPIO_PUD_OFF : constant unsigned := 2#00#; + --BCM2835_GPIO_PUD_DOWN : constant unsigned := 2#01#; + --BCM2835_GPIO_PUD_UP : constant unsigned := 2#10#; + + + --/ Pad control register offsets from BCM2835_GPIO_PADS + --/ Pad Control masks + --/ \brief bcm2835PadGroup + --/ Pad group specification for bcm2835_gpio_pad() + --/< Pad group for GPIO pads 0 to 27 + --/< Pad group for GPIO pads 28 to 45 + --/< Pad group for GPIO pads 46 to 53 + type bcm2835PadGroup is + (BCM2835_PAD_GROUP_GPIO_0_27, + BCM2835_PAD_GROUP_GPIO_28_45, + BCM2835_PAD_GROUP_GPIO_46_53); + pragma Convention (C, bcm2835PadGroup); -- /usr/local/include/bcm2835.h:467 + + --BCM2835_PAD_GROUP_GPIO_0_27 : constant unsigned := 0; + --BCM2835_PAD_GROUP_GPIO_28_45 : constant unsigned := 1; + --BCM2835_PAD_GROUP_GPIO_46_53 : constant unsigned := 2; + + + --/ \brief GPIO Pin Numbers + --/ + --/ Here we define Raspberry Pin GPIO pins on P1 in terms of the underlying BCM GPIO pin numbers. + --/ These can be passed as a pin number to any function requiring a pin. + --/ Not all pins on the RPi 26 bin IDE plug are connected to GPIO pins + --/ and some can adopt an alternate function. + --/ RPi version 2 has some slightly different pinouts, and these are values RPI_V2_*. + --/ At bootup, pins 8 and 10 are set to UART0_TXD, UART0_RXD (ie the alt0 function) respectively + --/ When SPI0 is in use (ie after bcm2835_spi_begin()), pins 19, 21, 23, 24, 26 are dedicated to SPI + --/ and cant be controlled independently + --/< Version 1, Pin P1-03 + --/< Version 1, Pin P1-05 + --/< Version 1, Pin P1-07 + --/< Version 1, Pin P1-08, defaults to alt function 0 UART0_TXD + --/< Version 1, Pin P1-10, defaults to alt function 0 UART0_RXD + --/< Version 1, Pin P1-11 + --/< Version 1, Pin P1-12, can be PWM channel 0 in ALT FUN 5 + --/< Version 1, Pin P1-13 + --/< Version 1, Pin P1-15 + --/< Version 1, Pin P1-16 + --/< Version 1, Pin P1-18 + --/< Version 1, Pin P1-19, MOSI when SPI0 in use + --/< Version 1, Pin P1-21, MISO when SPI0 in use + --/< Version 1, Pin P1-22 + --/< Version 1, Pin P1-23, CLK when SPI0 in use + --/< Version 1, Pin P1-24, CE0 when SPI0 in use + --/< Version 1, Pin P1-26, CE1 when SPI0 in use + -- RPi Version 2 + --/< Version 2, Pin P1-03 + --/< Version 2, Pin P1-05 + --/< Version 2, Pin P1-07 + --/< Version 2, Pin P1-08, defaults to alt function 0 UART0_TXD + --/< Version 2, Pin P1-10, defaults to alt function 0 UART0_RXD + --/< Version 2, Pin P1-11 + --/< Version 2, Pin P1-12, can be PWM channel 0 in ALT FUN 5 + --/< Version 2, Pin P1-13 + --/< Version 2, Pin P1-15 + --/< Version 2, Pin P1-16 + --/< Version 2, Pin P1-18 + --/< Version 2, Pin P1-19, MOSI when SPI0 in use + --/< Version 2, Pin P1-21, MISO when SPI0 in use + --/< Version 2, Pin P1-22 + --/< Version 2, Pin P1-23, CLK when SPI0 in use + --/< Version 2, Pin P1-24, CE0 when SPI0 in use + --/< Version 2, Pin P1-26, CE1 when SPI0 in use + -- RPi Version 2, new plug P5 + --/< Version 2, Pin P5-03 + --/< Version 2, Pin P5-04 + --/< Version 2, Pin P5-05 + --/< Version 2, Pin P5-06 + subtype RPiGPIOPin is unsigned; + RPI_GPIO_P1_03 : constant RPiGPIOPin := 0; + RPI_GPIO_P1_05 : constant RPiGPIOPin := 1; + RPI_GPIO_P1_07 : constant RPiGPIOPin := 4; + RPI_GPIO_P1_08 : constant RPiGPIOPin := 14; + RPI_GPIO_P1_10 : constant RPiGPIOPin := 15; + RPI_GPIO_P1_11 : constant RPiGPIOPin := 17; + RPI_GPIO_P1_12 : constant RPiGPIOPin := 18; + RPI_GPIO_P1_13 : constant RPiGPIOPin := 21; + RPI_GPIO_P1_15 : constant RPiGPIOPin := 22; + RPI_GPIO_P1_16 : constant RPiGPIOPin := 23; + RPI_GPIO_P1_18 : constant RPiGPIOPin := 24; + RPI_GPIO_P1_19 : constant RPiGPIOPin := 10; + RPI_GPIO_P1_21 : constant RPiGPIOPin := 9; + RPI_GPIO_P1_22 : constant RPiGPIOPin := 25; + RPI_GPIO_P1_23 : constant RPiGPIOPin := 11; + RPI_GPIO_P1_24 : constant RPiGPIOPin := 8; + RPI_GPIO_P1_26 : constant RPiGPIOPin := 7; + RPI_V2_GPIO_P1_03 : constant RPiGPIOPin := 2; + RPI_V2_GPIO_P1_05 : constant RPiGPIOPin := 3; + RPI_V2_GPIO_P1_07 : constant RPiGPIOPin := 4; + RPI_V2_GPIO_P1_08 : constant RPiGPIOPin := 14; + RPI_V2_GPIO_P1_10 : constant RPiGPIOPin := 15; + RPI_V2_GPIO_P1_11 : constant RPiGPIOPin := 17; + RPI_V2_GPIO_P1_12 : constant RPiGPIOPin := 18; + RPI_V2_GPIO_P1_13 : constant RPiGPIOPin := 27; + RPI_V2_GPIO_P1_15 : constant RPiGPIOPin := 22; + RPI_V2_GPIO_P1_16 : constant RPiGPIOPin := 23; + RPI_V2_GPIO_P1_18 : constant RPiGPIOPin := 24; + RPI_V2_GPIO_P1_19 : constant RPiGPIOPin := 10; + RPI_V2_GPIO_P1_21 : constant RPiGPIOPin := 9; + RPI_V2_GPIO_P1_22 : constant RPiGPIOPin := 25; + RPI_V2_GPIO_P1_23 : constant RPiGPIOPin := 11; + RPI_V2_GPIO_P1_24 : constant RPiGPIOPin := 8; + RPI_V2_GPIO_P1_26 : constant RPiGPIOPin := 7; + RPI_V2_GPIO_P5_03 : constant RPiGPIOPin := 28; + RPI_V2_GPIO_P5_04 : constant RPiGPIOPin := 29; + RPI_V2_GPIO_P5_05 : constant RPiGPIOPin := 30; + RPI_V2_GPIO_P5_06 : constant RPiGPIOPin := 31; -- /usr/local/include/bcm2835.h:524 + + -- Defines for SPI + -- GPIO register offsets from BCM2835_SPI0_BASE. + -- Offsets into the SPI Peripheral block in bytes per 10.5 SPI Register Map + -- Register masks for SPI0_CS + --/ \brief bcm2835SPIBitOrder SPI Bit order + --/ Specifies the SPI data bit ordering for bcm2835_spi_setBitOrder() + --/< LSB First + --/< MSB First + type bcm2835SPIBitOrder is + (BCM2835_SPI_BIT_ORDER_LSBFIRST, + BCM2835_SPI_BIT_ORDER_MSBFIRST); + pragma Convention (C, bcm2835SPIBitOrder); -- /usr/local/include/bcm2835.h:570 + + --BCM2835_SPI_BIT_ORDER_LSBFIRST : constant unsigned := 0; + --BCM2835_SPI_BIT_ORDER_MSBFIRST : constant unsigned := 1; + + + --/ \brief SPI Data mode + --/ Specify the SPI data mode to be passed to bcm2835_spi_setDataMode() + --/< CPOL = 0, CPHA = 0 + --/< CPOL = 0, CPHA = 1 + --/< CPOL = 1, CPHA = 0 + --/< CPOL = 1, CPHA = 1 + type bcm2835SPIMode is + (BCM2835_SPI_MODE0, + BCM2835_SPI_MODE1, + BCM2835_SPI_MODE2, + BCM2835_SPI_MODE3); + pragma Convention (C, bcm2835SPIMode); -- /usr/local/include/bcm2835.h:580 + + --BCM2835_SPI_MODE0 : constant unsigned := 0; + --BCM2835_SPI_MODE1 : constant unsigned := 1; + --BCM2835_SPI_MODE2 : constant unsigned := 2; + --BCM2835_SPI_MODE3 : constant unsigned := 3; + + + --/ \brief bcm2835SPIChipSelect + --/ Specify the SPI chip select pin(s) + --/< Chip Select 0 + --/< Chip Select 1 + --/< Chip Select 2 (ie pins CS1 and CS2 are asserted) + --/< No CS, control it yourself + type bcm2835SPIChipSelect is + (BCM2835_SPI_CS0, + BCM2835_SPI_CS1, + BCM2835_SPI_CS2, + BCM2835_SPI_CS_NONE); + pragma Convention (C, bcm2835SPIChipSelect); -- /usr/local/include/bcm2835.h:590 + + --BCM2835_SPI_CS0 : constant unsigned := 0; + --BCM2835_SPI_CS1 : constant unsigned := 1; + --BCM2835_SPI_CS2 : constant unsigned := 2; + --BCM2835_SPI_CS_NONE : constant unsigned := 3; + + --/ \brief bcm2835SPIClockDivider + --/ Specifies the divider used to generate the SPI clock from the system clock. + --/ Figures below give the divider, clock period and clock frequency. + --/ Clock divided is based on nominal base clock rate of 250MHz + --/ It is reported that (contrary to the documentation) any even divider may used. + --/ The frequencies shown for each divider have been confirmed by measurement + --/< 65536 = 262.144us = 3.814697260kHz + --/< 32768 = 131.072us = 7.629394531kHz + --/< 16384 = 65.536us = 15.25878906kHz + --/< 8192 = 32.768us = 30/51757813kHz + --/< 4096 = 16.384us = 61.03515625kHz + --/< 2048 = 8.192us = 122.0703125kHz + --/< 1024 = 4.096us = 244.140625kHz + --/< 512 = 2.048us = 488.28125kHz + --/< 256 = 1.024us = 976.5625MHz + --/< 128 = 512ns = = 1.953125MHz + --/< 64 = 256ns = 3.90625MHz + --/< 32 = 128ns = 7.8125MHz + --/< 16 = 64ns = 15.625MHz + --/< 8 = 32ns = 31.25MHz + --/< 4 = 16ns = 62.5MHz + --/< 2 = 8ns = 125MHz, fastest you can get + --/< 1 = 262.144us = 3.814697260kHz, same as 0/65536 + subtype bcm2835SPIClockDivider is unsigned; + BCM2835_SPI_CLOCK_DIVIDER_65536 : constant bcm2835SPIClockDivider := 0; + BCM2835_SPI_CLOCK_DIVIDER_32768 : constant bcm2835SPIClockDivider := 32768; + BCM2835_SPI_CLOCK_DIVIDER_16384 : constant bcm2835SPIClockDivider := 16384; + BCM2835_SPI_CLOCK_DIVIDER_8192 : constant bcm2835SPIClockDivider := 8192; + BCM2835_SPI_CLOCK_DIVIDER_4096 : constant bcm2835SPIClockDivider := 4096; + BCM2835_SPI_CLOCK_DIVIDER_2048 : constant bcm2835SPIClockDivider := 2048; + BCM2835_SPI_CLOCK_DIVIDER_1024 : constant bcm2835SPIClockDivider := 1024; + BCM2835_SPI_CLOCK_DIVIDER_512 : constant bcm2835SPIClockDivider := 512; + BCM2835_SPI_CLOCK_DIVIDER_256 : constant bcm2835SPIClockDivider := 256; + BCM2835_SPI_CLOCK_DIVIDER_128 : constant bcm2835SPIClockDivider := 128; + BCM2835_SPI_CLOCK_DIVIDER_64 : constant bcm2835SPIClockDivider := 64; + BCM2835_SPI_CLOCK_DIVIDER_32 : constant bcm2835SPIClockDivider := 32; + BCM2835_SPI_CLOCK_DIVIDER_16 : constant bcm2835SPIClockDivider := 16; + BCM2835_SPI_CLOCK_DIVIDER_8 : constant bcm2835SPIClockDivider := 8; + BCM2835_SPI_CLOCK_DIVIDER_4 : constant bcm2835SPIClockDivider := 4; + BCM2835_SPI_CLOCK_DIVIDER_2 : constant bcm2835SPIClockDivider := 2; + BCM2835_SPI_CLOCK_DIVIDER_1 : constant bcm2835SPIClockDivider := 1; -- /usr/local/include/bcm2835.h:617 + + -- Defines for I2C + -- GPIO register offsets from BCM2835_BSC*_BASE. + -- Offsets into the BSC Peripheral block in bytes per 3.1 BSC Register Map + -- Register masks for BSC_C + -- Register masks for BSC_S + --/ \brief bcm2835I2CClockDivider + --/ Specifies the divider used to generate the I2C clock from the system clock. + --/ Clock divided is based on nominal base clock rate of 250MHz + --/< 2500 = 10us = 100 kHz + --/< 622 = 2.504us = 399.3610 kHz + --/< 150 = 60ns = 1.666 MHz (default at reset) + --/< 148 = 59ns = 1.689 MHz + subtype bcm2835I2CClockDivider is unsigned; + BCM2835_I2C_CLOCK_DIVIDER_2500 : constant bcm2835I2CClockDivider := 2500; + BCM2835_I2C_CLOCK_DIVIDER_626 : constant bcm2835I2CClockDivider := 626; + BCM2835_I2C_CLOCK_DIVIDER_150 : constant bcm2835I2CClockDivider := 150; + BCM2835_I2C_CLOCK_DIVIDER_148 : constant bcm2835I2CClockDivider := 148; -- /usr/local/include/bcm2835.h:664 + + --/ \brief bcm2835I2CReasonCodes + --/ Specifies the reason codes for the bcm2835_i2c_write and bcm2835_i2c_read functions. + --/< Success + --/< Received a NACK + --/< Received Clock Stretch Timeout + --/< Not all data is sent / received + subtype bcm2835I2CReasonCodes is unsigned; + BCM2835_I2C_REASON_OK : constant bcm2835I2CReasonCodes := 0; + BCM2835_I2C_REASON_ERROR_NACK : constant bcm2835I2CReasonCodes := 1; + BCM2835_I2C_REASON_ERROR_CLKT : constant bcm2835I2CReasonCodes := 2; + BCM2835_I2C_REASON_ERROR_DATA : constant bcm2835I2CReasonCodes := 4; -- /usr/local/include/bcm2835.h:674 + + -- Defines for ST + -- GPIO register offsets from BCM2835_ST_BASE. + -- Offsets into the ST Peripheral block in bytes per 12.1 System Timer Registers + -- The System Timer peripheral provides four 32-bit timer channels and a single 64-bit free running counter. + -- BCM2835_ST_CLO is the System Timer Counter Lower bits register. + -- The system timer free-running counter lower register is a read-only register that returns the current value + -- of the lower 32-bits of the free running counter. + -- BCM2835_ST_CHI is the System Timer Counter Upper bits register. + -- The system timer free-running counter upper register is a read-only register that returns the current value + -- of the upper 32-bits of the free running counter. + --/ @} + -- Defines for PWM, word offsets (ie 4 byte multiples) + -- Defines for PWM Clock, word offsets (ie 4 byte multiples) + --/ \brief bcm2835PWMClockDivider + --/ Specifies the divider used to generate the PWM clock from the system clock. + --/ Figures below give the divider, clock period and clock frequency. + --/ Clock divided is based on nominal PWM base clock rate of 19.2MHz + --/ The frequencies shown for each divider have been confirmed by measurement + --/< 32768 = 585Hz + --/< 16384 = 1171.8Hz + --/< 8192 = 2.34375kHz + --/< 4096 = 4.6875kHz + --/< 2048 = 9.375kHz + --/< 1024 = 18.75kHz + --/< 512 = 37.5kHz + --/< 256 = 75kHz + --/< 128 = 150kHz + --/< 64 = 300kHz + --/< 32 = 600.0kHz + --/< 16 = 1.2MHz + --/< 8 = 2.4MHz + --/< 4 = 4.8MHz + --/< 2 = 9.6MHz, fastest you can get + --/< 1 = 4.6875kHz, same as divider 4096 + subtype bcm2835PWMClockDivider is unsigned; + BCM2835_PWM_CLOCK_DIVIDER_32768 : constant bcm2835PWMClockDivider := 32768; + BCM2835_PWM_CLOCK_DIVIDER_16384 : constant bcm2835PWMClockDivider := 16384; + BCM2835_PWM_CLOCK_DIVIDER_8192 : constant bcm2835PWMClockDivider := 8192; + BCM2835_PWM_CLOCK_DIVIDER_4096 : constant bcm2835PWMClockDivider := 4096; + BCM2835_PWM_CLOCK_DIVIDER_2048 : constant bcm2835PWMClockDivider := 2048; + BCM2835_PWM_CLOCK_DIVIDER_1024 : constant bcm2835PWMClockDivider := 1024; + BCM2835_PWM_CLOCK_DIVIDER_512 : constant bcm2835PWMClockDivider := 512; + BCM2835_PWM_CLOCK_DIVIDER_256 : constant bcm2835PWMClockDivider := 256; + BCM2835_PWM_CLOCK_DIVIDER_128 : constant bcm2835PWMClockDivider := 128; + BCM2835_PWM_CLOCK_DIVIDER_64 : constant bcm2835PWMClockDivider := 64; + BCM2835_PWM_CLOCK_DIVIDER_32 : constant bcm2835PWMClockDivider := 32; + BCM2835_PWM_CLOCK_DIVIDER_16 : constant bcm2835PWMClockDivider := 16; + BCM2835_PWM_CLOCK_DIVIDER_8 : constant bcm2835PWMClockDivider := 8; + BCM2835_PWM_CLOCK_DIVIDER_4 : constant bcm2835PWMClockDivider := 4; + BCM2835_PWM_CLOCK_DIVIDER_2 : constant bcm2835PWMClockDivider := 2; + BCM2835_PWM_CLOCK_DIVIDER_1 : constant bcm2835PWMClockDivider := 1; -- /usr/local/include/bcm2835.h:748 + + -- Historical name compatibility + --/ \defgroup init Library initialisation and management + --/ These functions allow you to intialise and control the bcm2835 library + --/ @{ + --/ Initialise the library by opening /dev/mem and getting pointers to the + --/ internal memory for BCM 2835 device registers. You must call this (successfully) + --/ before calling any other + --/ functions in this library (except bcm2835_set_debug). + --/ If bcm2835_init() fails by returning 0, + --/ calling any other function may result in crashes or other failures. + --/ Prints messages to stderr in case of errors. + --/ \return 1 if successful else 0 + function bcm2835_init return int; -- /usr/local/include/bcm2835.h:772 + pragma Import (C, bcm2835_init, "bcm2835_init"); + + --/ Close the library, deallocating any allocated memory and closing /dev/mem + --/ \return 1 if successful else 0 + function bcm2835_close return int; -- /usr/local/include/bcm2835.h:776 + pragma Import (C, bcm2835_close, "bcm2835_close"); + + --/ Sets the debug level of the library. + --/ A value of 1 prevents mapping to /dev/mem, and makes the library print out + --/ what it would do, rather than accessing the GPIO registers. + --/ A value of 0, the default, causes normal operation. + --/ Call this before calling bcm2835_init(); + --/ \param[in] debug The new debug level. 1 means debug + procedure bcm2835_set_debug (debug : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:784 + pragma Import (C, bcm2835_set_debug, "bcm2835_set_debug"); + + --/ @} // end of init + --/ \defgroup lowlevel Low level register access + --/ These functions provide low level register access, and should not generally + --/ need to be used + --/ + --/ @{ + --/ Reads 32 bit value from a peripheral address + --/ The read is done twice, and is therefore always safe in terms of + --/ manual section 1.3 Peripheral access precautions for correct memory ordering + --/ \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. + --/ \return the value read from the 32 bit register + --/ \sa Physical Addresses + function bcm2835_peri_read (paddr : access stdint_h.uint32_t) return stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:800 + pragma Import (C, bcm2835_peri_read, "bcm2835_peri_read"); + + --/ Reads 32 bit value from a peripheral address without the read barrier + --/ You should only use this when your code has previously called bcm2835_peri_read() + --/ within the same peripheral, and no other peripheral access has occurred since. + --/ \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. + --/ \return the value read from the 32 bit register + --/ \sa Physical Addresses + function bcm2835_peri_read_nb (paddr : access stdint_h.uint32_t) return stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:809 + pragma Import (C, bcm2835_peri_read_nb, "bcm2835_peri_read_nb"); + + --/ Writes 32 bit value from a peripheral address + --/ The write is done twice, and is therefore always safe in terms of + --/ manual section 1.3 Peripheral access precautions for correct memory ordering + --/ \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. + --/ \param[in] value The 32 bit value to write + --/ \sa Physical Addresses + procedure bcm2835_peri_write (paddr : access stdint_h.uint32_t; value : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:818 + pragma Import (C, bcm2835_peri_write, "bcm2835_peri_write"); + + --/ Writes 32 bit value from a peripheral address without the write barrier + --/ You should only use this when your code has previously called bcm2835_peri_write() + --/ within the same peripheral, and no other peripheral access has occurred since. + --/ \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. + --/ \param[in] value The 32 bit value to write + --/ \sa Physical Addresses + procedure bcm2835_peri_write_nb (paddr : access stdint_h.uint32_t; value : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:826 + pragma Import (C, bcm2835_peri_write_nb, "bcm2835_peri_write_nb"); + + --/ Alters a number of bits in a 32 peripheral regsiter. + --/ It reads the current valu and then alters the bits deines as 1 in mask, + --/ according to the bit value in value. + --/ All other bits that are 0 in the mask are unaffected. + --/ Use this to alter a subset of the bits in a register. + --/ The write is done twice, and is therefore always safe in terms of + --/ manual section 1.3 Peripheral access precautions for correct memory ordering + --/ \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc. + --/ \param[in] value The 32 bit value to write, masked in by mask. + --/ \param[in] mask Bitmask that defines the bits that will be altered in the register. + --/ \sa Physical Addresses + procedure bcm2835_peri_set_bits + (paddr : access stdint_h.uint32_t; + value : stdint_h.uint32_t; + mask : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:839 + pragma Import (C, bcm2835_peri_set_bits, "bcm2835_peri_set_bits"); + + --/ @} // end of lowlevel + --/ \defgroup gpio GPIO register access + --/ These functions allow you to control the GPIO interface. You can set the + --/ function of each GPIO pin, read the input state and set the output state. + --/ @{ + --/ Sets the Function Select register for the given pin, which configures + --/ the pin as Input, Output or one of the 6 alternate functions. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + --/ \param[in] mode Mode to set the pin to, one of BCM2835_GPIO_FSEL_* from \ref bcm2835FunctionSelect + procedure bcm2835_gpio_fsel (pin : stdint_h.uint8_t; mode : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:851 + pragma Import (C, bcm2835_gpio_fsel, "bcm2835_gpio_fsel"); + + --/ Sets the specified pin output to + --/ HIGH. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + --/ \sa bcm2835_gpio_write() + procedure bcm2835_gpio_set (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:857 + pragma Import (C, bcm2835_gpio_set, "bcm2835_gpio_set"); + + --/ Sets the specified pin output to + --/ LOW. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + --/ \sa bcm2835_gpio_write() + procedure bcm2835_gpio_clr (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:863 + pragma Import (C, bcm2835_gpio_clr, "bcm2835_gpio_clr"); + + --/ Sets any of the first 32 GPIO output pins specified in the mask to + --/ HIGH. + --/ \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) + --/ \sa bcm2835_gpio_write_multi() + procedure bcm2835_gpio_set_multi (mask : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:869 + pragma Import (C, bcm2835_gpio_set_multi, "bcm2835_gpio_set_multi"); + + --/ Sets any of the first 32 GPIO output pins specified in the mask to + --/ LOW. + --/ \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) + --/ \sa bcm2835_gpio_write_multi() + procedure bcm2835_gpio_clr_multi (mask : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:875 + pragma Import (C, bcm2835_gpio_clr_multi, "bcm2835_gpio_clr_multi"); + + --/ Reads the current level on the specified + --/ pin and returns either HIGH or LOW. Works whether or not the pin + --/ is an input or an output. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + --/ \return the current level either HIGH or LOW + function bcm2835_gpio_lev (pin : stdint_h.uint8_t) return stdint_h.uint8_t; -- /usr/local/include/bcm2835.h:882 + pragma Import (C, bcm2835_gpio_lev, "bcm2835_gpio_lev"); + + --/ Event Detect Status. + --/ Tests whether the specified pin has detected a level or edge + --/ as requested by bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen(), + --/ bcm2835_gpio_len(), bcm2835_gpio_aren(), bcm2835_gpio_afen(). + --/ Clear the flag for a given pin by calling bcm2835_gpio_set_eds(pin); + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + --/ \return HIGH if the event detect status for the given pin is true. + function bcm2835_gpio_eds (pin : stdint_h.uint8_t) return stdint_h.uint8_t; -- /usr/local/include/bcm2835.h:891 + pragma Import (C, bcm2835_gpio_eds, "bcm2835_gpio_eds"); + + --/ Sets the Event Detect Status register for a given pin to 1, + --/ which has the effect of clearing the flag. Use this afer seeing + --/ an Event Detect Status on the pin. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_set_eds (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:897 + pragma Import (C, bcm2835_gpio_set_eds, "bcm2835_gpio_set_eds"); + + --/ Enable Rising Edge Detect Enable for the specified pin. + --/ When a rising edge is detected, sets the appropriate pin in Event Detect Status. + --/ The GPRENn registers use + --/ synchronous edge detection. This means the input signal is sampled using the + --/ system clock and then it is looking for a ?011? pattern on the sampled signal. This + --/ has the effect of suppressing glitches. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_ren (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:906 + pragma Import (C, bcm2835_gpio_ren, "bcm2835_gpio_ren"); + + --/ Disable Rising Edge Detect Enable for the specified pin. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_clr_ren (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:910 + pragma Import (C, bcm2835_gpio_clr_ren, "bcm2835_gpio_clr_ren"); + + --/ Enable Falling Edge Detect Enable for the specified pin. + --/ When a falling edge is detected, sets the appropriate pin in Event Detect Status. + --/ The GPRENn registers use + --/ synchronous edge detection. This means the input signal is sampled using the + --/ system clock and then it is looking for a ?100? pattern on the sampled signal. This + --/ has the effect of suppressing glitches. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_fen (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:919 + pragma Import (C, bcm2835_gpio_fen, "bcm2835_gpio_fen"); + + --/ Disable Falling Edge Detect Enable for the specified pin. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_clr_fen (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:923 + pragma Import (C, bcm2835_gpio_clr_fen, "bcm2835_gpio_clr_fen"); + + --/ Enable High Detect Enable for the specified pin. + --/ When a HIGH level is detected on the pin, sets the appropriate pin in Event Detect Status. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_hen (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:928 + pragma Import (C, bcm2835_gpio_hen, "bcm2835_gpio_hen"); + + --/ Disable High Detect Enable for the specified pin. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_clr_hen (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:932 + pragma Import (C, bcm2835_gpio_clr_hen, "bcm2835_gpio_clr_hen"); + + --/ Enable Low Detect Enable for the specified pin. + --/ When a LOW level is detected on the pin, sets the appropriate pin in Event Detect Status. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_len (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:937 + pragma Import (C, bcm2835_gpio_len, "bcm2835_gpio_len"); + + --/ Disable Low Detect Enable for the specified pin. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_clr_len (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:941 + pragma Import (C, bcm2835_gpio_clr_len, "bcm2835_gpio_clr_len"); + + --/ Enable Asynchronous Rising Edge Detect Enable for the specified pin. + --/ When a rising edge is detected, sets the appropriate pin in Event Detect Status. + --/ Asynchronous means the incoming signal is not sampled by the system clock. As such + --/ rising edges of very short duration can be detected. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_aren (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:948 + pragma Import (C, bcm2835_gpio_aren, "bcm2835_gpio_aren"); + + --/ Disable Asynchronous Rising Edge Detect Enable for the specified pin. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_clr_aren (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:952 + pragma Import (C, bcm2835_gpio_clr_aren, "bcm2835_gpio_clr_aren"); + + --/ Enable Asynchronous Falling Edge Detect Enable for the specified pin. + --/ When a falling edge is detected, sets the appropriate pin in Event Detect Status. + --/ Asynchronous means the incoming signal is not sampled by the system clock. As such + --/ falling edges of very short duration can be detected. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_afen (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:959 + pragma Import (C, bcm2835_gpio_afen, "bcm2835_gpio_afen"); + + --/ Disable Asynchronous Falling Edge Detect Enable for the specified pin. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + procedure bcm2835_gpio_clr_afen (pin : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:963 + pragma Import (C, bcm2835_gpio_clr_afen, "bcm2835_gpio_clr_afen"); + + --/ Sets the Pull-up/down register for the given pin. This is + --/ used with bcm2835_gpio_pudclk() to set the Pull-up/down resistor for the given pin. + --/ However, it is usually more convenient to use bcm2835_gpio_set_pud(). + --/ \param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* from bcm2835PUDControl + --/ \sa bcm2835_gpio_set_pud() + procedure bcm2835_gpio_pud (pud : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:970 + pragma Import (C, bcm2835_gpio_pud, "bcm2835_gpio_pud"); + + --/ Clocks the Pull-up/down value set earlier by bcm2835_gpio_pud() into the pin. + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + --/ \param[in] on HIGH to clock the value from bcm2835_gpio_pud() into the pin. + --/ LOW to remove the clock. + --/ \sa bcm2835_gpio_set_pud() + procedure bcm2835_gpio_pudclk (pin : stdint_h.uint8_t; on : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:977 + pragma Import (C, bcm2835_gpio_pudclk, "bcm2835_gpio_pudclk"); + + --/ Reads and returns the Pad Control for the given GPIO group. + --/ \param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_* + --/ \return Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup + function bcm2835_gpio_pad (group : stdint_h.uint8_t) return stdint_h.uint32_t; -- /usr/local/include/bcm2835.h:982 + pragma Import (C, bcm2835_gpio_pad, "bcm2835_gpio_pad"); + + --/ Sets the Pad Control for the given GPIO group. + --/ \param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_* + --/ \param[in] control Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup. Note + --/ that it is not necessary to include BCM2835_PAD_PASSWRD in the mask as this + --/ is automatically included. + procedure bcm2835_gpio_set_pad (group : stdint_h.uint8_t; control : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:989 + pragma Import (C, bcm2835_gpio_set_pad, "bcm2835_gpio_set_pad"); + + --/ Delays for the specified number of milliseconds. + --/ Uses nanosleep(), and therefore does not use CPU until the time is up. + --/ However, you are at the mercy of nanosleep(). From the manual for nanosleep(): + --/ If the interval specified in req is not an exact multiple of the granularity + --/ underlying clock (see time(7)), then the interval will be + --/ rounded up to the next multiple. Furthermore, after the sleep completes, + --/ there may still be a delay before the CPU becomes free to once + --/ again execute the calling thread. + --/ \param[in] millis Delay in milliseconds + procedure bcm2835_delay (millis : unsigned); -- /usr/local/include/bcm2835.h:1000 + pragma Import (C, bcm2835_delay, "bcm2835_delay"); + + --/ Delays for the specified number of microseconds. + --/ Uses a combination of nanosleep() and a busy wait loop on the BCM2835 system timers, + --/ However, you are at the mercy of nanosleep(). From the manual for nanosleep(): + --/ If the interval specified in req is not an exact multiple of the granularity + --/ underlying clock (see time(7)), then the interval will be + --/ rounded up to the next multiple. Furthermore, after the sleep completes, + --/ there may still be a delay before the CPU becomes free to once + --/ again execute the calling thread. + --/ For times less than about 450 microseconds, uses a busy wait on the System Timer. + --/ It is reported that a delay of 0 microseconds on RaspberryPi will in fact + --/ result in a delay of about 80 microseconds. Your mileage may vary. + --/ \param[in] micros Delay in microseconds + procedure bcm2835_delayMicroseconds (micros : stdint_h.uint64_t); -- /usr/local/include/bcm2835.h:1014 + pragma Import (C, bcm2835_delayMicroseconds, "bcm2835_delayMicroseconds"); + + --/ Sets the output state of the specified pin + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + --/ \param[in] on HIGH sets the output to HIGH and LOW to LOW. + procedure bcm2835_gpio_write (pin : stdint_h.uint8_t; on : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1019 + pragma Import (C, bcm2835_gpio_write, "bcm2835_gpio_write"); + + --/ Sets any of the first 32 GPIO output pins specified in the mask to the state given by on + --/ \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) + --/ \param[in] on HIGH sets the output to HIGH and LOW to LOW. + procedure bcm2835_gpio_write_multi (mask : stdint_h.uint32_t; on : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1024 + pragma Import (C, bcm2835_gpio_write_multi, "bcm2835_gpio_write_multi"); + + --/ Sets the first 32 GPIO output pins specified in the mask to the value given by value + --/ \param[in] value values required for each bit masked in by mask, eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) + --/ \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05) + procedure bcm2835_gpio_write_mask (value : stdint_h.uint32_t; mask : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:1029 + pragma Import (C, bcm2835_gpio_write_mask, "bcm2835_gpio_write_mask"); + + --/ Sets the Pull-up/down mode for the specified pin. This is more convenient than + --/ clocking the mode in with bcm2835_gpio_pud() and bcm2835_gpio_pudclk(). + --/ \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin. + --/ \param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* from bcm2835PUDControl + procedure bcm2835_gpio_set_pud (pin : stdint_h.uint8_t; pud : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1035 + pragma Import (C, bcm2835_gpio_set_pud, "bcm2835_gpio_set_pud"); + + --/ @} + --/ \defgroup spi SPI access + --/ These functions let you use SPI0 (Serial Peripheral Interface) to + --/ interface with an external SPI device. + --/ @{ + --/ Start SPI operations. + --/ Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1) + --/ to alternate function ALT0, which enables those pins for SPI interface. + --/ You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to + --/ their default functions + --/ \sa bcm2835_spi_end() + procedure bcm2835_spi_begin; -- /usr/local/include/bcm2835.h:1050 + pragma Import (C, bcm2835_spi_begin, "bcm2835_spi_begin"); + + --/ End SPI operations. + --/ SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1) + --/ are returned to their default INPUT behaviour. + procedure bcm2835_spi_end; -- /usr/local/include/bcm2835.h:1055 + pragma Import (C, bcm2835_spi_end, "bcm2835_spi_end"); + + --/ Sets the SPI bit order + --/ NOTE: has no effect. Not supported by SPI0. + --/ Defaults to + --/ \param[in] order The desired bit order, one of BCM2835_SPI_BIT_ORDER_*, + --/ see \ref bcm2835SPIBitOrder + procedure bcm2835_spi_setBitOrder (order : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1062 + pragma Import (C, bcm2835_spi_setBitOrder, "bcm2835_spi_setBitOrder"); + + --/ Sets the SPI clock divider and therefore the + --/ SPI clock speed. + --/ \param[in] divider The desired SPI clock divider, one of BCM2835_SPI_CLOCK_DIVIDER_*, + --/ see \ref bcm2835SPIClockDivider + procedure bcm2835_spi_setClockDivider (divider : stdint_h.uint16_t); -- /usr/local/include/bcm2835.h:1068 + pragma Import (C, bcm2835_spi_setClockDivider, "bcm2835_spi_setClockDivider"); + + --/ Sets the SPI data mode + --/ Sets the clock polariy and phase + --/ \param[in] mode The desired data mode, one of BCM2835_SPI_MODE*, + --/ see \ref bcm2835SPIMode + procedure bcm2835_spi_setDataMode (mode : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1074 + pragma Import (C, bcm2835_spi_setDataMode, "bcm2835_spi_setDataMode"); + + --/ Sets the chip select pin(s) + --/ When an bcm2835_spi_transfer() is made, the selected pin(s) will be asserted during the + --/ transfer. + --/ \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave. + --/ One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect + procedure bcm2835_spi_chipSelect (cs : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1081 + pragma Import (C, bcm2835_spi_chipSelect, "bcm2835_spi_chipSelect"); + + --/ Sets the chip select pin polarity for a given pin + --/ When an bcm2835_spi_transfer() occurs, the currently selected chip select pin(s) + --/ will be asserted to the + --/ value given by active. When transfers are not happening, the chip select pin(s) + --/ return to the complement (inactive) value. + --/ \param[in] cs The chip select pin to affect + --/ \param[in] active Whether the chip select pin is to be active HIGH + procedure bcm2835_spi_setChipSelectPolarity (cs : stdint_h.uint8_t; active : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1090 + pragma Import (C, bcm2835_spi_setChipSelectPolarity, "bcm2835_spi_setChipSelectPolarity"); + + --/ Transfers one byte to and from the currently selected SPI slave. + --/ Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect) + --/ during the transfer. + --/ Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO. + --/ Returns the read data byte from the slave. + --/ Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual + --/ \param[in] value The 8 bit data byte to write to MOSI + --/ \return The 8 bit byte simultaneously read from MISO + --/ \sa bcm2835_spi_transfern() + function bcm2835_spi_transfer (value : stdint_h.uint8_t) return stdint_h.uint8_t; -- /usr/local/include/bcm2835.h:1101 + pragma Import (C, bcm2835_spi_transfer, "bcm2835_spi_transfer"); + + --/ Transfers any number of bytes to and from the currently selected SPI slave. + --/ Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect) + --/ during the transfer. + --/ Clocks the len 8 bit bytes out on MOSI, and simultaneously clocks in data from MISO. + --/ The data read read from the slave is placed into rbuf. rbuf must be at least len bytes long + --/ Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual + --/ \param[in] tbuf Buffer of bytes to send. + --/ \param[out] rbuf Received bytes will by put in this buffer + --/ \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received + --/ \sa bcm2835_spi_transfer() + procedure bcm2835_spi_transfernb + (tbuf : Interfaces.C.Strings.chars_ptr; + rbuf : Interfaces.C.Strings.chars_ptr; + len : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:1113 + pragma Import (C, bcm2835_spi_transfernb, "bcm2835_spi_transfernb"); + + --/ Transfers any number of bytes to and from the currently selected SPI slave + --/ using bcm2835_spi_transfernb. + --/ The returned data from the slave replaces the transmitted data in the buffer. + --/ \param[in,out] buf Buffer of bytes to send. Received bytes will replace the contents + --/ \param[in] len Number of bytes int eh buffer, and the number of bytes to send/received + --/ \sa bcm2835_spi_transfer() + procedure bcm2835_spi_transfern (buf : Interfaces.C.Strings.chars_ptr; len : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:1121 + pragma Import (C, bcm2835_spi_transfern, "bcm2835_spi_transfern"); + + --/ Transfers any number of bytes to the currently selected SPI slave. + --/ Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect) + --/ during the transfer. + --/ \param[in] buf Buffer of bytes to send. + --/ \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send + procedure bcm2835_spi_writenb (buf : Interfaces.C.Strings.chars_ptr; len : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:1128 + pragma Import (C, bcm2835_spi_writenb, "bcm2835_spi_writenb"); + + --/ @} + --/ \defgroup i2c I2C access + --/ These functions let you use I2C (The Broadcom Serial Control bus with the Philips + --/ I2C bus/interface version 2.1 January 2000.) to interface with an external I2C device. + --/ @{ + --/ Start I2C operations. + --/ Forces RPi I2C pins P1-03 (SDA) and P1-05 (SCL) + --/ to alternate function ALT0, which enables those pins for I2C interface. + --/ You should call bcm2835_i2c_end() when all I2C functions are complete to return the pins to + --/ their default functions + --/ \sa bcm2835_i2c_end() + procedure bcm2835_i2c_begin; -- /usr/local/include/bcm2835.h:1143 + pragma Import (C, bcm2835_i2c_begin, "bcm2835_i2c_begin"); + + --/ End I2C operations. + --/ I2C pins P1-03 (SDA) and P1-05 (SCL) + --/ are returned to their default INPUT behaviour. + procedure bcm2835_i2c_end; -- /usr/local/include/bcm2835.h:1148 + pragma Import (C, bcm2835_i2c_end, "bcm2835_i2c_end"); + + --/ Sets the I2C slave address. + --/ \param[in] addr The I2C slave address. + procedure bcm2835_i2c_setSlaveAddress (addr : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1152 + pragma Import (C, bcm2835_i2c_setSlaveAddress, "bcm2835_i2c_setSlaveAddress"); + + --/ Sets the I2C clock divider and therefore the I2C clock speed. + --/ \param[in] divider The desired I2C clock divider, one of BCM2835_I2C_CLOCK_DIVIDER_*, + --/ see \ref bcm2835I2CClockDivider + procedure bcm2835_i2c_setClockDivider (divider : stdint_h.uint16_t); -- /usr/local/include/bcm2835.h:1157 + pragma Import (C, bcm2835_i2c_setClockDivider, "bcm2835_i2c_setClockDivider"); + + --/ Sets the I2C clock divider by converting the baudrate parameter to + --/ the equivalent I2C clock divider. ( see \sa bcm2835_i2c_setClockDivider) + --/ For the I2C standard 100khz you would set baudrate to 100000 + --/ The use of baudrate corresponds to its use in the I2C kernel device + --/ driver. (Of course, bcm2835 has nothing to do with the kernel driver) + procedure bcm2835_i2c_set_baudrate (baudrate : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:1164 + pragma Import (C, bcm2835_i2c_set_baudrate, "bcm2835_i2c_set_baudrate"); + + --/ Transfers any number of bytes to the currently selected I2C slave. + --/ (as previously set by \sa bcm2835_i2c_setSlaveAddress) + --/ \param[in] buf Buffer of bytes to send. + --/ \param[in] len Number of bytes in the buf buffer, and the number of bytes to send. + --/ \return reason see \ref bcm2835I2CReasonCodes + function bcm2835_i2c_write (buf : Interfaces.C.Strings.chars_ptr; len : stdint_h.uint32_t) return stdint_h.uint8_t; -- /usr/local/include/bcm2835.h:1171 + pragma Import (C, bcm2835_i2c_write, "bcm2835_i2c_write"); + + --/ Transfers any number of bytes from the currently selected I2C slave. + --/ (as previously set by \sa bcm2835_i2c_setSlaveAddress) + --/ \param[in] buf Buffer of bytes to receive. + --/ \param[in] len Number of bytes in the buf buffer, and the number of bytes to received. + --/ \return reason see \ref bcm2835I2CReasonCodes + function bcm2835_i2c_read (buf : Interfaces.C.Strings.chars_ptr; len : stdint_h.uint32_t) return stdint_h.uint8_t; -- /usr/local/include/bcm2835.h:1178 + pragma Import (C, bcm2835_i2c_read, "bcm2835_i2c_read"); + + --/ Allows reading from I2C slaves that require a repeated start (without any prior stop) + --/ to read after the required slave register has been set. For example, the popular + --/ MPL3115A2 pressure and temperature sensor. Note that your device must support or + --/ require this mode. If your device does not require this mode then the standard + --/ combined: + --/ \sa bcm2835_i2c_write + --/ \sa bcm2835_i2c_read + --/ are a better choice. + --/ Will read from the slave previously set by \sa bcm2835_i2c_setSlaveAddress + --/ \param[in] regaddr Buffer containing the slave register you wish to read from. + --/ \param[in] buf Buffer of bytes to receive. + --/ \param[in] len Number of bytes in the buf buffer, and the number of bytes to received. + --/ \return reason see \ref bcm2835I2CReasonCodes + function bcm2835_i2c_read_register_rs + (regaddr : Interfaces.C.Strings.chars_ptr; + buf : Interfaces.C.Strings.chars_ptr; + len : stdint_h.uint32_t) return stdint_h.uint8_t; -- /usr/local/include/bcm2835.h:1193 + pragma Import (C, bcm2835_i2c_read_register_rs, "bcm2835_i2c_read_register_rs"); + + --/ @} + --/ \defgroup st System Timer access + --/ Allows access to and delays using the System Timer Counter. + --/ @{ + --/ Read the System Timer Counter register. + --/ \return the value read from the System Timer Counter Lower 32 bits register + function bcm2835_st_read return stdint_h.uint64_t; -- /usr/local/include/bcm2835.h:1203 + pragma Import (C, bcm2835_st_read, "bcm2835_st_read"); + + --/ Delays for the specified number of microseconds with offset. + --/ \param[in] offset_micros Offset in microseconds + --/ \param[in] micros Delay in microseconds + procedure bcm2835_st_delay (offset_micros : stdint_h.uint64_t; micros : stdint_h.uint64_t); -- /usr/local/include/bcm2835.h:1208 + pragma Import (C, bcm2835_st_delay, "bcm2835_st_delay"); + + --/ @} + --/ \defgroup pwm Pulse Width Modulation + --/ Allows control of 2 independent PWM channels. A limited subset of GPIO pins + --/ can be connected to one of these 2 channels, allowing PWM control of GPIO pins. + --/ You have to set the desired pin into a particular Alt Fun to PWM output. See the PWM + --/ documentation on the Main Page. + --/ @{ + --/ Sets the PWM clock divisor, + --/ to control the basic PWM pulse widths. + --/ \param[in] divisor Divides the basic 19.2MHz PWM clock. You can use one of the common + --/ values BCM2835_PWM_CLOCK_DIVIDER_* in \ref bcm2835PWMClockDivider. + procedure bcm2835_pwm_set_clock (divisor : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:1223 + pragma Import (C, bcm2835_pwm_set_clock, "bcm2835_pwm_set_clock"); + + --/ Sets the mode of the given PWM channel, + --/ allowing you to control the PWM mode and enable/disable that channel + --/ \param[in] channel The PWM channel. 0 or 1. + --/ \param[in] markspace Set true if you want Mark-Space mode. 0 for Balanced mode. + --/ \param[in] enabled Set true to enable this channel and produce PWM pulses. + procedure bcm2835_pwm_set_mode + (channel : stdint_h.uint8_t; + markspace : stdint_h.uint8_t; + enabled : stdint_h.uint8_t); -- /usr/local/include/bcm2835.h:1230 + pragma Import (C, bcm2835_pwm_set_mode, "bcm2835_pwm_set_mode"); + + --/ Sets the maximum range of the PWM output. + --/ The data value can vary between 0 and this range to control PWM output + --/ \param[in] channel The PWM channel. 0 or 1. + --/ \param[in] range The maximum value permitted for DATA. + procedure bcm2835_pwm_set_range (channel : stdint_h.uint8_t; c_range : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:1236 + pragma Import (C, bcm2835_pwm_set_range, "bcm2835_pwm_set_range"); + + --/ Sets the PWM pulse ratio to emit to DATA/RANGE, + --/ where RANGE is set by bcm2835_pwm_set_range(). + --/ \param[in] channel The PWM channel. 0 or 1. + --/ \param[in] data Controls the PWM output ratio as a fraction of the range. + --/ Can vary from 0 to RANGE. + procedure bcm2835_pwm_set_data (channel : stdint_h.uint8_t; data : stdint_h.uint32_t); -- /usr/local/include/bcm2835.h:1243 + pragma Import (C, bcm2835_pwm_set_data, "bcm2835_pwm_set_data"); + + --/ @} + --/ @example blink.c + --/ Blinks RPi GPIO pin 11 on and off + --/ @example input.c + --/ Reads the state of an RPi input pin + --/ @example event.c + --/ Shows how to use event detection on an input pin + --/ @example spi.c + --/ Shows how to use SPI interface to transfer a byte to and from an SPI device + --/ @example spin.c + --/ Shows how to use SPI interface to transfer a number of bytes to and from an SPI device + --/ @example pwm.c + --/ Shows how to use PWM to control GPIO pins +end bcm2835_h; diff --git a/st7565-lcd/ada/raspilcd.adb b/st7565-lcd/ada/raspilcd.adb new file mode 100644 index 0000000..e1e2e66 --- /dev/null +++ b/st7565-lcd/ada/raspilcd.adb @@ -0,0 +1,132 @@ +with Interfaces; +use Interfaces; +with Interfaces.C; +use Interfaces.C; +with Interfaces.C.extensions; +use Interfaces.C.extensions; +with bcm2835_h; +use bcm2835_h; + + + +package body RaspiLcd is + + + procedure io_init is + begin + bcm2835_gpio_fsel(pin => LCD_CS, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP)); + bcm2835_gpio_fsel(pin => LCD_RST, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP)); + bcm2835_gpio_fsel(pin => LCD_A0, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP)); + bcm2835_gpio_fsel(pin => LCD_CLK, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP)); + bcm2835_gpio_fsel(pin => LCD_SI, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP)); + end io_init; + + + procedure lcd_init is + begin + -- reset + bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH)); + bcm2835_delayMicroseconds(unsigned_long_long(1)); + bcm2835_gpio_write(pin => LCD_RST, on => unsigned_char(LOW)); + bcm2835_delayMicroseconds(unsigned_long_long(1)); + bcm2835_gpio_write(pin => LCD_RST, on => unsigned_char(HIGH)); + bcm2835_delayMicroseconds(unsigned_long_long(1)); + -- init routine + for index in lcd_init_data'range loop + lcd_transfer_data(value => lcd_init_data(index), si => false); + end loop; + lcd_clear; + end lcd_init; + + + procedure lcd_ascii57_string (xpos : natural; ypos : natural; data : string) is + begin + for index in 0 .. data'length-1 loop + lcd_ascii57(xpos => xpos + index * 6, ypos => ypos, data => character'val(character'pos(data(index+1)))); + end loop; + end lcd_ascii57_string; + + + procedure lcd_ascii57 (xpos : natural; ypos : natural; data : character) is + begin + lcd_set_page(page => ypos, column => xpos); + -- write one 5x7 char + for index in 0..4 loop + lcd_transfer_data(value => font_5x7(character'pos(data) - 32)(index), si => true); + end loop; + -- one free column between chars + lcd_transfer_data(value => 16#00#, si => true); + end lcd_ascii57; + + + procedure lcd_picture (xpos : natural; ypos: natural) is + begin + for outdex in 0..7 loop + lcd_set_page(page => ypos + outdex, column => xpos); + for index in (128 * outdex) .. (128 * (outdex + 1) - 1) loop + lcd_transfer_data(value => picture(index), si => true); + end loop; + end loop; + end lcd_picture; + + + procedure lcd_clear is + begin + bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(LOW)); + for outdex in 0..7 loop + lcd_set_page(page => outdex, column => 0); + for index in 0..128 loop + lcd_transfer_data(value => 16#00#, si => true); + end loop; + end loop; + bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH)); + end lcd_clear; + + + procedure lcd_transfer_data (value : byte; si : boolean) is + begin + bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(LOW)); + bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(HIGH)); + if si then + bcm2835_gpio_write(pin => LCD_A0, on => unsigned_char(HIGH)); + else + bcm2835_gpio_write(pin => LCD_A0, on => unsigned_char(LOW)); + end if; + lcd_byte(value); + bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH)); + end lcd_transfer_data; + + + procedure lcd_set_page (page : natural; column : natural) is + lsb : byte := byte(column + 1) and 16#0f#; + msb : byte := byte(column + 1) and 16#f0#; + page_int : byte := byte(page) or 16#b0#; + begin + msb := Shift_Right(msb, 4); + msb := msb or 16#10#; + lcd_transfer_data(value => page_int, si => false); + lcd_transfer_data(value => msb, si => false); + lcd_transfer_data(value => lsb, si => false); + null; + end lcd_set_page; + + + procedure lcd_byte (data : byte) is + data_int : byte := data; + begin + for index in 0..7 loop + bcm2835_delayMicroseconds(unsigned_long_long(1)); + bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(LOW)); + if (data_int and 16#80#) = 16#80# then + bcm2835_gpio_write(pin => LCD_SI, on => unsigned_char(HIGH)); + else + bcm2835_gpio_write(pin => LCD_SI, on => unsigned_char(LOW)); + end if; + data_int := Shift_Left(data_int, 1); + bcm2835_delayMicroseconds(unsigned_long_long(1)); + bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(HIGH)); + end loop; + end lcd_byte; + + +end RaspiLcd; \ No newline at end of file diff --git a/st7565-lcd/ada/raspilcd.ads b/st7565-lcd/ada/raspilcd.ads new file mode 100644 index 0000000..8234b7e --- /dev/null +++ b/st7565-lcd/ada/raspilcd.ads @@ -0,0 +1,224 @@ +with Interfaces; +with Interfaces.C; + + +package RaspiLcd is + + + -- type definitions + subtype byte is Interfaces.Unsigned_8; + + type byte_array is array (natural range <>) of byte; + + type byte_byte_array is array (natural range <>) of byte_array (0 .. 4); + + + -- character set + font_5x7 : constant byte_byte_array := ( + ( 16#00#, 16#00#, 16#00#, 16#00#, 16#00# ), -- - 16#20 - 32 + ( 16#00#, 16#00#, 16#5f#, 16#00#, 16#00# ), -- ! - 16#21 - 33 + ( 16#00#, 16#07#, 16#00#, 16#07#, 16#00# ), -- " - 16#22 - 34 + ( 16#14#, 16#7f#, 16#14#, 16#7f#, 16#14# ), -- # - 16#23 - 35 + ( 16#24#, 16#2a#, 16#7f#, 16#2a#, 16#12# ), -- $ - 16#24 - 36 + ( 16#23#, 16#13#, 16#08#, 16#64#, 16#62# ), -- % - 16#25 - 37 + ( 16#36#, 16#49#, 16#55#, 16#22#, 16#50# ), -- & - 16#26 - 38 + ( 16#00#, 16#05#, 16#03#, 16#00#, 16#00# ), -- ' - 16#27 - 39 + ( 16#00#, 16#1c#, 16#22#, 16#41#, 16#00# ), -- ( - 16#28 - 40 + ( 16#00#, 16#41#, 16#22#, 16#1c#, 16#00# ), -- ) - 16#29 - 41 + ( 16#14#, 16#08#, 16#3e#, 16#08#, 16#14# ), -- * - 16#2a - 42 + ( 16#08#, 16#08#, 16#3e#, 16#08#, 16#08# ), -- + - 16#2b - 43 + ( 16#00#, 16#50#, 16#30#, 16#00#, 16#00# ), -- , - 16#2c - 44 + ( 16#08#, 16#08#, 16#08#, 16#08#, 16#08# ), -- - - 16#2d - 45 + ( 16#00#, 16#60#, 16#60#, 16#00#, 16#00# ), -- . - 16#2e - 46 + ( 16#20#, 16#10#, 16#08#, 16#04#, 16#02# ), -- / - 16#2f - 47 + ( 16#3e#, 16#51#, 16#49#, 16#45#, 16#3e# ), -- 0 - 16#30 - 48 + ( 16#00#, 16#42#, 16#7f#, 16#40#, 16#00# ), -- 1 - 16#31 - 49 + ( 16#42#, 16#61#, 16#51#, 16#49#, 16#46# ), -- 2 - 16#32 - 50 + ( 16#21#, 16#41#, 16#45#, 16#4b#, 16#31# ), -- 3 - 16#33 - 51 + ( 16#18#, 16#14#, 16#12#, 16#7f#, 16#10# ), -- 4 - 16#34 - 52 + ( 16#27#, 16#45#, 16#45#, 16#45#, 16#39# ), -- 5 - 16#35 - 53 + ( 16#3c#, 16#4a#, 16#49#, 16#49#, 16#30# ), -- 6 - 16#36 - 54 + ( 16#01#, 16#71#, 16#09#, 16#05#, 16#03# ), -- 7 - 16#37 - 55 + ( 16#36#, 16#49#, 16#49#, 16#49#, 16#36# ), -- 8 - 16#38 - 56 + ( 16#06#, 16#49#, 16#49#, 16#29#, 16#1e# ), -- 9 - 16#39 - 57 + ( 16#00#, 16#36#, 16#36#, 16#00#, 16#00# ), -- : - 16#3a - 58 + ( 16#00#, 16#56#, 16#36#, 16#00#, 16#00# ), -- ; - 16#3b - 59 + ( 16#08#, 16#14#, 16#22#, 16#41#, 16#00# ), -- < - 16#3c - 60 + ( 16#14#, 16#14#, 16#14#, 16#14#, 16#14# ), -- = - 16#3d - 61 + ( 16#00#, 16#41#, 16#22#, 16#14#, 16#08# ), -- > - 16#3e - 62 + ( 16#02#, 16#01#, 16#51#, 16#09#, 16#06# ), -- ? - 16#3f - 63 + ( 16#32#, 16#49#, 16#79#, 16#41#, 16#3e# ), -- @ - 16#40 - 64 + ( 16#7e#, 16#11#, 16#11#, 16#11#, 16#7e# ), -- A - 16#41 - 65 + ( 16#7f#, 16#49#, 16#49#, 16#49#, 16#36# ), -- B - 16#42 - 66 + ( 16#3e#, 16#41#, 16#41#, 16#41#, 16#22# ), -- C - 16#43 - 67 + ( 16#7f#, 16#41#, 16#41#, 16#22#, 16#1c# ), -- D - 16#44 - 68 + ( 16#7f#, 16#49#, 16#49#, 16#49#, 16#41# ), -- E - 16#45 - 69 + ( 16#7f#, 16#09#, 16#09#, 16#09#, 16#01# ), -- F - 16#46 - 70 + ( 16#3e#, 16#41#, 16#49#, 16#49#, 16#7a# ), -- G - 16#47 - 71 + ( 16#7f#, 16#08#, 16#08#, 16#08#, 16#7f# ), -- H - 16#48 - 72 + ( 16#00#, 16#41#, 16#7f#, 16#41#, 16#00# ), -- I - 16#49 - 73 + ( 16#20#, 16#40#, 16#41#, 16#3f#, 16#01# ), -- J - 16#4a - 74 + ( 16#7f#, 16#08#, 16#14#, 16#22#, 16#41# ), -- K - 16#4b - 75 + ( 16#7f#, 16#40#, 16#40#, 16#40#, 16#40# ), -- L - 16#4c - 76 + ( 16#7f#, 16#02#, 16#0c#, 16#02#, 16#7f# ), -- M - 16#4d - 77 + ( 16#7f#, 16#04#, 16#08#, 16#10#, 16#7f# ), -- N - 16#4e - 78 + ( 16#3e#, 16#41#, 16#41#, 16#41#, 16#3e# ), -- O - 16#4f - 79 + ( 16#7f#, 16#09#, 16#09#, 16#09#, 16#06# ), -- P - 16#50 - 80 + ( 16#3e#, 16#41#, 16#51#, 16#21#, 16#5e# ), -- Q - 16#51 - 81 + ( 16#7f#, 16#09#, 16#19#, 16#29#, 16#46# ), -- R - 16#52 - 82 + ( 16#46#, 16#49#, 16#49#, 16#49#, 16#31# ), -- S - 16#53 - 83 + ( 16#01#, 16#01#, 16#7f#, 16#01#, 16#01# ), -- T - 16#54 - 84 + ( 16#3f#, 16#40#, 16#40#, 16#40#, 16#3f# ), -- U - 16#55 - 85 + ( 16#1f#, 16#20#, 16#40#, 16#20#, 16#1f# ), -- V - 16#56 - 86 + ( 16#3f#, 16#40#, 16#38#, 16#40#, 16#3f# ), -- W - 16#57 - 87 + ( 16#63#, 16#14#, 16#08#, 16#14#, 16#63# ), -- X - 16#58 - 88 + ( 16#07#, 16#08#, 16#70#, 16#08#, 16#07# ), -- Y - 16#59 - 89 + ( 16#61#, 16#51#, 16#49#, 16#45#, 16#43# ), -- Z - 16#5a - 90 + ( 16#00#, 16#7f#, 16#41#, 16#41#, 16#00# ), -- [ - 16#5b - 91 + ( 16#02#, 16#04#, 16#08#, 16#10#, 16#20# ), -- \ - 16#5c - 92 + ( 16#00#, 16#41#, 16#41#, 16#7f#, 16#00# ), -- ] - 16#5d - 93 + ( 16#04#, 16#02#, 16#01#, 16#02#, 16#04# ), -- ^ - 16#5e - 94 + ( 16#40#, 16#40#, 16#40#, 16#40#, 16#40# ), -- _ - 16#5f - 95 + ( 16#00#, 16#01#, 16#02#, 16#04#, 16#00# ), -- ` - 16#60 - 96 + ( 16#20#, 16#54#, 16#54#, 16#54#, 16#78# ), -- a - 16#61 - 97 + ( 16#7f#, 16#48#, 16#44#, 16#44#, 16#38# ), -- b - 16#62 - 98 + ( 16#38#, 16#44#, 16#44#, 16#44#, 16#20# ), -- c - 16#63 - 99 + ( 16#38#, 16#44#, 16#44#, 16#48#, 16#7f# ), -- d - 16#64 - 100 + ( 16#38#, 16#54#, 16#54#, 16#54#, 16#18# ), -- e - 16#65 - 101 + ( 16#08#, 16#7e#, 16#09#, 16#01#, 16#02# ), -- f - 16#66 - 102 + ( 16#38#, 16#44#, 16#44#, 16#54#, 16#34# ), -- g - 16#67 - 103 + ( 16#7f#, 16#08#, 16#04#, 16#04#, 16#78# ), -- h - 16#68 - 104 + ( 16#00#, 16#44#, 16#7d#, 16#40#, 16#00# ), -- i - 16#69 - 105 + ( 16#20#, 16#40#, 16#44#, 16#3d#, 16#00# ), -- j - 16#6a - 106 + ( 16#7f#, 16#10#, 16#28#, 16#44#, 16#00# ), -- k - 16#6b - 107 + ( 16#00#, 16#41#, 16#7f#, 16#40#, 16#00# ), -- l - 16#6c - 108 + ( 16#7c#, 16#04#, 16#18#, 16#04#, 16#78# ), -- m - 16#6d - 109 + ( 16#7c#, 16#08#, 16#04#, 16#04#, 16#78# ), -- n - 16#6e - 110 + ( 16#38#, 16#44#, 16#44#, 16#44#, 16#38# ), -- o - 16#6f - 111 + ( 16#7c#, 16#14#, 16#14#, 16#14#, 16#08# ), -- p - 16#70 - 112 + ( 16#08#, 16#14#, 16#14#, 16#18#, 16#7c# ), -- q - 16#71 - 113 + ( 16#7c#, 16#08#, 16#04#, 16#04#, 16#08# ), -- r - 16#72 - 114 + ( 16#48#, 16#54#, 16#54#, 16#54#, 16#20# ), -- s - 16#73 - 115 + ( 16#04#, 16#3f#, 16#44#, 16#40#, 16#20# ), -- t - 16#74 - 116 + ( 16#3c#, 16#40#, 16#40#, 16#20#, 16#7c# ), -- u - 16#75 - 117 + ( 16#1c#, 16#20#, 16#40#, 16#20#, 16#1c# ), -- v - 16#76 - 118 + ( 16#3c#, 16#40#, 16#30#, 16#40#, 16#3c# ), -- w - 16#77 - 119 + ( 16#44#, 16#28#, 16#10#, 16#28#, 16#44# ), -- x - 16#78 - 120 + ( 16#0c#, 16#50#, 16#50#, 16#50#, 16#3c# ), -- y - 16#79 - 121 + ( 16#44#, 16#64#, 16#54#, 16#4c#, 16#44# ), -- z - 16#7a - 122 + ( 16#00#, 16#08#, 16#36#, 16#41#, 16#00# ), -- { - 16#7b - 123 + ( 16#00#, 16#00#, 16#7f#, 16#00#, 16#00# ), -- | - 16#7c - 124 + ( 16#00#, 16#41#, 16#36#, 16#08#, 16#00# ), -- } - 16#7d - 125 + ( 16#10#, 16#08#, 16#08#, 16#10#, 16#08# ) -- ~ - 16#7e - 126 + ); + + + -- raspberry picture + picture : constant byte_array := ( + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 1. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 1. row + 16#00#,16#00#,16#00#,16#00#,16#F0#,16#F8#,16#58#,16#1C#,16#1C#,16#0C#,16#0C#,16#06#,16#86#,16#86#,16#86#,16#0E#, -- 1. row + 16#0E#,16#06#,16#0E#,16#1E#,16#1C#,16#1C#,16#0C#,16#3C#,16#38#,16#78#,16#F0#,16#E0#,16#C0#,16#C0#,16#E0#,16#70#, -- 1. row + 16#38#,16#18#,16#1C#,16#1C#,16#0C#,16#0E#,16#0E#,16#0E#,16#0E#,16#0E#,16#0E#,16#86#,16#86#,16#06#,16#04#,16#0C#, -- 1. row + 16#0C#,16#18#,16#F8#,16#F8#,16#F8#,16#F0#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 1. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 1. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 1. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 2. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 2. row + 16#00#,16#00#,16#00#,16#00#,16#03#,16#0F#,16#3F#,16#7C#,16#F0#,16#C0#,16#C0#,16#C0#,16#C0#,16#00#,16#01#,16#01#, -- 2. row + 16#03#,16#02#,16#06#,16#04#,16#04#,16#1C#,16#B8#,16#F0#,16#E0#,16#70#,16#30#,16#1F#,16#0F#,16#0F#,16#3F#,16#30#, -- 2. row + 16#F0#,16#E0#,16#B0#,16#18#,16#08#,16#0C#,16#04#,16#06#,16#02#,16#01#,16#01#,16#00#,16#00#,16#00#,16#00#,16#C0#, -- 2. row + 16#F0#,16#F8#,16#7F#,16#1F#,16#07#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 2. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 2. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 2. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 3. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 3. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#80#,16#E0#,16#F3#,16#33#,16#3F#,16#1F#,16#1E#,16#0E#,16#0E#, -- 3. row + 16#0C#,16#0C#,16#EC#,16#EC#,16#EE#,16#BE#,16#0F#,16#0F#,16#07#,16#06#,16#02#,16#02#,16#02#,16#02#,16#02#,16#06#, -- 3. row + 16#06#,16#0F#,16#0F#,16#BE#,16#EE#,16#CC#,16#8C#,16#0C#,16#0C#,16#0C#,16#0E#,16#1E#,16#1E#,16#3F#,16#73#,16#E1#, -- 3. row + 16#C1#,16#00#,16#36#,16#25#,16#55#,16#5D#,16#49#,16#6D#,16#32#,16#0C#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 3. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 3. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 3. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 4. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 4. row + 16#00#,16#00#,16#00#,16#80#,16#C0#,16#E0#,16#70#,16#7F#,16#7F#,16#3F#,16#FC#,16#FC#,16#FC#,16#3C#,16#1C#,16#0E#, -- 4. row + 16#07#,16#07#,16#03#,16#03#,16#03#,16#03#,16#03#,16#02#,16#06#,16#0E#,16#1C#,16#FC#,16#FC#,16#FC#,16#3C#,16#0E#, -- 4. row + 16#06#,16#02#,16#03#,16#03#,16#03#,16#03#,16#03#,16#03#,16#07#,16#06#,16#0C#,16#18#,16#78#,16#F0#,16#F0#,16#33#, -- 4. row + 16#7F#,16#7F#,16#70#,16#F0#,16#C0#,16#80#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 4. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 4. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 4. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 5. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 5. row + 16#00#,16#00#,16#FF#,16#FF#,16#83#,16#00#,16#00#,16#00#,16#00#,16#C0#,16#FF#,16#FF#,16#F0#,16#F0#,16#F0#,16#80#, -- 5. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#80#,16#80#,16#C0#,16#60#,16#78#,16#7F#,16#7F#,16#7F#,16#7C#,16#70#, -- 5. row + 16#E0#,16#C0#,16#80#,16#80#,16#00#,16#00#,16#00#,16#00#,16#00#,16#80#,16#80#,16#C0#,16#E0#,16#FF#,16#FF#,16#C0#, -- 5. row + 16#00#,16#00#,16#00#,16#00#,16#C3#,16#FF#,16#FE#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 5. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 5. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 5. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 6. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 6. row + 16#00#,16#00#,16#00#,16#03#,16#0F#,16#3E#,16#FC#,16#FC#,16#0E#,16#03#,16#03#,16#03#,16#03#,16#07#,16#07#,16#0F#, -- 6. row + 16#1F#,16#3F#,16#7F#,16#FF#,16#FF#,16#07#,16#01#,16#01#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 6. row + 16#00#,16#00#,16#01#,16#03#,16#FF#,16#FF#,16#7F#,16#1F#,16#0F#,16#07#,16#07#,16#03#,16#01#,16#01#,16#01#,16#01#, -- 6. row + 16#03#,16#FE#,16#FE#,16#7E#,16#07#,16#03#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 6. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 6. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 6. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 7. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 7. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#01#,16#07#,16#1F#,16#3C#,16#78#,16#70#,16#E0#,16#E0#,16#E0#,16#C0#, -- 7. row + 16#C0#,16#C0#,16#C0#,16#E1#,16#FF#,16#7F#,16#7F#,16#3C#,16#3C#,16#3C#,16#38#,16#30#,16#30#,16#30#,16#30#,16#38#, -- 7. row + 16#38#,16#3C#,16#3C#,16#7F#,16#FF#,16#E1#,16#C0#,16#C0#,16#C0#,16#C0#,16#C0#,16#E0#,16#60#,16#70#,16#38#,16#38#, -- 7. row + 16#1E#,16#0F#,16#03#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 7. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 7. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 7. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 8. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 8. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#01#,16#01#, -- 8. row + 16#01#,16#03#,16#03#,16#07#,16#07#,16#0E#,16#18#,16#18#,16#38#,16#30#,16#30#,16#30#,16#30#,16#30#,16#30#,16#30#, -- 8. row + 16#38#,16#18#,16#1C#,16#1E#,16#0F#,16#07#,16#03#,16#03#,16#01#,16#01#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 8. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 8. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#, -- 8. row + 16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00#,16#00# -- 8. row + ); + + + -- lcd init values + lcd_init_data : constant byte_array := ( + 16#a0#, -- cmd8: adc select + 16#c0#, -- cmd15: shl select + 16#a3#, -- cmd11: lcd bias set + 16#2c#, -- cmd16: power control set (vc=1, vr=0, vf=0) + 16#2e#, -- cmd16: power control set (vc=1, vr=1, vf=0) + 16#2f#, -- cmd16: power control set (vc=1, vr=1, vf=1) + 16#26#, -- cmd17: regulator resistor select + 16#60#, -- cmd2: display start line + 16#a6#, -- cmd6: display normal + 16#c8#, -- cmd15: common output mode select (reversed) + 16#af#, -- cmd1: display on + 16#a4#, -- cmd10: all points off + 16#81#, -- cmd18: set volume 1st + 16#18# -- cmd18: set volume 2nd (brightness) + ); + + + -- pin definitions + LCD_CS : constant Interfaces.C.unsigned_char := 24; + LCD_RST : constant Interfaces.C.unsigned_char := 23; + LCD_A0 : constant Interfaces.C.unsigned_char := 22; + LCD_CLK : constant Interfaces.C.unsigned_char := 27; + LCD_SI : constant Interfaces.C.unsigned_char := 17; + + + -- procedures declarations + procedure io_init; + procedure lcd_init; + procedure lcd_ascii57_string (xpos : natural; ypos : natural; data : string); + procedure lcd_ascii57 (xpos : natural; ypos : natural; data : character); + procedure lcd_picture (xpos : natural; ypos: natural); + procedure lcd_clear; + procedure lcd_set_page (page : natural; column : natural); + procedure lcd_transfer_data (value : byte; si : boolean); + procedure lcd_byte (data : byte); + + +end RaspiLcd; \ No newline at end of file diff --git a/st7565-lcd/ada/raspitest.adb b/st7565-lcd/ada/raspitest.adb new file mode 100644 index 0000000..6e4b226 --- /dev/null +++ b/st7565-lcd/ada/raspitest.adb @@ -0,0 +1,44 @@ +with Ada.Text_IO; +with bcm2835_h; +with RaspiLcd; + + + +procedure raspitest is + + + package IO renames Ada.Text_IO; + package LCD renames RaspiLcd; + + +begin + + + if integer(bcm2835_h.bcm2835_init) = 0 then + + IO.Put_Line("Error while initializing BCM2835 library"); + + else + + LCD.io_init; + + LCD.lcd_init; + + LCD.lcd_picture(xpos => 0, ypos => 0); + + bcm2835_h.bcm2835_delay(5000); + + LCD.lcd_clear; + + LCD.lcd_ascii57_string(xpos => 0, ypos => 0, data => "raspiFPGA 0.1"); + LCD.lcd_ascii57_string(xpos => 0, ypos => 1, data => "(c) raspiDEV 2013"); + + -- close library + if integer(bcm2835_h.bcm2835_close) = 0 then + IO.Put_Line("Error while closing BCM2835 library"); + end if; + + end if; + + +end raspitest; \ No newline at end of file diff --git a/st7565-lcd/ada/stdint_h.ads b/st7565-lcd/ada/stdint_h.ads new file mode 100644 index 0000000..73396a1 --- /dev/null +++ b/st7565-lcd/ada/stdint_h.ads @@ -0,0 +1,122 @@ +with Interfaces.C; use Interfaces.C; +with Interfaces.C.Extensions; + +package stdint_h is + + -- Copyright (C) 1997,1998,1999,2000,2001,2006 Free Software Foundation, Inc. + -- This file is part of the GNU C Library. + -- The GNU C Library is free software; you can redistribute it and/or + -- modify it under the terms of the GNU Lesser General Public + -- License as published by the Free Software Foundation; either + -- version 2.1 of the License, or (at your option) any later version. + -- The GNU C Library is distributed in the hope that it will be useful, + -- but WITHOUT ANY WARRANTY; without even the implied warranty of + -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + -- Lesser General Public License for more details. + -- You should have received a copy of the GNU Lesser General Public + -- License along with the GNU C Library; if not, write to the Free + -- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + -- 02111-1307 USA. + + -- * ISO C99: 7.18 Integer types + -- + + -- Exact integral types. + -- Signed. + -- There is some amount of overlap with as known by inet code + subtype int8_t is signed_char; -- /usr/include/stdint.h:37 + + subtype int16_t is short; -- /usr/include/stdint.h:38 + + subtype int32_t is int; -- /usr/include/stdint.h:39 + + subtype int64_t is Long_Long_Integer; -- /usr/include/stdint.h:44 + + -- Unsigned. + subtype uint8_t is unsigned_char; -- /usr/include/stdint.h:49 + + subtype uint16_t is unsigned_short; -- /usr/include/stdint.h:50 + + subtype uint32_t is unsigned; -- /usr/include/stdint.h:52 + + subtype uint64_t is Extensions.unsigned_long_long; -- /usr/include/stdint.h:59 + + -- Small types. + -- Signed. + subtype int_least8_t is signed_char; -- /usr/include/stdint.h:66 + + subtype int_least16_t is short; -- /usr/include/stdint.h:67 + + subtype int_least32_t is int; -- /usr/include/stdint.h:68 + + subtype int_least64_t is Long_Long_Integer; -- /usr/include/stdint.h:73 + + -- Unsigned. + subtype uint_least8_t is unsigned_char; -- /usr/include/stdint.h:77 + + subtype uint_least16_t is unsigned_short; -- /usr/include/stdint.h:78 + + subtype uint_least32_t is unsigned; -- /usr/include/stdint.h:79 + + subtype uint_least64_t is Extensions.unsigned_long_long; -- /usr/include/stdint.h:84 + + -- Fast types. + -- Signed. + subtype int_fast8_t is signed_char; -- /usr/include/stdint.h:91 + + subtype int_fast16_t is int; -- /usr/include/stdint.h:97 + + subtype int_fast32_t is int; -- /usr/include/stdint.h:98 + + subtype int_fast64_t is Long_Long_Integer; -- /usr/include/stdint.h:100 + + -- Unsigned. + subtype uint_fast8_t is unsigned_char; -- /usr/include/stdint.h:104 + + subtype uint_fast16_t is unsigned; -- /usr/include/stdint.h:110 + + subtype uint_fast32_t is unsigned; -- /usr/include/stdint.h:111 + + subtype uint_fast64_t is Extensions.unsigned_long_long; -- /usr/include/stdint.h:113 + + -- Types for `void *' pointers. + subtype intptr_t is int; -- /usr/include/stdint.h:126 + + subtype uintptr_t is unsigned; -- /usr/include/stdint.h:129 + + -- Largest integral types. + subtype intmax_t is Long_Long_Integer; -- /usr/include/stdint.h:139 + + subtype uintmax_t is Extensions.unsigned_long_long; -- /usr/include/stdint.h:141 + + -- The ISO C99 standard specifies that in C++ implementations these + -- macros should only be defined if explicitly requested. + + -- Limits of integral types. + -- Minimum of signed integral types. + -- Maximum of signed integral types. + -- Maximum of unsigned integral types. + -- Minimum of signed integral types having a minimum size. + -- Maximum of signed integral types having a minimum size. + -- Maximum of unsigned integral types having a minimum size. + -- Minimum of fast signed integral types having a minimum size. + -- Maximum of fast signed integral types having a minimum size. + -- Maximum of fast unsigned integral types having a minimum size. + -- Values to test for integral types holding `void *' pointer. + -- Minimum for largest signed integral type. + -- Maximum for largest signed integral type. + -- Maximum for largest unsigned integral type. + -- Limits of other integer types. + -- Limits of `ptrdiff_t' type. + -- Limits of `sig_atomic_t'. + -- Limit of `size_t' type. + -- Limits of `wchar_t'. + -- These constants might also be defined in . + -- Limits of `wint_t'. + -- The ISO C99 standard specifies that in C++ implementations these + -- should only be defined if explicitly requested. + + -- Signed. + -- Unsigned. + -- Maximal type. +end stdint_h;