Skip to content

Commit

Permalink
Issue #72, tone now working, Genes changes applied
Browse files Browse the repository at this point in the history
  • Loading branch information
msproul committed Sep 4, 2011
1 parent 9d2a732 commit b443d89
Showing 1 changed file with 68 additions and 86 deletions.
154 changes: 68 additions & 86 deletions hardware/pic32/cores/pic32/Tone.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//* Tone.cpp
//*
//* Arduino core files for PIC32
//* Copyright (c) 2010, 2011 by Mark Sproul
//* Copyright (c) 2010, 2011 by Mark Sproul
//*
//*
//************************************************************************
Expand Down Expand Up @@ -35,127 +35,131 @@
//* Edit History
//************************************************************************
//* Oct 15, 2010 Started on Tone.cpp for PIC32
//* Aug 7, 2011 <GeneApperson> Completed implementation for single tone.
//************************************************************************


#define __LANGUAGE_C__
#define LANGUAGE_C
#define __LANGUAGE_C__
//* the Microchip .h files do not know about C++
#include <plib.h>

//#define DEBUG_TONE

//#define _DEBUG_TONE_

#ifdef _DEBUG_TONE_
#include "WProgram.h"
#include "HardwareSerial.h"
#ifdef DEBUG_TONE
#include "WProgram.h"
#include "HardwareSerial.h"
#endif

#include "wiring.h"
#include "pins_arduino.h"


// timerx_toggle_count:
// timerx_toggle_count:
// > 0 - duration specified
// = 0 - stopped
// < 0 - infinitely (until stop() method called, or new play() called)


volatile long timer1_toggle_count;
volatile uint32_t *timer1_pin_port;
volatile uint8_t timer1_pin_mask;
static uint8_t tone_pin = 255;
volatile uint32_t *tone_pin_port;
volatile uint16_t tone_pin_mask;

#if defined(DEAD)
#define AVAILABLE_TONE_PINS 1

const uint8_t tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };
const uint8_t tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };
static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };



#endif

// frequency (in hertz) and duration (in milliseconds).

//************************************************************************
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
{
unsigned long tonePeriod;
uint32_t ocr = 0;
int8_t _timer;
uint8_t port;
uint32_t tonePeriod;
uint8_t port;

timer1_toggle_count = duration;

pinMode(_pin, OUTPUT);
port = digitalPinToPort(_pin);
// Should have an error check here for pin number out of range.

timer1_pin_port = portOutputRegister(port);
// If a tone is currently playing on a different pin, the function is
// documented to have no effect. If playing on the same pin, change
// the frequency. If not currently playing, initialize the timer.
// This is currently hard coded to use timer1.
if (tone_pin == 255)
{
// No tone currently playing. Init the timer.
T1CON = T1_PS_1_256;
mT1ClearIntFlag();
ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_3 | T1_INT_SUB_PRIOR_1);
}
else if (_pin != tone_pin)
{
// Tone currently playing on another pin. ignore this call.
return;
}

timer1_pin_mask = digitalPinToBitMask(_pin);
// Determine which port and bit are requested.
tone_pin = _pin;
port = digitalPinToPort(_pin);
tone_pin_port = portOutputRegister(port);
tone_pin_mask = digitalPinToBitMask(_pin);

//* just to get things going
int ii;
unsigned long startTime;
// Ensure that the pin is a digital output
pinMode(_pin, OUTPUT);

/* tonePeriod = 1000 / frequency;
startTime = millis();
while ((millis() - startTime) < duration)
// Duration 0 means to play forever until stopped. Other values
// mean to play for that many milliseconds.
if (duration > 0)
{
digitalWrite(_pin, HIGH);
delay(tonePeriod / 2);
digitalWrite(_pin, LOW);
delay(tonePeriod / 2);
timer1_toggle_count = (2 * frequency * duration)/1000;
}
else
{
timer1_toggle_count = -1;
}
*/

tonePeriod = ((F_CPU / 256) / 2 / frequency);

ConfigIntTimer1(T1_INT_ON | T1_INT_PRIOR_3 | T1_INT_PRIOR_1);

OpenTimer1(T1_ON | T1_PS_1_256, tonePeriod);

TMR1 = 0;
PR1 = ((F_CPU / 256) / 2 / frequency);
T1CONSET = T1_ON;
}


//************************************************************************
// XXX: this function only works properly for timer 2 (the only one we use
// currently). for the others, it should end the tone, but won't restore
// proper PWM functionality for the timer.
//************************************************************************
void disableTimer(uint8_t _timer)
{
CloseTimer1();
mT1IntEnable(0);
T1CON = 0;;
tone_pin = 255;
}


//************************************************************************
void noTone(uint8_t _pin)
{
int8_t _timer = -1;

disableTimer(_timer);
int8_t _timer = 1;

digitalWrite(_pin, 0);
if (_pin == tone_pin)
{
digitalWrite(_pin, 0);
disableTimer(_timer);
}
}

//*******************************************************************************************
//* we need the extern C so that the interrupt handler names dont get mangled by C++
extern "C"
{


//* not done yet
//************************************************************************
void __ISR(_TIMER_1_VECTOR, ipl3) Timer1Handler(void)
{
//* degugging
mPORTBToggleBits(0x0ffff);

// clear the interrupt flag
mT1ClearIntFlag();
// clear the interrupt flag
mT1ClearIntFlag();

if (timer1_toggle_count != 0)
{
// toggle the pin
*timer1_pin_port ^= timer1_pin_mask;
// The PORTxINV register is at offset +3 from the PORTx register
*(tone_pin_port+3) = tone_pin_mask;

if (timer1_toggle_count > 0)
{
Expand All @@ -164,33 +168,11 @@ void __ISR(_TIMER_1_VECTOR, ipl3) Timer1Handler(void)
}
else
{
disableTimer(2);
*timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop
disableTimer(1);
// The PORTxCLR register is at offset +1 from the PORTx register
*(tone_pin_port+1) = tone_pin_mask; // keep pin low after stop
}

// update the period
// UpdateCoreTimer(CORE_TICK_RATE);

}

};

//- //************************************************************************
//- ISR(TIMER2_COMPA_vect, )
//- {
//-
//- if (timer2_toggle_count != 0)
//- {
//- // toggle the pin
//- *timer2_pin_port ^= timer2_pin_mask;
//-
//- if (timer2_toggle_count > 0)
//- timer2_toggle_count--;
//- }
//- else
//- {
//- disableTimer(2);
//- *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop
//- }
//- }

0 comments on commit b443d89

Please sign in to comment.