Mouse code for the MacroRat

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Fri May 26 17:21:04 2017 +0000
Revision:
34:69342782fb68
Parent:
18:6a4db94011d3
Added small reverse turns before the break so that we can stop faster.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sahilmgandhi 18:6a4db94011d3 1 /* mbed Microcontroller Library
sahilmgandhi 18:6a4db94011d3 2 * Copyright (c) 2006-2015 ARM Limited
sahilmgandhi 18:6a4db94011d3 3 *
sahilmgandhi 18:6a4db94011d3 4 * Licensed under the Apache License, Version 2.0 (the "License");
sahilmgandhi 18:6a4db94011d3 5 * you may not use this file except in compliance with the License.
sahilmgandhi 18:6a4db94011d3 6 * You may obtain a copy of the License at
sahilmgandhi 18:6a4db94011d3 7 *
sahilmgandhi 18:6a4db94011d3 8 * http://www.apache.org/licenses/LICENSE-2.0
sahilmgandhi 18:6a4db94011d3 9 *
sahilmgandhi 18:6a4db94011d3 10 * Unless required by applicable law or agreed to in writing, software
sahilmgandhi 18:6a4db94011d3 11 * distributed under the License is distributed on an "AS IS" BASIS,
sahilmgandhi 18:6a4db94011d3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sahilmgandhi 18:6a4db94011d3 13 * See the License for the specific language governing permissions and
sahilmgandhi 18:6a4db94011d3 14 * limitations under the License.
sahilmgandhi 18:6a4db94011d3 15 */
sahilmgandhi 18:6a4db94011d3 16 #include "mbed_assert.h"
sahilmgandhi 18:6a4db94011d3 17 #include "pwmout_api.h"
sahilmgandhi 18:6a4db94011d3 18
sahilmgandhi 18:6a4db94011d3 19 #include "cmsis.h"
sahilmgandhi 18:6a4db94011d3 20 #include "pinmap.h"
sahilmgandhi 18:6a4db94011d3 21 #include "PeripheralPins.h"
sahilmgandhi 18:6a4db94011d3 22
sahilmgandhi 18:6a4db94011d3 23 static float pwm_clock = 0;
sahilmgandhi 18:6a4db94011d3 24
sahilmgandhi 18:6a4db94011d3 25 void pwmout_init(pwmout_t* obj, PinName pin) {
sahilmgandhi 18:6a4db94011d3 26 // determine the channel
sahilmgandhi 18:6a4db94011d3 27 PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
sahilmgandhi 18:6a4db94011d3 28 MBED_ASSERT(pwm != (PWMName)NC);
sahilmgandhi 18:6a4db94011d3 29
sahilmgandhi 18:6a4db94011d3 30 uint32_t MGCOUTClock = SystemCoreClock * (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK) >> SIM_CLKDIV1_OUTDIV1_SHIFT));
sahilmgandhi 18:6a4db94011d3 31 uint32_t BusClock = MGCOUTClock / (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >> SIM_CLKDIV1_OUTDIV2_SHIFT));
sahilmgandhi 18:6a4db94011d3 32
sahilmgandhi 18:6a4db94011d3 33 uint32_t clkdiv = 0;
sahilmgandhi 18:6a4db94011d3 34 float clkval = BusClock / 1000000.0f;
sahilmgandhi 18:6a4db94011d3 35
sahilmgandhi 18:6a4db94011d3 36 while (clkval > 1) {
sahilmgandhi 18:6a4db94011d3 37 clkdiv++;
sahilmgandhi 18:6a4db94011d3 38 clkval /= 2.0;
sahilmgandhi 18:6a4db94011d3 39 if (clkdiv == 7)
sahilmgandhi 18:6a4db94011d3 40 break;
sahilmgandhi 18:6a4db94011d3 41 }
sahilmgandhi 18:6a4db94011d3 42
sahilmgandhi 18:6a4db94011d3 43 pwm_clock = clkval;
sahilmgandhi 18:6a4db94011d3 44 unsigned int ftm_n = (pwm >> TPM_SHIFT);
sahilmgandhi 18:6a4db94011d3 45 unsigned int ch_n = (pwm & 0xFF);
sahilmgandhi 18:6a4db94011d3 46
sahilmgandhi 18:6a4db94011d3 47 SIM->SCGC6 |= 1 << (SIM_SCGC6_FTM0_SHIFT + ftm_n);
sahilmgandhi 18:6a4db94011d3 48
sahilmgandhi 18:6a4db94011d3 49 FTM_Type *ftm = (FTM_Type *)(FTM0_BASE + 0x1000 * ftm_n);
sahilmgandhi 18:6a4db94011d3 50 ftm->CONF |= FTM_CONF_BDMMODE(3);
sahilmgandhi 18:6a4db94011d3 51 ftm->SC = FTM_SC_CLKS(1) | FTM_SC_PS(clkdiv); // (clock)MHz / clkdiv ~= (0.75)MHz
sahilmgandhi 18:6a4db94011d3 52 ftm->CONTROLS[ch_n].CnSC = (FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK); /* No Interrupts; High True pulses on Edge Aligned PWM */
sahilmgandhi 18:6a4db94011d3 53 ftm->MODE = FTM_MODE_FTMEN_MASK;
sahilmgandhi 18:6a4db94011d3 54 ftm->SYNC = FTM_SYNC_CNTMIN_MASK;
sahilmgandhi 18:6a4db94011d3 55 ftm->SYNCONF = FTM_SYNCONF_SYNCMODE_MASK | FTM_SYNCONF_SWSOC_MASK | FTM_SYNCONF_SWWRBUF_MASK;
sahilmgandhi 18:6a4db94011d3 56
sahilmgandhi 18:6a4db94011d3 57 //Without SYNCEN set CnV does not seem to update
sahilmgandhi 18:6a4db94011d3 58 ftm->COMBINE = FTM_COMBINE_SYNCEN0_MASK | FTM_COMBINE_SYNCEN1_MASK | FTM_COMBINE_SYNCEN2_MASK | FTM_COMBINE_SYNCEN3_MASK;
sahilmgandhi 18:6a4db94011d3 59
sahilmgandhi 18:6a4db94011d3 60 obj->CnV = &ftm->CONTROLS[ch_n].CnV;
sahilmgandhi 18:6a4db94011d3 61 obj->MOD = &ftm->MOD;
sahilmgandhi 18:6a4db94011d3 62 obj->SYNC = &ftm->SYNC;
sahilmgandhi 18:6a4db94011d3 63
sahilmgandhi 18:6a4db94011d3 64 // default to 20ms: standard for servos, and fine for e.g. brightness control
sahilmgandhi 18:6a4db94011d3 65 pwmout_period_ms(obj, 20);
sahilmgandhi 18:6a4db94011d3 66 pwmout_write(obj, 0.0);
sahilmgandhi 18:6a4db94011d3 67
sahilmgandhi 18:6a4db94011d3 68 // Wire pinout
sahilmgandhi 18:6a4db94011d3 69 pinmap_pinout(pin, PinMap_PWM);
sahilmgandhi 18:6a4db94011d3 70 }
sahilmgandhi 18:6a4db94011d3 71
sahilmgandhi 18:6a4db94011d3 72 void pwmout_free(pwmout_t* obj) {}
sahilmgandhi 18:6a4db94011d3 73
sahilmgandhi 18:6a4db94011d3 74 void pwmout_write(pwmout_t* obj, float value) {
sahilmgandhi 18:6a4db94011d3 75 if (value < 0.0) {
sahilmgandhi 18:6a4db94011d3 76 value = 0.0;
sahilmgandhi 18:6a4db94011d3 77 } else if (value > 1.0) {
sahilmgandhi 18:6a4db94011d3 78 value = 1.0;
sahilmgandhi 18:6a4db94011d3 79 }
sahilmgandhi 18:6a4db94011d3 80
sahilmgandhi 18:6a4db94011d3 81 while(*obj->SYNC & FTM_SYNC_SWSYNC_MASK);
sahilmgandhi 18:6a4db94011d3 82 *obj->CnV = (uint32_t)((float)(*obj->MOD + 1) * value);
sahilmgandhi 18:6a4db94011d3 83 *obj->SYNC |= FTM_SYNC_SWSYNC_MASK;
sahilmgandhi 18:6a4db94011d3 84 }
sahilmgandhi 18:6a4db94011d3 85
sahilmgandhi 18:6a4db94011d3 86 float pwmout_read(pwmout_t* obj) {
sahilmgandhi 18:6a4db94011d3 87 while(*obj->SYNC & FTM_SYNC_SWSYNC_MASK);
sahilmgandhi 18:6a4db94011d3 88 float v = (float)(*obj->CnV) / (float)(*obj->MOD + 1);
sahilmgandhi 18:6a4db94011d3 89 return (v > 1.0) ? (1.0) : (v);
sahilmgandhi 18:6a4db94011d3 90 }
sahilmgandhi 18:6a4db94011d3 91
sahilmgandhi 18:6a4db94011d3 92 void pwmout_period(pwmout_t* obj, float seconds) {
sahilmgandhi 18:6a4db94011d3 93 pwmout_period_us(obj, seconds * 1000000.0f);
sahilmgandhi 18:6a4db94011d3 94 }
sahilmgandhi 18:6a4db94011d3 95
sahilmgandhi 18:6a4db94011d3 96 void pwmout_period_ms(pwmout_t* obj, int ms) {
sahilmgandhi 18:6a4db94011d3 97 pwmout_period_us(obj, ms * 1000);
sahilmgandhi 18:6a4db94011d3 98 }
sahilmgandhi 18:6a4db94011d3 99
sahilmgandhi 18:6a4db94011d3 100 // Set the PWM period, keeping the duty cycle the same.
sahilmgandhi 18:6a4db94011d3 101 void pwmout_period_us(pwmout_t* obj, int us) {
sahilmgandhi 18:6a4db94011d3 102 float dc = pwmout_read(obj);
sahilmgandhi 18:6a4db94011d3 103 *obj->MOD = (uint32_t)(pwm_clock * (float)us) - 1;
sahilmgandhi 18:6a4db94011d3 104 *obj->SYNC |= FTM_SYNC_SWSYNC_MASK;
sahilmgandhi 18:6a4db94011d3 105 pwmout_write(obj, dc);
sahilmgandhi 18:6a4db94011d3 106 }
sahilmgandhi 18:6a4db94011d3 107
sahilmgandhi 18:6a4db94011d3 108 void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
sahilmgandhi 18:6a4db94011d3 109 pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
sahilmgandhi 18:6a4db94011d3 110 }
sahilmgandhi 18:6a4db94011d3 111
sahilmgandhi 18:6a4db94011d3 112 void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
sahilmgandhi 18:6a4db94011d3 113 pwmout_pulsewidth_us(obj, ms * 1000);
sahilmgandhi 18:6a4db94011d3 114 }
sahilmgandhi 18:6a4db94011d3 115
sahilmgandhi 18:6a4db94011d3 116 void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
sahilmgandhi 18:6a4db94011d3 117 *obj->CnV = (uint32_t)(pwm_clock * (float)us);
sahilmgandhi 18:6a4db94011d3 118 *obj->SYNC |= FTM_SYNC_SWSYNC_MASK;
sahilmgandhi 18:6a4db94011d3 119 }