From 9439c6f1caffd938673018f3af7460b33a12528e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karel=20Ko=C4=8D=C3=AD?= Date: Sun, 20 Mar 2016 16:39:30 +0100 Subject: Another work progress --- docs/parts/ioport.md | 167 +++++++++++++++++++++++++++++++++++++++++++++ docs/parts/jobs.md | 15 ++++ docs/parts/spi.md | 80 ++++++++++++++++++++++ docs/parts/tasks.md | 38 +++++++++++ docs/parts/timer.md | 0 docs/parts/usart.md | 23 +++++++ docs/parts/utils/buffer.md | 105 ++++++++++++++++++++++++++++ docs/parts/utils/narray.md | 64 +++++++++++++++++ 8 files changed, 492 insertions(+) create mode 100644 docs/parts/ioport.md create mode 100644 docs/parts/jobs.md create mode 100644 docs/parts/spi.md create mode 100644 docs/parts/tasks.md create mode 100644 docs/parts/timer.md create mode 100644 docs/parts/usart.md create mode 100644 docs/parts/utils/buffer.md create mode 100644 docs/parts/utils/narray.md (limited to 'docs/parts') diff --git a/docs/parts/ioport.md b/docs/parts/ioport.md new file mode 100644 index 0000000..96a4b82 --- /dev/null +++ b/docs/parts/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/parts/jobs.md b/docs/parts/jobs.md new file mode 100644 index 0000000..878a557 --- /dev/null +++ b/docs/parts/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/parts/spi.md b/docs/parts/spi.md new file mode 100644 index 0000000..f63d304 --- /dev/null +++ b/docs/parts/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/parts/tasks.md b/docs/parts/tasks.md new file mode 100644 index 0000000..e4f71df --- /dev/null +++ b/docs/parts/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/parts/timer.md b/docs/parts/timer.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/parts/usart.md b/docs/parts/usart.md new file mode 100644 index 0000000..22e54ab --- /dev/null +++ b/docs/parts/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/parts/utils/buffer.md b/docs/parts/utils/buffer.md new file mode 100644 index 0000000..4365c25 --- /dev/null +++ b/docs/parts/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/parts/utils/narray.md b/docs/parts/utils/narray.md new file mode 100644 index 0000000..3e64f67 --- /dev/null +++ b/docs/parts/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