Skip to content

Commit

Permalink
- I2C:
Browse files Browse the repository at this point in the history
	- removes i2c_configure function and corresponding struct
	- adds i2c_set_* functions to set the configuration
- SPI:
	- removes chip enable from configuration struct
	- adds extra function for configuring which chip enable line to use
- PWM:
	- removes pwm channel from configuration struct
	- adds the channel as parameter for pwm_configure
- changes examples according to above changes
- minor changes in README.md and documentation
  • Loading branch information
jasLogic committed May 24, 2019
1 parent 6a85872 commit 4ef1a19
Show file tree
Hide file tree
Showing 21 changed files with 174 additions and 119 deletions.
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ ACLOCAL_AMFLAGS=-I m4

lib_LTLIBRARIES=libmipea.la
libmipea_la_SOURCES=src/clock_manager.c src/dma.c src/gpio.c src/i2c.c src/mailbox_mod.c src/mipea.c src/peripherals.c src/pwm.c src/spi.c src/timer.c
libmipea_la_LDFLAGS=-version-info 2:0:0
libmipea_la_LDFLAGS=-version-info 2:1:0

pkginclude_HEADERS=src/clock_manager.h src/dma.h src/gpio.h src/i2c.h src/mailbox_mod.h src/mipea.h src/peripherals.h src/pwm.h src/spi.h src/timer.h
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
[![Documentation Status](https://readthedocs.org/projects/mipea/badge/?version=latest)](https://mipea.readthedocs.io/en/latest/?badge=latest)
![GitHub release](https://img.shields.io/github/release/jasLogic/mipea.svg)
![GitHub](https://img.shields.io/github/license/jasLogic/mipea.svg?color=informational)

# mipea

## minimalistic peripheral access for the Raspberry Pi

This library grants easy and fast access to peripherals. The GPIO, PWM and SPI are implemented at the moment.
This library grants easy and fast access to peripherals.

Contributions are welcome, please fork and open a pull request.

If you have successfully used mipea on a Raspberry Pi which is not tested yet, please inform me and I can add it to the list.

**Peripherals Implemented at the moment:**
* GPIO
* PWM
* Using the clock manager
* SPI
* I2C
* Timer
* DMA
* with a modified mailbox

### Goal of this library
The library is very useful for **high-speed and lighweight applications**,
**efficiency** and **total control** on the **hardware level**.
Expand Down Expand Up @@ -104,6 +98,11 @@ more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------
```

### Documentation

Documentation is uploaded to [ReadTheDocs](mipea.readthedocs.io).
You can also build the documentation yourself using `sphinx`.

### Usage

To use a peripheral, for example GPIO, you need to include the corresponding header into your program.
Expand Down
15 changes: 12 additions & 3 deletions doc/clock_manager.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,31 @@ Macros

.. macro:: CLOCK_MANAGER_OFFSET

::

0x101000

This macro defines the offset at which the clock manager registers
are located relative to the peripheral base.
It has the value :code:`0x101000`

.. macro:: CLOCK_MANAGER_SIZE

::

0xA4

This macro holds the size of the clock manager registers
which needs to be mapped.
It has the value :code:`0xA4`

.. macro:: CM_PASSWD

::

0x5A000000

This macro holds the clock manager password. This value must always be
present when writing to a clock manager register
(e.g. by OR with the value).
It has the value :code:`0x5A000000`

Registers
=========
Expand Down
11 changes: 9 additions & 2 deletions doc/gpio.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ Macros

.. macro:: GPIO_OFFSET

::

0x200000

This macro defines the offset at which the GPIO registers are located from
the peripheral base. It has the value :code:`0x200000`
the peripheral base.

.. macro:: GPIO_SIZE

::

0xB0

This macro holds the size of the GPIO registers which needs to be mapped.
It has the value :code:`0xB0`

Registers
=========
Expand Down
64 changes: 25 additions & 39 deletions doc/i2c.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ Macros

.. macro:: I2C_SIZE

::

0x18

This macro holds the size of the I2C registers which needs to be mapped.
It has the value :code:`0x18`

:macro:`I2C_FIFO_SIZE`
:macro:`I2C_C_I2CEN`
Expand Down Expand Up @@ -74,41 +77,6 @@ Registers
By using this macro, the registers of the I2C can be accessed like this
:code:`I2C->FIFO`.

Structs
=======

.. type:: i2c_config_t

This struct is used to configure the I2C controller::

typedef struct {
uint8_t addr: 7;
uint16_t div;
uint16_t clkstr;
} i2c_config_t;

.. member:: uint8_t addr: 7

This member holds the address of the I2C device that should be contacted.
I2C addresses have a length of seven bits.

.. member:: uint16_t div

This member sets the clock divider for the BSC controller.

.. note:: The clock source is the core clock with a frequency, \
according to the Datasheet_, of :code:`150 MHz` and \
according to `this file`_ and other sources of :code:`250 MHz`. \
When I tested the clock speed of I2C and SPI with a logic analyzer, \
it seems that :code:`250 MHz` **is correct** \
(at least for the Raspberry Pi Zero I use).

.. member:: uint16_t clkstr

This member sets the clock stretch timeout (or delay). This means that
the master will wait :code:`clkstr` cycles after the rising clock edge
for the slave to respond. After this the timeout flag is set.

Functions
=========

Expand All @@ -122,10 +90,28 @@ Functions

This function unmaps the I2C registers.

.. function:: void i2c_configure(i2c_config_t *config)
.. function:: void i2c_set_address(uint8_t addr)

This function sets the address of the I2C device to communicate with.
The address is a seven bit value.

.. function:: void i2c_set_clkdiv(uint16_t divisor)

This function sets the clock divisor of the BSC controller.

.. note:: The clock source is the core clock with a frequency, \
according to the Datasheet_, of :code:`150 MHz` and \
according to `this file`_ and other sources of :code:`250 MHz`. \
When I tested the clock speed of I2C and SPI with a logic analyzer, \
it seems that :code:`250 MHz` **is correct** \
(at least for the Raspberry Pi Zero I use).

.. function:: void i2c_set_clkstr(uint16_t clkstr)

This function configures the BSC controller with the :type:`i2c_config_t`
pointed to by :code:`config`.
This function sets the clock stretch timeout (or delay). This means that
the master will wait :code:`clkstr` cycles after the rising clock edge
for the slave to respond. After this the timeout flag is set.
This can often be left at reset value :code:`0x40`.

.. function:: void i2c_start(void)

Expand Down
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ mipea - minimalistic peripheral access library for the Raspberry Pi
i2c.rst
pwm.rst
spi.rst
mipea.rst

gpl.rst
fdl.rst
Expand Down
22 changes: 22 additions & 0 deletions doc/mipea.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.. index::
single: Mipea Wrapper

*************
Mipea Wrapper
*************

The mipea.c / h files are just a wrapper for all the other parts of the library.
If you are lazy (or need all peripherals mapped) than this wrapper is usefull.

Functions
=========

.. function:: int mipea_map(void)

This function maps all the peripherals.

.. function:: void mipea_unmap(void)

This function unmaps all the peripherals.

.. _Datasheet: https://www.raspberrypi.org/documentation/hardware/raspberrypi/bcm2835/BCM2835-ARM-Peripherals.pdf
18 changes: 12 additions & 6 deletions doc/peripherals.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ Macros

.. macro:: PERIPHERAL_BASE_BCM2835

::

0x20000000

This macro holds the value of the peripheral base, when a BCM2835 is used.
It has the value :code:`0x20000000`

.. macro:: PERIPHERAL_BASE_BCM2836_7

::

0x3F000000

This macro holds the value of the peripheral base, when a BCM2836 or
BCM2837 is used. It has the value :code:`0x3F000000`
BCM2837 is used.

Functions
=========
Expand All @@ -29,12 +36,11 @@ Functions
This function maps a code memory block of size :code:`size` at offset
:code:`offset` from the peripheral base.

.. note:: The :code:`offset` must be a multiple of the page size which is \
:code:`4096` on the Raspberry Pi.
.. note:: The :code:`offset` must be a multiple of the page size which is \
:code:`4096` on the Raspberry Pi.


The function returns a pointer
to the mapped memory on success and :code:`NULL` on error.
The function returns a pointer to the mapped memory on success and :code:`NULL` on error.

.. function:: void peripheral_unmap (void* map, uint32_t size)

Expand Down
26 changes: 14 additions & 12 deletions doc/pwm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ Macros

.. macro:: PWM_OFFSET

::

0x20C000

This macro defines the offset at which the PWM registers are located from
the peripheral base. It has the value :code:`0x20C000`
the peripheral base.

.. macro:: PWM_SIZE

::

0x24

This macro holds the size of the I2C registers which needs to be mapped.
It has the value :code:`0x24`

.. macro:: RNG_CHANNEL0
.. macro:: DAT_CHANNEL0
Expand Down Expand Up @@ -71,11 +78,11 @@ Registers
uint32_t CTL;
uint32_t STA;
uint32_t DMAC;
uint32_t: 32; // address not implemented
uint32_t: 32;
uint32_t RNG1;
uint32_t DAT1;
uint32_t FIF1;
uint32_t: 32; // address not implemented
uint32_t: 32;
uint32_t RNG2;
uint32_t DAT2;
};
Expand Down Expand Up @@ -108,7 +115,6 @@ Structs
This struct is used to configure a PWM channel::

typedef struct {
pwm_channel_t channel;
union {
struct {
uint32_t: 1;
Expand All @@ -126,10 +132,6 @@ Structs
uint32_t range;
} pwm_channel_config_t;

.. member:: pwm_channel_t channel

This member specifies the PWM channel to configure.

.. member:: uint32_t ctl_register

This member can be directly edited by the anonymous struct inside
Expand Down Expand Up @@ -157,10 +159,10 @@ Functions

This function unmaps the PWM registers.

.. function:: void pwm_configure(pwm_channel_config_t *config)
.. function:: void pwm_configure(pwm_channel_t channel, pwm_channel_config_t *config)

This function configures a PWM channel with a :type:`pwm_channel_config_t`
pointed to by :code:`config`.
This function configures :type:`pwm_channel_t` :code:`channel` with a
:type:`pwm_channel_config_t` pointed to by :code:`config`.

.. function:: void pwm_enable(pwm_channel_t channel)

Expand Down
18 changes: 15 additions & 3 deletions doc/spi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,20 @@ Macros

.. macro:: SPI_OFFSET

::

0x204000

This macro defines the offset at which the SPI registers are located from
the peripheral base. It has the value :code:`0x204000`
the peripheral base.

.. macro:: SPI_SIZE

::

0x14

This macro holds the size of the I2C registers which needs to be mapped.
It has the value :code:`0x14`

Configuration Macros
--------------------
Expand Down Expand Up @@ -73,7 +80,7 @@ Structs
typedef struct {
union {
struct {
uint32_t cs: 2;
uint32_t: 2;
uint32_t cpha: 1;
uint32_t cpol: 1;
uint32_t: 2;
Expand Down Expand Up @@ -124,6 +131,11 @@ Functions
This function configures SPI with a :type:`spi_channel_config_t`
pointed to by :code:`config`.

.. function:: void spi_set_ce(uint8_t ce)

This function sets which chip enable line the SPI controller should use.
This can be a 3 bit value.

.. function:: void spi_transfer_start(void)

This function starts a SPI transfer.
Expand Down
9 changes: 3 additions & 6 deletions examples/i2c_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,9 @@ main(void)
gpio_func(sda, ALT0);
gpio_func(scl, ALT0);

i2c_config_t conf = {
.addr = 0x6a, // address
.div = 4000, // clock divider -> clk must be < 100kHz for gyro
.clkstr = 0x40 // standard reset value
};
i2c_configure(&conf);
i2c_set_address(0x6a); // set address
i2c_set_clkdiv(4000); // clock divider -> clk must be < 100kHz for gyro
i2c_set_clkstr(0x40); // can often be ignored and left on reset value

i2c_start(); // start i2c

Expand Down
Loading

0 comments on commit 4ef1a19

Please sign in to comment.