#include <sched.h> /*sheduler*/
#include <unistd.h> /*usleep*/
#include <pthread.h> /*threads*/
+#include <time.h> /*nanosleep*/
#include "rpin.h" /*gpclk*/
#include "rp_spi.h" /*spi*/
#define PRIOR_LOW 20
#define THREAD_SHARED 0
-#define INIT_VALUE 0 /*init value for semaphor*/
+#define INIT_VALUE 1 /*init value for semaphor*/
#define PXMC_SIN_FIX_TAB_BITS 9
#define PXMC_SIN_FIX_PI2 0x40000000
#define PXMC_SIN_FIX_2PI3 0x55555555
-struct sigaction sighnd; /*struktura pro signal handler*/
+#define NSEC_PER_SEC (1000000000) /* The number of nsecs per sec. */
+
+
+
struct rpi_in data;
struct rpi_state{
uint8_t test;
/**
* \brief Signal handler pro Ctrl+C
*/
-void sighnd_fnc(){
+void appl_stop(){
spi_disable();
clk_disable();
/*muzeme zavrit semafor*/
sem_destroy(&thd_par_sem);
printf("\nprogram bezpecne ukoncen\n");
- exit(0);
}
void substractOffset(struct rpi_in* data, struct rpi_in* offset){
* bit 89 - shutdown3
* .
* .
+ * Unused
+ * .
* .
- * bits 66 .. 56 - match PWM1
- * bits 55 .. 45 - match PWM2
- * bit 11,12 - Unused
- * bits 42 .. 32 - match PWM3
+ * bits 47 .. 32 - match PWM1
+ * bits 31 .. 16 - match PWM2
+ * bits 15 .. 0 - match PWM3
*/
uint16_t tmp;
- /* keep the cap*/
+ /* keep the 11-bit cap*/
if (rps.pwm1>2047) rps.pwm1=2047;
if (rps.pwm2>2047) rps.pwm2=2047;
tx[0]=rps.test; /*bit 94 - enable PWM1*/
+ /*now we have to switch the bytes due to endianess */
+ /* ARMv6 & ARMv7 instructions are little endian */
/*pwm1*/
- tx[7]=(tx[7] & 0xF8) | (0x07 & ((uint8_t*)&rps.pwm1)[1]); /*MSB*/
- tx[8]=((uint8_t*)&rps.pwm1)[0]; /*LSB*/
+ tx[10]=((uint8_t*)&rps.pwm1)[1]; /*MSB*/
+ tx[11]=((uint8_t*)&rps.pwm1)[0]; /*LSB*/
/*pwm2*/
- tmp=rps.pwm2;
- tmp<<=5;
- tx[9]=((uint8_t*)&tmp)[1]; /*MSB*/
- tx[10]=(tx[10] & 0x1F) | (0xE0 & ((uint8_t*)&tmp)[0]); /*LSB*/
+ tx[12]=((uint8_t*)&rps.pwm2)[1]; /*MSB*/
+ tx[13]=((uint8_t*)&rps.pwm2)[0]; /*LSB*/
/*pwm3*/
- tx[10]=(tx[10] & 0xF8) | (0x07 & ((uint8_t*)&rps.pwm3)[1]); /*MSB*/
- tx[11]=((uint8_t*)&rps.pwm3)[0]; /*LSB*/
+ tx[14]=((uint8_t*)&rps.pwm3)[1]; /*MSB*/
+ tx[15]=((uint8_t*)&rps.pwm3)[0]; /*LSB*/
}
* Funkce pravidelne vypisuje posledni zjistenou pozici lokalniho motoru
*/
void * pos_monitor(void* param){
- set_priority(param); /*set priority*/
while(1){
printData();
usleep(1000000); /*1 Hz*/
/*
* \brief
* Feedback loop.
- * TODO: replace usleep with real-time wait
- * measure times
*/
void * read_data(void* param){
int i;
struct rpi_in pocatek;
+ struct timespec t;
+ int interval = 1000000; /* 1ms ~ 1kHz*/
uint8_t tx[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;
char first=1;
uint16_t last_index; /*we have index up-to date*/
- set_priority(param); /*set priority*/
pocatek = spi_read(tx);
+ clock_gettime(CLOCK_MONOTONIC ,&t);
+ /* start after one second */
+ t.tv_sec++;
while(1){
- prepare_tx(tx); /*save the data to send*/
+ /* wait until next shot */
+ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &t, NULL);
sem_wait(&thd_par_sem); /*---take semaphore---*/
+ prepare_tx(tx); /*save the data to send*/
data = spi_read(tx); /*exchange data*/
/*subtract initiate postion */
rps.tf_count++;
simple_hall_commutator(rps.duty);
}
sem_post(&thd_par_sem); /*--post semaphore---*/
- usleep(1000); /*1kHz*/
+
+ /* calculate next shot */
+ t.tv_nsec += interval;
+
+ while (t.tv_nsec >= NSEC_PER_SEC) {
+ t.tv_nsec -= NSEC_PER_SEC;
+ t.tv_sec++;
+ }
+
}
}
+
/**
- * \brief Main function.
+ * \brief
+ * Commands detection.
*/
-
-int main(){
+void poll_cmd(){
unsigned int tmp;
-
- /*nastaveni priorit vlaken*/
- struct thread_param tsp;
- tsp.sch_policy = SCHED_FIFO;
-
- /*nastaveni signalu pro vypnuti pomoci Ctrl+C*/
- sighnd.sa_handler=&sighnd_fnc;
- sigaction(SIGINT, &sighnd, NULL );
-
- clk_init(); /* inicializace gpio hodin */
- spi_init(); /* iniicializace spi*/
-
- /*semafor pro detekci zpracovani parametru vlaken*/
- sem_init(&thd_par_sem,THREAD_SHARED,INIT_VALUE);
-
- /*vlakna*/
- pthread_t tid; /*identifikator vlakna*/
- pthread_attr_t attr; /*atributy vlakna*/
- pthread_attr_init(&attr); /*inicializuj implicitni atributy*/
-
-
-
- /*ziskavani dat z motoru*//*vysoka priorita*/
- tsp.sch_prior = PRIOR_HIGH;
- pthread_create(&tid, &attr, read_data, (void*)&tsp);
-
- /*vypisovani lokalni pozice*//*nizka priorita*/
- tsp.sch_prior = PRIOR_LOW;
- sem_wait(&thd_par_sem);
- pthread_create(&tid, &attr, pos_monitor, (void*)&tsp);
-
-
-
/*
* Note:
* pri pouziti scanf("%u",&simple_hall_duty); dochazelo
}
}
- return 0;
+ return ;
}
+/**
+ * \brief Main function.
+ */
+
+int main(){
+ pthread_t base_thread_id;
+ clk_init(); /* inicializace gpio hodin */
+ spi_init(); /* iniicializace spi*/
+
+ /*semafor pro detekci zpracovani parametru vlaken*/
+ sem_init(&thd_par_sem,THREAD_SHARED,INIT_VALUE);
+ setup_environment();
+ base_thread_id=pthread_self();
+
+ /*main control loop*/
+ create_rt_task(&base_thread_id,PRIOR_HIGH,read_data,NULL);
+
+ /*monitor of current state*/
+ create_rt_task(&base_thread_id,PRIOR_LOW,pos_monitor,NULL);
+
+ /*wait for commands*/
+ poll_cmd();
+
+ return 0;
+}