00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "pic24_all.h"
00030 #include <stdio.h>
00031
00038 extern void ADPCMEncoderInit(void);
00039 extern uint8 ADPCMEncoder( int16 i16_sample);
00040 extern int16 ADPCMDecoder(uint8 u8_code);
00041 extern void ADPCMDecoderInit(void);
00042
00043
00044 #define EEPROM 0xA0 //LC515 address assuming both address pins tied low.
00045 #define BLKSIZE 64
00046
00047
00048 void waitForWriteCompletion(uint8 u8_i2cAddr) {
00049 uint8 u8_ack, u8_savedSWDTEN;
00050 u8_savedSWDTEN = _SWDTEN;
00051 _SWDTEN = 1;
00052 u8_i2cAddr = I2C_WADDR(u8_i2cAddr);
00053 do {
00054 startI2C1();
00055 u8_ack = putNoAckCheckI2C1(u8_i2cAddr);
00056 stopI2C1();
00057 } while (u8_ack == I2C_NAK);
00058 _SWDTEN = u8_savedSWDTEN;
00059 }
00060
00061
00062 void memWriteLC515(uint8 u8_i2cAddr, uint16 u16_MemAddr, uint8 *pu8_buf) {
00063 uint8 u8_AddrLo, u8_AddrHi;
00064 uint16 u16_i;
00065 u8_AddrLo = u16_MemAddr & 0x00FF;
00066 u8_AddrHi = (u16_MemAddr >> 8);
00067 if (u16_MemAddr & 0x8000) {
00068
00069 u8_i2cAddr = u8_i2cAddr | 0x08;
00070 }
00071 waitForWriteCompletion(u8_i2cAddr);
00072
00073 startI2C1();
00074 putI2C1(I2C_WADDR(u8_i2cAddr));
00075 putI2C1(u8_AddrHi);
00076 putI2C1(u8_AddrLo);
00077 for (u16_i=0; u16_i < BLKSIZE; u16_i++) {
00078 putI2C1(*pu8_buf);
00079 pu8_buf++;
00080 }
00081 stopI2C1();
00082 }
00083
00084 void memReadLC515(uint8 u8_i2cAddr, uint16 u16_MemAddr, uint8 *pu8_buf) {
00085
00086 uint8 u8_AddrLo, u8_AddrHi;
00087
00088 u8_AddrLo = u16_MemAddr & 0x00FF;
00089 u8_AddrHi = (u16_MemAddr >> 8);
00090
00091 if (u16_MemAddr & 0x8000) {
00092
00093 u8_i2cAddr = u8_i2cAddr | 0x08;
00094 }
00095 waitForWriteCompletion(u8_i2cAddr);
00096
00097 write2I2C1(u8_i2cAddr,u8_AddrHi, u8_AddrLo);
00098
00099 readNI2C1(u8_i2cAddr,pu8_buf, BLKSIZE);
00100 }
00101
00102
00103 #define CONFIG_SLAVE_ENABLE() CONFIG_RB3_AS_DIG_OUTPUT()
00104 #define SLAVE_ENABLE() _LATB3 = 0 //low true assertion
00105 #define SLAVE_DISABLE() _LATB3 = 1
00106
00107
00108 void configSPI1(void) {
00109
00110 SPI1CON1 = SEC_PRESCAL_1_1 |
00111 PRI_PRESCAL_4_1 |
00112 CLK_POL_ACTIVE_HIGH |
00113 SPI_CKE_ON |
00114 SPI_MODE8_ON |
00115 MASTER_ENABLE_ON;
00116
00117 CONFIG_SDO1_TO_RP(6);
00118 CONFIG_SCK1OUT_TO_RP(7);
00119
00120 SPI1STATbits.SPIEN = 1;
00121 }
00122 void configDAC() {
00123 CONFIG_SLAVE_ENABLE();
00124 SLAVE_DISABLE();
00125 }
00126
00127 void writeDAC (uint8 dacval) {
00128 SLAVE_ENABLE();
00129 ioMasterSPI1(0b00001001);
00130 ioMasterSPI1(dacval);
00131 SLAVE_DISABLE();
00132 }
00133
00134 #define ISR_PERIOD 125 // in microseconds
00135
00136 void configTimer3(void) {
00137
00138 T2CONbits.T32 = 0;
00139
00140
00141 T3CON = T3_OFF |T3_IDLE_CON | T3_GATE_OFF
00142 | T3_SOURCE_INT
00143 | T3_PS_1_1 ;
00144 PR3 = usToU16Ticks (ISR_PERIOD, getTimerPrescale(T3CONbits)) - 1;
00145 TMR3 = 0;
00146 _T3IF = 0;
00147 _T3IP = 1;
00148 _T3IE = 1;
00149 T3CONbits.TON = 1;
00150 }
00151
00152
00153 uint8 au8_bufferA[BLKSIZE];
00154 uint8 au8_bufferB[BLKSIZE];
00155
00156 typedef struct tagFLAGBITS {
00157 unsigned u1_activeBuffer:
00158 1;
00159 unsigned u1_writeFlag:
00160 1;
00161 unsigned u1_recordFlag:
00162 1;
00163 unsigned u1_playbackFlag:
00164 1;
00165 unsigned u1_readFlag:
00166 1;
00167 unsigned u1_passThruFlag:
00168 1;
00169 unsigned u1_compressionFlag:
00170 1;
00171 }FLAGBITS;
00172 volatile FLAGBITS flags;
00173
00174 uint8 u8_sampleCount;
00175 uint8 u8_bufferCount;
00176 uint16 u16_adcVal;
00177 uint8 u8_dacVal;
00178 int16 i16_adcval;
00179
00180 void isrRecord() {
00181 uint8 u8_tmp;
00182 if (flags.u1_compressionFlag) {
00183
00184 i16_adcval = u16_adcVal;
00185 i16_adcval -= 2048;
00186 u8_tmp = ADPCMEncoder( i16_adcval);
00187 if (u8_sampleCount & 0x01) {
00188 u8_dacVal = (u8_tmp << 4)| u8_dacVal;
00189 u8_sampleCount++;
00190 if (flags.u1_activeBuffer) au8_bufferB[u8_bufferCount++] = u8_dacVal;
00191 else au8_bufferA[u8_bufferCount++] = u8_dacVal;
00192 } else {
00193 u8_dacVal = u8_tmp;
00194 u8_sampleCount++;
00195 }
00196 } else {
00197 u8_dacVal = (u16_adcVal>>4) & 0x00FF;
00198 if (flags.u1_activeBuffer) au8_bufferB[u8_bufferCount++] = u8_dacVal;
00199 else au8_bufferA[u8_bufferCount++] = u8_dacVal;
00200 }
00201 if (u8_bufferCount == BLKSIZE) {
00202 flags.u1_activeBuffer = !flags.u1_activeBuffer;
00203 flags.u1_writeFlag = 1;
00204 u8_bufferCount = 0;
00205 u8_sampleCount = 0;
00206 }
00207 }
00208
00209 void isrPlayback() {
00210 uint8 u8_tmp;
00211 if (flags.u1_activeBuffer) u8_tmp = au8_bufferB[u8_bufferCount];
00212 else u8_tmp = au8_bufferA[u8_bufferCount];
00213 if (flags.u1_compressionFlag) {
00214 if (u8_sampleCount & 0x01) {
00215 i16_adcval = ADPCMDecoder(u8_tmp >> 4);
00216 u8_bufferCount++;
00217 } else {
00218 i16_adcval = ADPCMDecoder(u8_tmp & 0x0F);
00219 }
00220 i16_adcval += 2048;
00221 u16_adcVal = i16_adcval;
00222 u8_dacVal = (u16_adcVal>>4) & 0x00FF;
00223 writeDAC(u8_dacVal);
00224 u8_sampleCount++;
00225 } else {
00226 writeDAC(u8_tmp);
00227 u8_bufferCount++;
00228 }
00229 if (u8_bufferCount == BLKSIZE) {
00230 flags.u1_activeBuffer = !flags.u1_activeBuffer;
00231 flags.u1_readFlag = 1;
00232 u8_bufferCount = 0;
00233 u8_sampleCount = 0;
00234 }
00235 }
00236
00237 void _ISR _T3Interrupt (void) {
00238
00239 _T3IF = 0;
00240 u16_adcVal = ADC1BUF0;
00241
00242 SET_SAMP_BIT_ADC1();
00243 if (flags.u1_recordFlag) isrRecord();
00244 if (flags.u1_playbackFlag) isrPlayback();
00245 if (flags.u1_passThruFlag) {
00246 u8_dacVal = (u16_adcVal>>4) & 0x00FF;
00247 writeDAC(u8_dacVal);
00248 }
00249 }
00250
00251 #define VREF 3.3 //assume Vref = 3.3 volts
00252
00253 void doRecord(uint8 u8_compression) {
00254 uint16 u16_MemAddr;
00255 flags.u1_compressionFlag = u8_compression;
00256 if (u8_compression) ADPCMEncoderInit();
00257 flags.u1_activeBuffer = 0;
00258 u8_sampleCount = 0;
00259 u8_bufferCount = 0;
00260 u16_MemAddr = 0;
00261 flags.u1_writeFlag = 0;
00262 flags.u1_recordFlag = 1;
00263 do {
00264 if (flags.u1_writeFlag) reportError("Record overflow");
00265 while (!flags.u1_writeFlag) doHeartbeat();
00266 flags.u1_writeFlag = 0;
00267 if (flags.u1_activeBuffer)
00268 memWriteLC515(EEPROM,u16_MemAddr,au8_bufferA);
00269 else
00270 memWriteLC515(EEPROM,u16_MemAddr,au8_bufferB);
00271 u16_MemAddr = u16_MemAddr +64;
00272 outString("*");
00273 } while (u16_MemAddr != 0);
00274 flags.u1_recordFlag = 0;
00275 flags.u1_compressionFlag = 0;
00276 outString("Finished recording\n");
00277 }
00278
00279 void doPlayback(uint8 u8_compression) {
00280 uint16 u16_MemAddr;
00281
00282 flags.u1_compressionFlag = u8_compression;
00283 if (u8_compression) ADPCMDecoderInit();
00284 flags.u1_activeBuffer = 0;
00285 flags.u1_readFlag = 0;
00286 u8_sampleCount = 0;
00287 u8_bufferCount = 0;
00288 u16_MemAddr = 0;
00289
00290 memReadLC515(EEPROM,u16_MemAddr,au8_bufferA);
00291 u16_MemAddr = u16_MemAddr +64;
00292 flags.u1_playbackFlag = 1;
00293 while (!isCharReady()) {
00294 if (flags.u1_activeBuffer)
00295 memReadLC515(EEPROM,u16_MemAddr,au8_bufferA);
00296 else
00297 memReadLC515(EEPROM,u16_MemAddr,au8_bufferB);
00298 u16_MemAddr = u16_MemAddr +64;
00299 if (flags.u1_writeFlag) reportError("Playback underflow");
00300 while (!flags.u1_readFlag) doHeartbeat();
00301 flags.u1_readFlag = 0;
00302 outChar('*');
00303 }
00304 inChar();
00305 outString("\nPlayback terminated.\n");
00306 flags.u1_playbackFlag = 0;
00307 flags.u1_compressionFlag = 0;
00308 }
00309
00310 void doSampledPassthru(void) {
00311 flags.u1_passThruFlag = 1;
00312 while (!isCharReady()) doHeartbeat();
00313 inChar();
00314 flags.u1_passThruFlag = 0;
00315 outString("\nFeedthru terminated.\n");
00316 }
00317
00318
00319 void doTest(void) {
00320 _T3IE = 0;
00321 while (!isCharReady()) {
00322 doHeartbeat();
00323 while (!_T3IF);
00324 _T3IF = 0;
00325 u16_adcVal = ADC1BUF0;
00326
00327 SET_SAMP_BIT_ADC1();
00328 outUint16(u16_adcVal);
00329 outString("\n");
00330 }
00331 _T3IE = 1;
00332 }
00333
00334 int main (void) {
00335
00336 uint8 u8_mode;
00337
00338 configBasic(HELLO_MSG);
00339 CONFIG_AN0_AS_ANALOG();
00340 configADC1_ManualCH0( ADC_CH0_POS_SAMPLEA_AN0, 31, 1 );
00341 SET_SAMP_BIT_ADC1();
00342 configSPI1();
00343 configDAC();
00344 configTimer3();
00345 configI2C1(400);
00346 while (1) {
00347 outString("\nEnter 'r' (record), 'p' (playback), 'f' (sampled feedthru). 'R', 'P' use compression. Any key terminates: ");
00348 u8_mode = inCharEcho();
00349 outString("\n");
00350 switch (u8_mode) {
00351 case 'r':
00352 doRecord(0);
00353 break;
00354 case 'R':
00355 doRecord(1);
00356 break;
00357 case 'p':
00358 doPlayback(0);
00359 break;
00360 case 'P':
00361 doPlayback(1);
00362 break;
00363 case 'f':
00364 doSampledPassthru();
00365 break;
00366 case 't':
00367 doTest();
00368 break;
00369
00370 }
00371 }
00372 }