Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Matej
committed
Feb 3, 2014
0 parents
commit 80fd9df
Showing
22 changed files
with
1,876 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
// ------------------------------------------------------------------ | ||
// --- circbuf.c - circular buffer routines --- | ||
// --- --- | ||
// --- 7.nov.2010, Matej Kogovsek (matej@hamradio.si) --- | ||
// ------------------------------------------------------------------ | ||
|
||
#include "stm32f10x.h" | ||
#include "circbuf8.h" | ||
|
||
// ------------------------------------------------------------------ | ||
// initializes (clears) circ buf | ||
|
||
void cbuf8_clear(volatile struct cbuf8_t* cb, uint8_t* const p, const uint16_t s) | ||
{ | ||
uint32_t g = __get_PRIMASK(); | ||
__disable_irq(); | ||
|
||
cb->buf = p; | ||
cb->size = s; | ||
cb->head = 0; | ||
cb->tail = 0; | ||
cb->len = 0; | ||
|
||
__set_PRIMASK(g); | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
// inserts an element | ||
|
||
uint8_t cbuf8_put(volatile struct cbuf8_t* cb, const uint8_t d) | ||
{ | ||
uint32_t g = __get_PRIMASK(); | ||
__disable_irq(); | ||
|
||
if (cb->len == cb->size) { | ||
__set_PRIMASK(g); | ||
return 0; | ||
} | ||
|
||
cb->buf[cb->tail] = d; | ||
cb->tail++; | ||
if(cb->tail == cb->size) { cb->tail = 0; } | ||
cb->len++; | ||
|
||
__set_PRIMASK(g); | ||
return 1; | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
// gets the next element | ||
|
||
uint8_t cbuf8_get(volatile struct cbuf8_t* cb, uint8_t* const d) | ||
{ | ||
uint32_t g = __get_PRIMASK(); | ||
__disable_irq(); | ||
|
||
if (cb->len == 0) { | ||
__set_PRIMASK(g); | ||
return 0; | ||
} | ||
|
||
if( d ) { // if d is null, cbuf_get can be used to check for data in buffer | ||
*d = cb->buf[cb->head]; | ||
cb->head++; | ||
if(cb->head == cb->size) { cb->head = 0; } | ||
cb->len--; | ||
} | ||
|
||
__set_PRIMASK(g); | ||
return 1; | ||
} | ||
|
||
// ------------------------------------------------------------------ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// ------------------------------------------------------------------ | ||
// --- circbuf.c - circular buffer routines --- | ||
// --- --- | ||
// --- 7.nov.2010, Matej Kogovsek (matej@hamradio.si) --- | ||
// ------------------------------------------------------------------ | ||
|
||
#ifndef MAT_CIRCBUF8_H | ||
#define MAT_CIRCBUF8_H | ||
|
||
#include <inttypes.h> | ||
|
||
struct cbuf8_t | ||
{ | ||
uint8_t* buf; | ||
uint16_t head; | ||
uint16_t tail; | ||
uint16_t len; | ||
uint16_t size; | ||
}; | ||
|
||
void cbuf8_clear(volatile struct cbuf8_t* cb, uint8_t* const p, const uint16_t s); | ||
uint8_t cbuf8_put(volatile struct cbuf8_t* cb, const uint8_t d); | ||
uint8_t cbuf8_get(volatile struct cbuf8_t* cb, uint8_t* const d); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
// ------------------------------------------------------------------ | ||
// --- cmt.c --- | ||
// --- simple cooperative "on-delay" multitasking --- | ||
// --- 15.dec.2013, Matej Kogovsek --- | ||
// ------------------------------------------------------------------ | ||
|
||
#include "stm32f10x.h" | ||
|
||
#include "cmt.h" | ||
|
||
volatile uint8_t cmt_curtask = 0; | ||
volatile struct cmt_task cmt_tasks[CMT_MAXTASKS]; | ||
volatile uint8_t cmt_numtasks = 1; | ||
|
||
// ------------------------------------------------------------------ | ||
// task switching is done here | ||
// this should not be called with interrupts disabled | ||
void cmt_delay_ticks(uint32_t d) | ||
{ | ||
asm("push {r4-r11}\n"); // push all registers not saved by the caller | ||
|
||
__disable_irq(); | ||
cmt_tasks[cmt_curtask].sp = __get_MSP(); // remember current task's SP | ||
cmt_tasks[cmt_curtask].d = d; // and how long it wishes to sleep | ||
__enable_irq(); | ||
|
||
uint8_t i = cmt_curtask; | ||
while( 1 ) { | ||
//wdt_reset(); | ||
i = (i + 1) % cmt_numtasks; | ||
if( 0 == cmt_tasks[i].d ) { break; } // found ready to run task | ||
} | ||
|
||
__disable_irq(); | ||
cmt_curtask = i; | ||
__set_MSP(cmt_tasks[i].sp); // restore task's stack pointer | ||
__enable_irq(); | ||
|
||
uint32_t tp = cmt_tasks[i].tp; | ||
if( tp ) { // if this is the first time the task | ||
cmt_tasks[i].tp = 0; // is run, jump to task proc directly | ||
asm("bx %0\n"::"r" (tp):); | ||
} | ||
|
||
asm("pop {r4-r11}\n"); | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
// setup task, call this to setup all tasks | ||
uint8_t cmt_setup_task(void (*task_proc)(void), uint32_t task_sp) | ||
{ | ||
cmt_tasks[0].minsp = -1; // should be in cmt_init, but can as well be here | ||
cmt_tasks[0].tp = 0; | ||
|
||
if( cmt_numtasks >= CMT_MAXTASKS ) return 0; | ||
|
||
cmt_tasks[cmt_numtasks].sp = task_sp; | ||
cmt_tasks[cmt_numtasks].tp = 1|(uint32_t)task_proc; | ||
cmt_tasks[cmt_numtasks].d = 0; // ready to run | ||
cmt_tasks[cmt_numtasks].minsp = -1; | ||
|
||
return ++cmt_numtasks; | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
// should be called by a timer interrupt | ||
void cmt_tick(void) | ||
{ | ||
// keep track of current task's min SP | ||
if( __get_MSP() < cmt_tasks[cmt_curtask].minsp ) { | ||
cmt_tasks[cmt_curtask].minsp = __get_MSP(); | ||
} | ||
|
||
// decrease all tasks' delay count | ||
uint8_t i; | ||
for( i = 0; i < cmt_numtasks; i++ ) { | ||
if( cmt_tasks[i].d ) { | ||
cmt_tasks[i].d--; | ||
} | ||
} | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
// returns the task's minimal detected stack pointer | ||
uint32_t cmt_minsp(uint8_t task_num) | ||
{ | ||
if( task_num < cmt_numtasks ) { | ||
return cmt_tasks[task_num].minsp; | ||
} | ||
return 0; | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
// tries to acquire mutex | ||
uint8_t cmt_try_acquire(struct cmt_mutex* m) | ||
{ | ||
if( (m->ot == cmt_curtask) || (m->ac == 0) ) { | ||
m->ot = cmt_curtask; | ||
m->ac++; | ||
return 1; | ||
} | ||
return 0; | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
// waits until mutex acquired | ||
void cmt_acquire(struct cmt_mutex* m) | ||
{ | ||
while( !cmt_try_acquire(m) ) { | ||
cmt_delay_ticks(0); | ||
} | ||
} | ||
|
||
// ------------------------------------------------------------------ | ||
// releases mutex | ||
void cmt_release(struct cmt_mutex* m) | ||
{ | ||
if( (m->ot == cmt_curtask) && (m->ac > 0) ) { | ||
m->ac--; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// ------------------------------------------------------------------ | ||
// --- cmt.c --- | ||
// --- simple cooperative "on-sleep" multitasking --- | ||
// --- 8.mar.2011, Matej Kogovsek --- | ||
// ------------------------------------------------------------------ | ||
|
||
#ifndef MAT_CMT_H | ||
#define MAT_CMT_H | ||
|
||
#include <inttypes.h> | ||
|
||
#define CMT_MAXTASKS 5 | ||
|
||
struct cmt_task | ||
{ | ||
uint32_t sp; // stack pointer | ||
uint32_t tp; // task proc | ||
uint32_t d; // ticks left to sleep | ||
uint32_t minsp; // min detected task's SP | ||
}; | ||
|
||
struct cmt_mutex | ||
{ | ||
uint8_t ot; // owning task | ||
uint8_t ac; // acquire count | ||
}; | ||
|
||
void cmt_delay_ticks(uint32_t d); | ||
uint8_t cmt_setup_task(void (*task_proc)(void), uint32_t task_sp); | ||
void cmt_tick(void); | ||
uint32_t cmt_minsp(uint8_t task_num); | ||
|
||
uint8_t cmt_try_acquire(struct cmt_mutex* m); | ||
void cmt_acquire(struct cmt_mutex* m); | ||
void cmt_release(struct cmt_mutex* m); | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
|
||
#include "stm32f10x.h" | ||
#include "i2c.h" | ||
#include "hmc5883l.h" | ||
#include <math.h> | ||
|
||
const uint8_t HMC_I2C_ADDR = 0x3c; | ||
|
||
uint8_t hmc_init(uint8_t cra, uint8_t crb, uint8_t mode) | ||
{ | ||
uint8_t b[4] = {0, cra, crb, mode}; | ||
|
||
return i2c_wr(I2C1, b, 4, HMC_I2C_ADDR); | ||
} | ||
|
||
uint8_t hmc_read(int16_t* x, int16_t* y, int16_t* z) | ||
{ | ||
uint8_t b[6] = {3}; | ||
|
||
if( i2c_wr(I2C1, b, 1, HMC_I2C_ADDR) ) { return 1; } | ||
|
||
if( i2c_rd(I2C1, b, 6, HMC_I2C_ADDR) ) { return 1; } | ||
|
||
*x = (((int16_t)b[0]) << 8) | b[1]; | ||
*z = (((int16_t)b[2]) << 8) | b[3]; | ||
*y = (((int16_t)b[4]) << 8) | b[5]; | ||
|
||
return 0; | ||
} | ||
|
||
float hmc_heading(int16_t x, int16_t y) | ||
{ | ||
float heading = atan2(y, x); | ||
|
||
if( heading < 0 ) { heading += 2 * M_PI; } | ||
|
||
return heading * 180 / M_PI; | ||
} | ||
|
||
bool hmc_present(void) | ||
{ | ||
uint8_t b[3] = {10}; | ||
|
||
if( i2c_wr(I2C1, b, 1, HMC_I2C_ADDR) ) { return false; } | ||
|
||
if( i2c_rd(I2C1, b, 3, HMC_I2C_ADDR) ) { return false; } | ||
|
||
return (b[0] == 'H') && (b[1] == '4') && (b[2] == '3'); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
|
||
#ifndef HMC8883L_H | ||
#define HMC8883L_H | ||
|
||
#include <stdbool.h> | ||
|
||
uint8_t hmc_init(uint8_t cra, uint8_t crb, uint8_t mode); | ||
|
||
uint8_t hmc_read(int16_t* x, int16_t* y, int16_t* z); | ||
|
||
float hmc_heading(int16_t x, int16_t y); | ||
|
||
bool hmc_present(void); | ||
|
||
#endif |
Oops, something went wrong.