From 4e1ce86af16307bf7d42657db07600867c7c4bbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Thu, 30 Jun 2016 17:18:49 +0200 Subject: Add some more progress and split non-core functionality to separate repo More progress to implementation and some changes in project it self. This library will implement only drivers for features on chip but nothing else. Everything connected externally is now in separate repository. --- docs/references/ioport.md | 167 ++++++++++++++++++++++++++++++++++++++++ docs/references/jobs.md | 15 ++++ docs/references/spi.md | 80 +++++++++++++++++++ docs/references/tasks.md | 38 +++++++++ docs/references/timer.md | 0 docs/references/usart.md | 23 ++++++ docs/references/utils/buffer.md | 105 +++++++++++++++++++++++++ docs/references/utils/narray.md | 64 +++++++++++++++ 8 files changed, 492 insertions(+) create mode 100644 docs/references/ioport.md create mode 100644 docs/references/jobs.md create mode 100644 docs/references/spi.md create mode 100644 docs/references/tasks.md create mode 100644 docs/references/timer.md create mode 100644 docs/references/usart.md create mode 100644 docs/references/utils/buffer.md create mode 100644 docs/references/utils/narray.md (limited to 'docs/references') diff --git a/docs/references/ioport.md b/docs/references/ioport.md new file mode 100644 index 0000000..96a4b82 --- /dev/null +++ b/docs/references/ioport.md @@ -0,0 +1,167 @@ +IO port +======= +And define: `CONFIG_IOE_IOPORT` + +Defines simple access to io ports. This allows runtime access to any pin with just +serialized identifier. + +Most of the functions has group and mask arguments. Group is letter, but in this +library is represented as number and exact number is defined as macro definition. +Mask is one shifted by index number(use \_BV macro). This way can be +addressed all IO ports. Exact identification consult with datasheet. You can also +use more than one index number and control more ports in single group with single +command. + +WARNING: No check is implemented for right group number. Usage of unsupported +value is undefined (write to other parts of memory can happen). + +Configuration +------------- +To use this part, you must enable `CONFIG_IOPORTS` option. +This part also handles pin change interrupts. Enable it using +`CONFIG_IOPORTS_PCINT` option. + +References +---------- +### For output +#### Function io_setout +```C +static inline void io_setout(uint8_t group, uint8_t mask) +``` +Configures port of `group` with `mask` as output. +Parameters: +__group__ - Character specifying exact port group +__mask__ - Binary shifted 1. Shift is equal to port index in specified group. + +#### Function io_hight +```C +static inline void io_hight(uint8_t group, uint8_t mask) +``` +Sets output port to hight (also can be called as 1). +WARNING: Invoke this only if io_setout is called before. + +Parameters: +__group__ - Character specifying exact port group +__mask__ - Binary shifted 1. Shift is equal to port index in specified group. + +#### Function io_low +```C +static inline void io_low(uint8_t group, uint8_t mask) +``` +Sets output port to low (also called as 0). +WARNING: Invoke this only if io_setout is called before. + +Parameters: +__group__ - Number specifying exact port group +__mask__ - Binary shifted 1. Shift is equal to port index in specified group. + +#### Function io_set +```C +static inline void io_set(uint8_t group, uint8_t mask, int8_t val) +``` +Sets output port to value passed as argument. +WARNING: Invoke this only if io_setout is called before. +Parameters: +__group__ - Number specifying exact port group +__mask__ - Binary shifted 1. Shift is equal to port index in specified group. + +### For input +#### Function io_setin +```C +static inline void io_setin(uint8_t group, uint8_t mask, + enum ioeIOInResistor resistor) +``` +Configures port of `group` with `mask` as input with specified pull-up/down +resistor. + +Parameters: +__group__ - Number specifying exact port group +__mask__ - Binary shifted 1. Shift is equal to port index in specified group. + +#### Function io_get +```C +static inline int8_t io_get(uint8_t group, uint8_t mask) +``` +Returns current value of port. Note that you can use this also if port is +configured as output. + +Parameters: +__group__ - Number specifying exact port group +__mask__ - Binary shifted 1. Shift is equal to port index in specified group. + +#### Enum ioeIOInResistor +```C +enum ioeIOInResistor { + IOE_IO_PULLUP, + IOE_IO_PULLDOWN +}; +``` +This enum is used as argument for io_setin. Names should be self explanatory +in this case. + +### Pin change interrupts +#### Function io_change_sethook +```C +int8_t io_change_sethook(uint8_t group, uint8_t mask, uint8_t edge, + void (*change) (uint8_t group, uint8_t mask)) +``` +Registers function `change` as hook for pin change interrupt. `group` and `mask` +specifies port and edge specifies on what edge should hook be called. `edge` can +be IO_RISING or IO_FALLING or their binary combination with operator +`|`. +WARNING: `change` call is call during interrupt handling. You shouldn't be +blocking execution for long time. + +Parameters: +__group__ - Number specifying exact port group. +__mask__ - Binary shifted 1. Shift is equal to port index in specified group. +__edge__ - Signals on what edge should be hook called. +__change__ - Pointer to function used as interupt hook. + +#### Function io_change_remhook +```C +int8_t io_change_remhook(void (*change) (uint8_t group, uint8_t mask)) +``` +Removes `change` hook. + +Parameters: +__change__ - Pointer to function used as hook + +### Others +#### Definitions IO_{GROUP} +This defines exact numbers related to data-sheet groups. Always use these +definition not direct numbers, you can ensure cross MCU support this way. + +#### Definitions IO_{GROUP}{INDEX} +Because specifying group and mask as separate parameters is not always optimal, +mcu support file should define all ports in form of single line definition in +format `IOE_IO_{GROUP}{INDEX}`. Disadvantage is that with these definitions you +can't use binary conjunction and so only one pin can be controlled with it. + +Relevant examples +----------------- +* blink +* pcinterrupt + +Adding support +-------------- +For more information on how add support, see [Adding MCU support](/add_support.md). +Main definition is `MCUSUPPORT_IOPORT`. Define it to enable support. + +### IO_{GROUP} +This should define any number that is handy for implementation of `IOE_IOE_PIN`, +`IOE_IO_DDR` and `IOE_IO_PORT`. + +### IO_{PIN/DDR/PORT} +These should calculate exact pointers to register `PORT{GROUP}` for PORT variant +and likewise for others with group as argument. Common implementation would be +like this: +```C +#define IOE_IO_PIN(GROUP) (* (volatile uint8_t *)(PINB + 0x3*GROUP)) +``` +### IO_{GROUP}{INDEX} +This should be pair of group and one binary shifted to left relative to index. + +### MCUSUPPORT_PCINT{NUM} +This defines that MCU supports specific pin change interrupt group. Also it +defines value that is number of pins in group. diff --git a/docs/references/jobs.md b/docs/references/jobs.md new file mode 100644 index 0000000..878a557 --- /dev/null +++ b/docs/references/jobs.md @@ -0,0 +1,15 @@ +Jobs +==== +Jobs allows periodic execution of different short functions. It is designed to host +control loops. So called functions should be short. + +Every job must specify deadline and if not set otherwise also its duration. + +If tasks support is enabled jobs can be also executed on multiple tasks, which is +handy if you divide sensor reading and control algorithm, because control +algorithm can than run when for example mcu waiting for response from sensor. +Always be sure that jobs are running on tasks with highest priority, otherwise +deadlines might not be fulfilled every time. + +Be aware of taking mutexes and semaphores. It can sometime result in long task +suspension and that would result to deadline misses. diff --git a/docs/references/spi.md b/docs/references/spi.md new file mode 100644 index 0000000..f63d304 --- /dev/null +++ b/docs/references/spi.md @@ -0,0 +1,80 @@ +Serial peripheral interface +=========================== +To use include: `spi.h` +This interface is link to MOSI and MISO pins. Also SS pin is used when slave mode +initialized. + +Configuration +------------- +To use SPI you must enable `CONFIG_SPI` configuration symbol. + +References +---------- +### Function spi\_init +```C +static inline void spi_init(enum spiMode mode) +``` +Initializes SPI interface. +Parameters: + mode - Specify mode of SPI interface + +NOTE: Global interrupts must be enabled for right function of SPI. + +### Function spi\_busy +```C +static inline int8_t spi_busy(void) +``` +Returns NULL when device is not busy. +When device is busy return values in non-zero. + +### Function spi\_join +```C +static inline void spi_join(void) +``` +Blocks processor until device is not busy. + +### Function spi\_send +```C +static inline uint8_t spi_send(uint8_t data) +``` +Swap bytes with slave over SPI. +This function blocks execution until device isn't busy (transfer completed). +WARNING: Invoke this only when interface is initialized in MASTER mode. + +### Function spi\_transfer +```C +static inline void spi_transfer(uint8_t data) +``` +Transfer byte to slave over SPI. +This function isn't blocking execution until transfer is complete. +Always call spi\_join before this function when called outside of spi\_receive(). +WARNING: Invoke this only when interface is initialized in MASTER mode. + +### Function spi\_expose +```C +static inline void spi_expose(uint8_t data) +``` +Expose data for next master request. +Please don't use this when device is busy. +Best place to call this is spi\_receive(). +WARNING: Invoke this only when interface is initialized in SLAVE mode. + +### Function pointer spi\_receive +```C +extern void (*spi_receive)(uint8_t data) +``` +This function is called every time transfer is finished. +And until return from this function interrupts are disabled. + +### Enum spiMode +```C +enum spiMode { + SPI_MODE_MASTER, + SPI_MODE_SLAVE +}; +``` +This is used as parameter for spi\_init function. + +Relevant examples +----------------- +* spiblink diff --git a/docs/references/tasks.md b/docs/references/tasks.md new file mode 100644 index 0000000..e4f71df --- /dev/null +++ b/docs/references/tasks.md @@ -0,0 +1,38 @@ +Tasks +===== +Tasks can be used for sharing processor for example during period of waiting for +interrupt. Planing is based on priority. + +## Functions +### tasks_run +```C +int8_t tasks_run(void) +``` +This function starts tasks execution. Should be called after all task slots are +prepared and at least one task is started. This function exits if no task exist or +all existing tasks exited. + +### task_init + +## Structures +### Task +```C +typedef struct { + uint8_t flags; + void (*func) (void); +} Task; +``` + +### TaskSlot +```C +typedef struct { + uint8_t flags; + Task *task; + uint8_t stack_size; + uint8_t stack[]; +} TaskSlot; +``` + +### Mutex + +### Semaphore diff --git a/docs/references/timer.md b/docs/references/timer.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/references/usart.md b/docs/references/usart.md new file mode 100644 index 0000000..22e54ab --- /dev/null +++ b/docs/references/usart.md @@ -0,0 +1,23 @@ +Universal synchronous/asynchronous receive/transmitter +====================================================== +This part acts as UART intended as text base interface with computer. It is +using hardware termed as USART by Atmel. This hardware also supports synchronous +communication and can behave as SPI master, but this is not supported by this +library (I don't require this feature, but implementation is welcomed). + +This part implements, if enabled, whole stack for binding input and output to +stdin and stdout. This is handy during development. You can use `printf` and +`scanf` directly. + +This part can be enabled by `CONFIG_USART` configuration option. This enables +more detailed configuration in sub-menu. + +## Usage + + +## References +### usart_init_async +```C +void usart_init_async(void) +``` + diff --git a/docs/references/utils/buffer.md b/docs/references/utils/buffer.md new file mode 100644 index 0000000..4365c25 --- /dev/null +++ b/docs/references/utils/buffer.md @@ -0,0 +1,105 @@ +buffer +====== +In whole project are used ring buffers. This is so common that handling them is +exported to separated header file. In fact it contains two implementations of +buffers. One implementation is defined using preprocessor macros. Another one is +plain C code. + +## Preprocessor implementation +Preprocessor implementation is expected to be faster and less memory intense. Also +more suitable for buffers of simple types (such us int). But this buffer has to be +defined with known size at compile time and can't be resized. All this makes it +good implementation for IO devices input and output buffers, but less for more +complicated tasks containing for example sorting. + +### Macros +#### IOEBUFFER +```C +IOEBUFFER(type, name, size) +``` +This macro defines buffer. Use it to define new buffer. +##### Parameters +| type | Specify type of elements in buffer. Can be any valid C type | +| name | Name of buffer. This is C variable name. | +| size | Numerical value of buffer size | + +#### IOEBUFFER_INIT +```C +IOEBUFFER_INIT(name, size) +``` +Use this to initialize buffer. Parameter `size` must be same as for IOEBUFFER +(definition of buffer). You can use this also to reset buffer (remove all data +from buffer). +##### Parameters +| name | Name if buffer. This is C variable name. | +| size | Numerical value of buffer size | + +#### IOEBUFFER_PUT +```C +IOEBUFFER_PUT(name, size, data, mode) +``` +Use this macro to add new data to buffer. +##### Parameters +| name | Name of buffer. This is C variable name. | +| size | Numerical value of buffer size | +| data | Data to be stored to buffer | +| mode | This specifies action if buffer is full. | +##### Modes +| IOEBUFFER_MODE_BLOCK | Block execution until buffer has some free space. | +| IOEBUFFER_MODE_OVERWRITE | Overwrites oldest added (fist to be read) | +| IOEBUFFER_MODE_DROP | New data won't be stored to buffer if full | + +#### IOEBUFFER_GET +```C +IOEBUFFER_GET(name, size, variable) +``` +Get value from buffer. Value is stored in `variable` (it is variable of same type +as buffer data, not pointer to variable of same type). If no data is in buffer, +variable is set to NULL. +##### Parameters +| name | Name of buffer. This is C variable name. | +| size | Numerical value of buffer size. | +| variable | Variable in which data will be stored in. | + +#### IOEBUFFER_CNT +```C +IOEBUFFER_CNT(name, size, variable) +``` +Counts number of data entries in buffer and saves value to variable. +##### Parameters +| name | Name of buffer. This is C variable name. | +| size | Numerical value of buffer size. | +| variable | Int/Unsigned type variable where data count will be stored. | + +## C implementation +C implementation is more general. Size is defined by calling initialization +function. But it is using general pointers, so it is only able store pointers. + +As buffer identification is used defined type `IOEBuffer`. All functions takes +pointer to this type as parameter. Because of this, it won't be described for +every function. + +### Functions +#### ioebuffer_init +```C +int8_t ioebuffer_init(IOEBuffer *buf, uint8_t size, uint8_t flags) +``` +Initialized buffer and allocates required resources. +##### Parameters +| size | Number of elements to be maximally stored in buffer | +| flags | TODO +##### Flags +TODO + +#### ioebuffer_uninit +```C +void ioebuffer_uninit(IOEBuffer *buf) +``` +Frees all resources allocated during initialization of buffer. Use this every time +you are freeing buffer. + +#### ioebuffer_put +```C +int8_t ioebuffer_put(IOEBuffer *buf, void *data) +``` +Add `data` to buffer diff --git a/docs/references/utils/narray.md b/docs/references/utils/narray.md new file mode 100644 index 0000000..3e64f67 --- /dev/null +++ b/docs/references/utils/narray.md @@ -0,0 +1,64 @@ +narray.h +======== +This implements some helping functions for null terminated arrays. Null terminated +arrays are used across whole project because they are simple and don't waste +memory space. Their disadvantage is more complicated implementation of utility +functions and much longer adding time (they are reallocated every time new data +are added). + +This implementation is limited to only contains 255 elements(limited by uint8_t +type). But it should be enough for basic usage. If you need store more than that, +you should use different approach. Also only pointers can be stored. + +To define null terminated array just define pointer to you required pointer and set +it to NULL. Such narray is handled as empty. Example: +```C +int **narray = 0; +``` +After adding some data (in example case data of type `int*`) you can access them +same as if you would working with simple array (`narray[i]`). Last element it such +array is `NULL`. No more valid data are stored after `NULL` (This also means that +`NULL` can't be stored to narray). + +All functions are taking as parameter `void ***array`, which is pointer to null +terminated array. This parameter won't be described in functions. + +## Functions and macros +### narray_add +```C +void narray_add(void ***array, void *data) +``` +Add data to end of the array. This increases size of the array by one (two bytes). +#### Parameters +| data | data to be stored to array | + +### narray_remove +```C +void narray_remove(void ***array, void *data) +``` +Remove specified data from array. This effectively decreases size of the array by +one (two bytes). +#### Parameters +| data | data to be removed from array | + +### narray_size +```C +size_t narray_size(void ***array) +``` +Returns size of array. + +### narray_free +```C +inline void narray_free(void ***array) +``` +Frees whole array if allocated. + +### fornarray +```C +#define fornarray(array, i, data) for (i = 0; (data = array[i]) != 0; i++) +``` +This is macro. It implements simple foreach cycle. +#### Parameters +| array | array it self (void ** not pointer) | +| i | unsigned integer (uint8_t) | +| data | variable which will be used to access data | -- cgit v1.2.3