Merge pull request #1051 from toyowata/master

NXP's HAL - Fix PwmOut period using SCT
pull/1057/head
Martin Kojtal 2015-04-20 10:39:06 +01:00
commit 016b9ad9cb
7 changed files with 56 additions and 56 deletions

View File

@ -44,9 +44,9 @@
/** A MIDI message container */
class MIDIMessage {
public:
MIDIMessage() {}
MIDIMessage() : length(4) {}
MIDIMessage(uint8_t *buf) {
MIDIMessage(uint8_t *buf) : length(4) {
for (int i = 0; i < 4; i++)
data[i] = buf[i];
}
@ -270,7 +270,7 @@ public:
}
uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
uint8_t length=4;
uint8_t length;
};
#endif

View File

@ -20,7 +20,9 @@
#include "USBMIDI.h"
USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release) {
USBMIDI::USBMIDI(uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
: USBDevice(vendor_id, product_id, product_release), cur_data(0), data_end(true)
{
midi_evt = NULL;
USBDevice::connect();
}

View File

@ -103,8 +103,8 @@ protected:
private:
uint8_t data[MAX_MIDI_MESSAGE_SIZE+1];
uint8_t cur_data=0;
bool data_end = true;
uint8_t cur_data;
bool data_end;
void (*midi_evt)(MIDIMessage);
};

View File

@ -77,9 +77,8 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
pinmap_pinout(pin, PinMap_PWM);
LPC_SCT0_Type* pwm = obj->pwm;
// Two 16-bit counters, autolimit
pwm->CONFIG &= ~(0x1);
pwm->CONFIG |= (1 << 17);
// Unified 32-bit counter, autolimit
pwm->CONFIG |= ((0x3 << 17) | 0x01);
// halt and clear the counter
pwm->CTRL |= (1 << 2) | (1 << 3);
@ -170,8 +169,8 @@ void pwmout_period_us(pwmout_t* obj, int us) {
uint32_t t_off = obj->pwm->MATCHREL0;
uint32_t t_on = obj->pwm->MATCHREL1;
float v = (float)t_on/(float)t_off;
obj->pwm->MATCHREL0 = (uint64_t)us;
obj->pwm->MATCHREL1 = (uint64_t)((float)us * (float)v);
obj->pwm->MATCHREL0 = (uint32_t)us;
obj->pwm->MATCHREL1 = (uint32_t)((float)us * (float)v);
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
@ -183,7 +182,7 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
}
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
obj->pwm->MATCHREL1 = (uint64_t)us;
obj->pwm->MATCHREL1 = (uint32_t)us;
}
#endif

View File

@ -59,33 +59,32 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
LPC_SYSCON->PRESETCTRL1 &= ~(1 << (obj->pwm_ch + 2));
switch(obj->pwm_ch) {
case 0:
case 0:
// SCT0_OUT0
LPC_SWM->PINASSIGN[7] &= ~0x0000FF00;
LPC_SWM->PINASSIGN[7] |= (pin << 8);
break;
case 1:
break;
case 1:
// SCT1_OUT0
LPC_SWM->PINASSIGN[8] &= ~0x000000FF;
LPC_SWM->PINASSIGN[8] |= (pin);
break;
case 2:
break;
case 2:
// SCT2_OUT0
LPC_SWM->PINASSIGN[8] &= ~0xFF000000;
LPC_SWM->PINASSIGN[8] |= (pin << 24);
break;
case 3:
break;
case 3:
// SCT3_OUT0
LPC_SWM->PINASSIGN[9] &= ~0x00FF0000;
LPC_SWM->PINASSIGN[9] |= (pin << 16);
break;
default:
break;
break;
default:
break;
}
// Two 16-bit counters, autolimit
pwm->CONFIG &= ~(0x1);
pwm->CONFIG |= (1 << 17);
// Unified 32-bit counter, autolimit
pwm->CONFIG |= ((0x3 << 17) | 0x01);
// halt and clear the counter
pwm->CTRL |= (1 << 2) | (1 << 3);
@ -101,10 +100,10 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
pwm->OUT0_SET = (1 << 0); // event 0
pwm->OUT0_CLR = (1 << 1); // event 1
pwm->EV0_CTRL = (1 << 12);
pwm->EV0_STATE = 0xFFFFFFFF;
pwm->EV1_CTRL = (1 << 12) | (1 << 0);
pwm->EV1_STATE = 0xFFFFFFFF;
pwm->EV0_CTRL = (1 << 12);
pwm->EV0_STATE = 0xFFFFFFFF;
pwm->EV1_CTRL = (1 << 12) | (1 << 0);
pwm->EV1_STATE = 0xFFFFFFFF;
// unhalt the counter:
// - clearing bit 2 of the CTRL register
@ -135,7 +134,7 @@ void pwmout_write(pwmout_t* obj, float value) {
float pwmout_read(pwmout_t* obj) {
uint32_t t_off = obj->pwm->MATCHREL0;
uint32_t t_on = obj->pwm->MATCHREL1;
float v = (float)t_on/(float)t_off;
float v = (float)t_on/(float)t_off;
return (v > 1.0f) ? (1.0f) : (v);
}
@ -152,9 +151,9 @@ void pwmout_period_us(pwmout_t* obj, int us) {
LPC_SCT0_Type* pwm = obj->pwm;
uint32_t t_off = pwm->MATCHREL0;
uint32_t t_on = pwm->MATCHREL1;
float v = (float)t_on/(float)t_off;
pwm->MATCHREL0 = (uint64_t)us;
pwm->MATCHREL1 = (uint64_t)((float)us * (float)v);
float v = (float)t_on/(float)t_off;
pwm->MATCHREL0 = (uint32_t)us;
pwm->MATCHREL1 = (uint32_t)((float)us * (float)v);
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds) {
@ -166,6 +165,6 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms) {
}
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
obj->pwm->MATCHREL1 = (uint64_t)us;
obj->pwm->MATCHREL1 = (uint32_t)us;
}

View File

@ -72,22 +72,23 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
LPC_SYSCON->PRESETCTRL |= (1 << 8);
// Two 16-bit counters, autolimit (ie reset on Match_0)
pwm->CONFIG &= ~(0x1);
pwm->CONFIG |= (1 << 17);
//pwm->CONFIG &= ~(0x1);
//pwm->CONFIG |= (1 << 17);
pwm->CONFIG |= ((0x3 << 17) | 0x01);
// halt and clear the counter
pwm->CTRL_L |= (1 << 2) | (1 << 3);
pwm->CTRL_U |= (1 << 2) | (1 << 3);
// System Clock (30 Mhz) -> Prescaler -> us_ticker (1 MHz)
pwm->CTRL_L &= ~(0x7F << 5);
pwm->CTRL_L |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5);
pwm->CTRL_U &= ~(0x7F << 5);
pwm->CTRL_U |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5);
pwm->EVENT[0].CTRL = (1 << 12) | 0; // Event_0 on Match_0
pwm->EVENT[0].STATE = 0xFFFFFFFF; // All states
// unhalt the counter:
// - clearing bit 2 of the CTRL register
pwm->CTRL_L &= ~(1 << 2);
pwm->CTRL_U &= ~(1 << 2);
// Not using IRQs
//NVIC_SetVector(PWM_IRQn, (uint32_t)pwm_irq_handler);
@ -154,20 +155,20 @@ void pwmout_write(pwmout_t* obj, float value) {
}
// Match_0 is PWM period. Compute new endtime of pulse for current channel
uint32_t t_off = (uint32_t)((float)(obj->pwm->MATCHREL[0].L) * value);
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = t_off; // New endtime
uint32_t t_off = (uint32_t)((float)(obj->pwm->MATCHREL[0].U) * value);
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = t_off; // New endtime
}
// Get dutycycle (0.0 .. 1.0)
float pwmout_read(pwmout_t* obj) {
uint32_t t_period = obj->pwm->MATCHREL[0].L;
uint32_t t_period = obj->pwm->MATCHREL[0].U;
//Sanity check
if (t_period == 0) {
return 0.0;
};
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L;
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U;
float v = (float)t_off/(float)t_period;
//Sanity check
return (v > 1.0f) ? (1.0f) : (v);
@ -186,8 +187,8 @@ void pwmout_period_ms(pwmout_t* obj, int ms) {
// Set the PWM period, keeping the duty cycle the same (for this channel only!).
void pwmout_period_us(pwmout_t* obj, int us) {
uint32_t t_period = obj->pwm->MATCHREL[0].L; // Current PWM period
obj->pwm->MATCHREL[0].L = (uint64_t)us; // New PWM period
uint32_t t_period = obj->pwm->MATCHREL[0].U; // Current PWM period
obj->pwm->MATCHREL[0].U = (uint32_t)us; // New PWM period
//Keep the dutycycle for the new PWM period
//Should really do this for all active channels!!
@ -199,9 +200,9 @@ void pwmout_period_us(pwmout_t* obj, int us) {
// obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = 0; // New endtime for this channel
}
else {
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L;
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U;
float v = (float)t_off/(float)t_period;
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = (uint64_t)((float)us * (float)v); // New endtime for this channel
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = (uint32_t)((float)us * (float)v); // New endtime for this channel
}
}
@ -220,7 +221,7 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms){
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
//Should add Sanity check to make sure pulsewidth < period!
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = (uint64_t)us; // New endtime for this channel
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = (uint32_t)us; // New endtime for this channel
}
#endif

View File

@ -48,7 +48,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
obj->pwm = (LPC_SCT_Type*)LPC_SCT;
obj->pwm_ch = sct_n;
LPC_SCT_Type* pwm = obj->pwm;
LPC_SCT_Type* pwm = obj->pwm;
// Enable the SCT clock
LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);
@ -81,9 +81,8 @@ void pwmout_init(pwmout_t* obj, PinName pin)
break;
}
// Two 16-bit counters, autolimit
pwm->CONFIG &= ~(0x1);
pwm->CONFIG |= (1 << 17);
// Unified 32-bit counter, autolimit
pwm->CONFIG |= ((0x3 << 17) | 0x01);
// halt and clear the counter
pwm->CTRL |= (1 << 2) | (1 << 3);
@ -151,8 +150,8 @@ void pwmout_period_us(pwmout_t* obj, int us)
uint32_t t_off = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0];
uint32_t t_on = obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1];
float v = (float)t_on/(float)t_off;
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0] = (uint64_t)us;
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint64_t)((float)us * (float)v);
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 0] = (uint32_t)us;
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)((float)us * (float)v);
}
void pwmout_pulsewidth(pwmout_t* obj, float seconds)
@ -167,7 +166,7 @@ void pwmout_pulsewidth_ms(pwmout_t* obj, int ms)
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
{
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint64_t)us;
obj->pwm->MATCHREL[(obj->pwm_ch * 2) + 1] = (uint32_t)us;
}
#endif