Integrating the ublox LISA C200 modem

Fork of SprintUSBModemHTTPClientTest by Donatien Garnier

Committer:
sam_grove
Date:
Thu Sep 26 00:44:20 2013 -0500
Revision:
5:3f93dd1d4cb3
Exported program and replaced contents of the repo with the source
to build and debug using keil mdk. Libs NOT upto date are lwip, lwip-sys
and socket. these have newer versions under mbed_official but were starting
from a know working point

Who changed what in which revision?

UserRevisionLine numberNew contents of line
sam_grove 5:3f93dd1d4cb3 1 /* mbed Microcontroller Library
sam_grove 5:3f93dd1d4cb3 2 * Copyright (c) 2006-2013 ARM Limited
sam_grove 5:3f93dd1d4cb3 3 *
sam_grove 5:3f93dd1d4cb3 4 * Licensed under the Apache License, Version 2.0 (the "License");
sam_grove 5:3f93dd1d4cb3 5 * you may not use this file except in compliance with the License.
sam_grove 5:3f93dd1d4cb3 6 * You may obtain a copy of the License at
sam_grove 5:3f93dd1d4cb3 7 *
sam_grove 5:3f93dd1d4cb3 8 * http://www.apache.org/licenses/LICENSE-2.0
sam_grove 5:3f93dd1d4cb3 9 *
sam_grove 5:3f93dd1d4cb3 10 * Unless required by applicable law or agreed to in writing, software
sam_grove 5:3f93dd1d4cb3 11 * distributed under the License is distributed on an "AS IS" BASIS,
sam_grove 5:3f93dd1d4cb3 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
sam_grove 5:3f93dd1d4cb3 13 * See the License for the specific language governing permissions and
sam_grove 5:3f93dd1d4cb3 14 * limitations under the License.
sam_grove 5:3f93dd1d4cb3 15 */
sam_grove 5:3f93dd1d4cb3 16 #include "pwmout_api.h"
sam_grove 5:3f93dd1d4cb3 17 #include "cmsis.h"
sam_grove 5:3f93dd1d4cb3 18 #include "pinmap.h"
sam_grove 5:3f93dd1d4cb3 19 #include "error.h"
sam_grove 5:3f93dd1d4cb3 20
sam_grove 5:3f93dd1d4cb3 21 #define TCR_CNT_EN 0x00000001
sam_grove 5:3f93dd1d4cb3 22 #define TCR_RESET 0x00000002
sam_grove 5:3f93dd1d4cb3 23
sam_grove 5:3f93dd1d4cb3 24 // PORT ID, PWM ID, Pin function
sam_grove 5:3f93dd1d4cb3 25 static const PinMap PinMap_PWM[] = {
sam_grove 5:3f93dd1d4cb3 26 {P1_18, PWM_1, 2},
sam_grove 5:3f93dd1d4cb3 27 {P1_20, PWM_2, 2},
sam_grove 5:3f93dd1d4cb3 28 {P1_21, PWM_3, 2},
sam_grove 5:3f93dd1d4cb3 29 {P1_23, PWM_4, 2},
sam_grove 5:3f93dd1d4cb3 30 {P1_24, PWM_5, 2},
sam_grove 5:3f93dd1d4cb3 31 {P1_26, PWM_6, 2},
sam_grove 5:3f93dd1d4cb3 32 {P2_0 , PWM_1, 1},
sam_grove 5:3f93dd1d4cb3 33 {P2_1 , PWM_2, 1},
sam_grove 5:3f93dd1d4cb3 34 {P2_2 , PWM_3, 1},
sam_grove 5:3f93dd1d4cb3 35 {P2_3 , PWM_4, 1},
sam_grove 5:3f93dd1d4cb3 36 {P2_4 , PWM_5, 1},
sam_grove 5:3f93dd1d4cb3 37 {P2_5 , PWM_6, 1},
sam_grove 5:3f93dd1d4cb3 38 {P3_25, PWM_2, 3},
sam_grove 5:3f93dd1d4cb3 39 {P3_26, PWM_3, 3},
sam_grove 5:3f93dd1d4cb3 40 {NC, NC, 0}
sam_grove 5:3f93dd1d4cb3 41 };
sam_grove 5:3f93dd1d4cb3 42
sam_grove 5:3f93dd1d4cb3 43 __IO uint32_t *PWM_MATCH[] = {
sam_grove 5:3f93dd1d4cb3 44 &(LPC_PWM1->MR0),
sam_grove 5:3f93dd1d4cb3 45 &(LPC_PWM1->MR1),
sam_grove 5:3f93dd1d4cb3 46 &(LPC_PWM1->MR2),
sam_grove 5:3f93dd1d4cb3 47 &(LPC_PWM1->MR3),
sam_grove 5:3f93dd1d4cb3 48 &(LPC_PWM1->MR4),
sam_grove 5:3f93dd1d4cb3 49 &(LPC_PWM1->MR5),
sam_grove 5:3f93dd1d4cb3 50 &(LPC_PWM1->MR6)
sam_grove 5:3f93dd1d4cb3 51 };
sam_grove 5:3f93dd1d4cb3 52
sam_grove 5:3f93dd1d4cb3 53 #define TCR_PWM_EN 0x00000008
sam_grove 5:3f93dd1d4cb3 54
sam_grove 5:3f93dd1d4cb3 55 static unsigned int pwm_clock_mhz;
sam_grove 5:3f93dd1d4cb3 56
sam_grove 5:3f93dd1d4cb3 57 void pwmout_init(pwmout_t* obj, PinName pin) {
sam_grove 5:3f93dd1d4cb3 58 // determine the channel
sam_grove 5:3f93dd1d4cb3 59 PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
sam_grove 5:3f93dd1d4cb3 60 if (pwm == (PWMName)NC)
sam_grove 5:3f93dd1d4cb3 61 error("PwmOut pin mapping failed");
sam_grove 5:3f93dd1d4cb3 62
sam_grove 5:3f93dd1d4cb3 63 obj->pwm = pwm;
sam_grove 5:3f93dd1d4cb3 64 obj->MR = PWM_MATCH[pwm];
sam_grove 5:3f93dd1d4cb3 65
sam_grove 5:3f93dd1d4cb3 66 // ensure the power is on
sam_grove 5:3f93dd1d4cb3 67 LPC_SC->PCONP |= 1 << 6;
sam_grove 5:3f93dd1d4cb3 68
sam_grove 5:3f93dd1d4cb3 69 // ensure clock to /4
sam_grove 5:3f93dd1d4cb3 70 LPC_SC->PCLKSEL0 &= ~(0x3 << 12); // pclk = /4
sam_grove 5:3f93dd1d4cb3 71 LPC_PWM1->PR = 0; // no pre-scale
sam_grove 5:3f93dd1d4cb3 72
sam_grove 5:3f93dd1d4cb3 73 // ensure single PWM mode
sam_grove 5:3f93dd1d4cb3 74 LPC_PWM1->MCR = 1 << 1; // reset TC on match 0
sam_grove 5:3f93dd1d4cb3 75
sam_grove 5:3f93dd1d4cb3 76 // enable the specific PWM output
sam_grove 5:3f93dd1d4cb3 77 LPC_PWM1->PCR |= 1 << (8 + pwm);
sam_grove 5:3f93dd1d4cb3 78
sam_grove 5:3f93dd1d4cb3 79 pwm_clock_mhz = SystemCoreClock / 4000000;
sam_grove 5:3f93dd1d4cb3 80
sam_grove 5:3f93dd1d4cb3 81 // default to 20ms: standard for servos, and fine for e.g. brightness control
sam_grove 5:3f93dd1d4cb3 82 pwmout_period_ms(obj, 20);
sam_grove 5:3f93dd1d4cb3 83 pwmout_write (obj, 0);
sam_grove 5:3f93dd1d4cb3 84
sam_grove 5:3f93dd1d4cb3 85 // Wire pinout
sam_grove 5:3f93dd1d4cb3 86 pinmap_pinout(pin, PinMap_PWM);
sam_grove 5:3f93dd1d4cb3 87 }
sam_grove 5:3f93dd1d4cb3 88
sam_grove 5:3f93dd1d4cb3 89 void pwmout_free(pwmout_t* obj) {
sam_grove 5:3f93dd1d4cb3 90 // [TODO]
sam_grove 5:3f93dd1d4cb3 91 }
sam_grove 5:3f93dd1d4cb3 92
sam_grove 5:3f93dd1d4cb3 93 void pwmout_write(pwmout_t* obj, float value) {
sam_grove 5:3f93dd1d4cb3 94 if (value < 0.0f) {
sam_grove 5:3f93dd1d4cb3 95 value = 0.0;
sam_grove 5:3f93dd1d4cb3 96 } else if (value > 1.0f) {
sam_grove 5:3f93dd1d4cb3 97 value = 1.0;
sam_grove 5:3f93dd1d4cb3 98 }
sam_grove 5:3f93dd1d4cb3 99
sam_grove 5:3f93dd1d4cb3 100 // set channel match to percentage
sam_grove 5:3f93dd1d4cb3 101 uint32_t v = (uint32_t)((float)(LPC_PWM1->MR0) * value);
sam_grove 5:3f93dd1d4cb3 102
sam_grove 5:3f93dd1d4cb3 103 // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
sam_grove 5:3f93dd1d4cb3 104 if (v == LPC_PWM1->MR0) {
sam_grove 5:3f93dd1d4cb3 105 v++;
sam_grove 5:3f93dd1d4cb3 106 }
sam_grove 5:3f93dd1d4cb3 107
sam_grove 5:3f93dd1d4cb3 108 *obj->MR = v;
sam_grove 5:3f93dd1d4cb3 109
sam_grove 5:3f93dd1d4cb3 110 // accept on next period start
sam_grove 5:3f93dd1d4cb3 111 LPC_PWM1->LER |= 1 << obj->pwm;
sam_grove 5:3f93dd1d4cb3 112 }
sam_grove 5:3f93dd1d4cb3 113
sam_grove 5:3f93dd1d4cb3 114 float pwmout_read(pwmout_t* obj) {
sam_grove 5:3f93dd1d4cb3 115 float v = (float)(*obj->MR) / (float)(LPC_PWM1->MR0);
sam_grove 5:3f93dd1d4cb3 116 return (v > 1.0f) ? (1.0f) : (v);
sam_grove 5:3f93dd1d4cb3 117 }
sam_grove 5:3f93dd1d4cb3 118
sam_grove 5:3f93dd1d4cb3 119 void pwmout_period(pwmout_t* obj, float seconds) {
sam_grove 5:3f93dd1d4cb3 120 pwmout_period_us(obj, seconds * 1000000.0f);
sam_grove 5:3f93dd1d4cb3 121 }
sam_grove 5:3f93dd1d4cb3 122
sam_grove 5:3f93dd1d4cb3 123 void pwmout_period_ms(pwmout_t* obj, int ms) {
sam_grove 5:3f93dd1d4cb3 124 pwmout_period_us(obj, ms * 1000);
sam_grove 5:3f93dd1d4cb3 125 }
sam_grove 5:3f93dd1d4cb3 126
sam_grove 5:3f93dd1d4cb3 127 // Set the PWM period, keeping the duty cycle the same.
sam_grove 5:3f93dd1d4cb3 128 void pwmout_period_us(pwmout_t* obj, int us) {
sam_grove 5:3f93dd1d4cb3 129 // calculate number of ticks
sam_grove 5:3f93dd1d4cb3 130 uint32_t ticks = pwm_clock_mhz * us;
sam_grove 5:3f93dd1d4cb3 131
sam_grove 5:3f93dd1d4cb3 132 // set reset
sam_grove 5:3f93dd1d4cb3 133 LPC_PWM1->TCR = TCR_RESET;
sam_grove 5:3f93dd1d4cb3 134
sam_grove 5:3f93dd1d4cb3 135 // set the global match register
sam_grove 5:3f93dd1d4cb3 136 LPC_PWM1->MR0 = ticks;
sam_grove 5:3f93dd1d4cb3 137
sam_grove 5:3f93dd1d4cb3 138 // Scale the pulse width to preserve the duty ratio
sam_grove 5:3f93dd1d4cb3 139 if (LPC_PWM1->MR0 > 0) {
sam_grove 5:3f93dd1d4cb3 140 *obj->MR = (*obj->MR * ticks) / LPC_PWM1->MR0;
sam_grove 5:3f93dd1d4cb3 141 }
sam_grove 5:3f93dd1d4cb3 142
sam_grove 5:3f93dd1d4cb3 143 // set the channel latch to update value at next period start
sam_grove 5:3f93dd1d4cb3 144 LPC_PWM1->LER |= 1 << 0;
sam_grove 5:3f93dd1d4cb3 145
sam_grove 5:3f93dd1d4cb3 146 // enable counter and pwm, clear reset
sam_grove 5:3f93dd1d4cb3 147 LPC_PWM1->TCR = TCR_CNT_EN | TCR_PWM_EN;
sam_grove 5:3f93dd1d4cb3 148 }
sam_grove 5:3f93dd1d4cb3 149
sam_grove 5:3f93dd1d4cb3 150 void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
sam_grove 5:3f93dd1d4cb3 151 pwmout_pulsewidth_us(obj, seconds * 1000000.0f);
sam_grove 5:3f93dd1d4cb3 152 }
sam_grove 5:3f93dd1d4cb3 153
sam_grove 5:3f93dd1d4cb3 154 void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
sam_grove 5:3f93dd1d4cb3 155 pwmout_pulsewidth_us(obj, ms * 1000);
sam_grove 5:3f93dd1d4cb3 156 }
sam_grove 5:3f93dd1d4cb3 157
sam_grove 5:3f93dd1d4cb3 158 void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
sam_grove 5:3f93dd1d4cb3 159 // calculate number of ticks
sam_grove 5:3f93dd1d4cb3 160 uint32_t v = pwm_clock_mhz * us;
sam_grove 5:3f93dd1d4cb3 161
sam_grove 5:3f93dd1d4cb3 162 // workaround for PWM1[1] - Never make it equal MR0, else we get 1 cycle dropout
sam_grove 5:3f93dd1d4cb3 163 if (v == LPC_PWM1->MR0) {
sam_grove 5:3f93dd1d4cb3 164 v++;
sam_grove 5:3f93dd1d4cb3 165 }
sam_grove 5:3f93dd1d4cb3 166
sam_grove 5:3f93dd1d4cb3 167 // set the match register value
sam_grove 5:3f93dd1d4cb3 168 *obj->MR = v;
sam_grove 5:3f93dd1d4cb3 169
sam_grove 5:3f93dd1d4cb3 170 // set the channel latch to update value at next period start
sam_grove 5:3f93dd1d4cb3 171 LPC_PWM1->LER |= 1 << obj->pwm;
sam_grove 5:3f93dd1d4cb3 172 }