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

View File

@ -20,7 +20,9 @@
#include "USBMIDI.h" #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; midi_evt = NULL;
USBDevice::connect(); USBDevice::connect();
} }

View File

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

View File

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

View File

@ -59,33 +59,32 @@ void pwmout_init(pwmout_t* obj, PinName pin) {
LPC_SYSCON->PRESETCTRL1 &= ~(1 << (obj->pwm_ch + 2)); LPC_SYSCON->PRESETCTRL1 &= ~(1 << (obj->pwm_ch + 2));
switch(obj->pwm_ch) { switch(obj->pwm_ch) {
case 0: case 0:
// SCT0_OUT0 // SCT0_OUT0
LPC_SWM->PINASSIGN[7] &= ~0x0000FF00; LPC_SWM->PINASSIGN[7] &= ~0x0000FF00;
LPC_SWM->PINASSIGN[7] |= (pin << 8); LPC_SWM->PINASSIGN[7] |= (pin << 8);
break; break;
case 1: case 1:
// SCT1_OUT0 // SCT1_OUT0
LPC_SWM->PINASSIGN[8] &= ~0x000000FF; LPC_SWM->PINASSIGN[8] &= ~0x000000FF;
LPC_SWM->PINASSIGN[8] |= (pin); LPC_SWM->PINASSIGN[8] |= (pin);
break; break;
case 2: case 2:
// SCT2_OUT0 // SCT2_OUT0
LPC_SWM->PINASSIGN[8] &= ~0xFF000000; LPC_SWM->PINASSIGN[8] &= ~0xFF000000;
LPC_SWM->PINASSIGN[8] |= (pin << 24); LPC_SWM->PINASSIGN[8] |= (pin << 24);
break; break;
case 3: case 3:
// SCT3_OUT0 // SCT3_OUT0
LPC_SWM->PINASSIGN[9] &= ~0x00FF0000; LPC_SWM->PINASSIGN[9] &= ~0x00FF0000;
LPC_SWM->PINASSIGN[9] |= (pin << 16); LPC_SWM->PINASSIGN[9] |= (pin << 16);
break; break;
default: default:
break; break;
} }
// Two 16-bit counters, autolimit // Unified 32-bit counter, autolimit
pwm->CONFIG &= ~(0x1); pwm->CONFIG |= ((0x3 << 17) | 0x01);
pwm->CONFIG |= (1 << 17);
// halt and clear the counter // halt and clear the counter
pwm->CTRL |= (1 << 2) | (1 << 3); 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_SET = (1 << 0); // event 0
pwm->OUT0_CLR = (1 << 1); // event 1 pwm->OUT0_CLR = (1 << 1); // event 1
pwm->EV0_CTRL = (1 << 12); pwm->EV0_CTRL = (1 << 12);
pwm->EV0_STATE = 0xFFFFFFFF; pwm->EV0_STATE = 0xFFFFFFFF;
pwm->EV1_CTRL = (1 << 12) | (1 << 0); pwm->EV1_CTRL = (1 << 12) | (1 << 0);
pwm->EV1_STATE = 0xFFFFFFFF; pwm->EV1_STATE = 0xFFFFFFFF;
// unhalt the counter: // unhalt the counter:
// - clearing bit 2 of the CTRL register // - 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) { float pwmout_read(pwmout_t* obj) {
uint32_t t_off = obj->pwm->MATCHREL0; uint32_t t_off = obj->pwm->MATCHREL0;
uint32_t t_on = obj->pwm->MATCHREL1; 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); 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; LPC_SCT0_Type* pwm = obj->pwm;
uint32_t t_off = pwm->MATCHREL0; uint32_t t_off = pwm->MATCHREL0;
uint32_t t_on = pwm->MATCHREL1; uint32_t t_on = pwm->MATCHREL1;
float v = (float)t_on/(float)t_off; float v = (float)t_on/(float)t_off;
pwm->MATCHREL0 = (uint64_t)us; pwm->MATCHREL0 = (uint32_t)us;
pwm->MATCHREL1 = (uint64_t)((float)us * (float)v); pwm->MATCHREL1 = (uint32_t)((float)us * (float)v);
} }
void pwmout_pulsewidth(pwmout_t* obj, float seconds) { 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) { 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); LPC_SYSCON->PRESETCTRL |= (1 << 8);
// Two 16-bit counters, autolimit (ie reset on Match_0) // Two 16-bit counters, autolimit (ie reset on Match_0)
pwm->CONFIG &= ~(0x1); //pwm->CONFIG &= ~(0x1);
pwm->CONFIG |= (1 << 17); //pwm->CONFIG |= (1 << 17);
pwm->CONFIG |= ((0x3 << 17) | 0x01);
// halt and clear the counter // 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) // System Clock (30 Mhz) -> Prescaler -> us_ticker (1 MHz)
pwm->CTRL_L &= ~(0x7F << 5); pwm->CTRL_U &= ~(0x7F << 5);
pwm->CTRL_L |= (((SystemCoreClock/1000000 - 1) & 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].CTRL = (1 << 12) | 0; // Event_0 on Match_0
pwm->EVENT[0].STATE = 0xFFFFFFFF; // All states pwm->EVENT[0].STATE = 0xFFFFFFFF; // All states
// unhalt the counter: // unhalt the counter:
// - clearing bit 2 of the CTRL register // - clearing bit 2 of the CTRL register
pwm->CTRL_L &= ~(1 << 2); pwm->CTRL_U &= ~(1 << 2);
// Not using IRQs // Not using IRQs
//NVIC_SetVector(PWM_IRQn, (uint32_t)pwm_irq_handler); //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 // 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); uint32_t t_off = (uint32_t)((float)(obj->pwm->MATCHREL[0].U) * value);
obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = t_off; // New endtime obj->pwm->MATCHREL[(obj->pwm_ch) + 1].U = t_off; // New endtime
} }
// Get dutycycle (0.0 .. 1.0) // Get dutycycle (0.0 .. 1.0)
float pwmout_read(pwmout_t* obj) { 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 //Sanity check
if (t_period == 0) { if (t_period == 0) {
return 0.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; float v = (float)t_off/(float)t_period;
//Sanity check //Sanity check
return (v > 1.0f) ? (1.0f) : (v); 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!). // Set the PWM period, keeping the duty cycle the same (for this channel only!).
void pwmout_period_us(pwmout_t* obj, int us) { void pwmout_period_us(pwmout_t* obj, int us) {
uint32_t t_period = obj->pwm->MATCHREL[0].L; // Current PWM period uint32_t t_period = obj->pwm->MATCHREL[0].U; // Current PWM period
obj->pwm->MATCHREL[0].L = (uint64_t)us; // New PWM period obj->pwm->MATCHREL[0].U = (uint32_t)us; // New PWM period
//Keep the dutycycle for the new PWM period //Keep the dutycycle for the new PWM period
//Should really do this for all active channels!! //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 // obj->pwm->MATCHREL[(obj->pwm_ch) + 1].L = 0; // New endtime for this channel
} }
else { 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; 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) { void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
//Should add Sanity check to make sure pulsewidth < period! //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 #endif

View File

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