/*H***************************************************************************** * * $Archive:: $ * $Revision:: $ * $Date:: $ * $Author:: $ * * DESCRIPTION: Contains the functions that allows you to write to, * reset, and read the registers of the codec for the TMS320C5410, and * a function that will count the number of read errors to the structure. * * GLOBALS * * PUBLIC FUNCTIONS: * * PRIVATE FUNCTIONS: * * USAGE/LIMITATIONS: * * NOTES: * * AUTHOR: Patrick Cresap, 2000 *H***************************************************************************/ #define codec_controls_c /*---- compilation control switches ----------------------------------------*/ /***************************************************************************** * INCLUDE FILES *****************************************************************************/ /*---- system and platform files -------------------------------------------*/ /*---- program files -------------------------------------------------------*/ #include "codec_controls.h" /***************************************************************************** * EXTERNAL REFERENCE *****************************************************************************/ /*---- data declarations ---------------------------------------------------*/ extern volatile unsigned int *bdxr0Ptr; /*from main program*/ extern volatile unsigned int *bdrr0Ptr; extern unsigned short serial_port_mode; extern CODEC_CONTROL_OPTIONS codec_control; extern CODEC_CONTROL_REGISTERS codec_reg; extern unsigned short user_request; extern unsigned short read_register; extern unsigned short write_command; /*---- function prototypes -------------------------------------------------*/ /***************************************************************************** * PUBLIC DECLARATIONS *****************************************************************************/ /*---- data declarations ---------------------------------------------------*/ unsigned short regerror = 0; unsigned short regcount = 0; #define GLOBAL_INT_ENABLE asm( " rsbx intm ") /* enables interrupts*/ #define GLOBAL_INT_DISABLE asm( " ssbx intm ") /* disable interrupts*/ /***************************************************************************** * PRIVATE DECLARATIONS *****************************************************************************/ /*---- context -------------------------------------------------------------*/ /*---- data declarations ---------------------------------------------------*/ /*---- function prototypes -------------------------------------------------*/ /*---- macros --------------------------------------------------------------*/ /***************************************************************************** * PUBLIC FUNCTION DEFINITIONS *****************************************************************************/ /*F*************************************************************************** * NAME: void no_sec_mask ( void ) * * DESCRIPTION: * this places a 0 in the DO bit of the xmitted value in order to NOT request * a secondary interrupt. * * NOTES: * *F***************************************************************************/ void no_sec_mask ( void ) { if( serial_port_mode == LOOP_BACK ) { // codec_control.rcv_buffer = *bdrr0Ptr & NO_SEC_MASK; *bdxr0Ptr= codec_control.xmit_buffer & NO_SEC_MASK; // *bdxr0Ptr = *bdrr0Ptr & NO_SEC_MASK; } else { *bdxr0Ptr= codec_control.xmit_buffer & NO_SEC_MASK; } } /*F*************************************************************************** * NAME: void codec_secondary_req (void) * * DESCRIPTION: * this places a 1 in the DO bit of the xmitted value in order to request * a secondary interrupt for codec commands. * * NOTES: * *F***************************************************************************/ void codec_secondary_req (void) { if( serial_port_mode == LOOP_BACK ) { codec_control.rcv_buffer = *bdrr0Ptr | CODEC_SECONDARY_REQ; } else { *bdxr0Ptr= codec_control.xmit_buffer | CODEC_SECONDARY_REQ; } } /*F*************************************************************************** * NAME: unsigned short user_isr_convert ( void ) * * DESCRIPTION: * this function converts the user's request into a command used by the ISR. * * NOTES: * *F***************************************************************************/ unsigned short user_isr_convert ( void ) { unsigned short temp; switch (user_request) { case USER_NOTHING: temp = ISR_IDLE; break; case USER_RESET: temp = ISR_SEC_REQ_WRITE; break; case USER_WRITE: temp = ISR_SEC_REQ_WRITE; user_request = USER_NOTHING; break; case USER_READ: temp = ISR_SEC_REQ_READ; break; default: break; } return temp; } /*F*************************************************************************** * NAME: void reg_read_error (unsigned short reg) * * DESCRIPTION: * compare to make sure that what should be written to the register is * actually read and put into the register structure properly. * * NOTES: * If you stop and restart the program, errors could be caused because the * *brr0Ptr contents change. It is better to reset the DSP and reload the * program. Also, it will give an error when resetting the device. It is * normal to have 1 or 2 errors due to the above. * *F***************************************************************************/ void reg_read_error (unsigned short reg) { unsigned short regtemp = 0; unsigned short wcmdtemp = 0; /* compares to make sure that what should be written to the register * is actually read and put into the register structure. */ wcmdtemp = write_command & 0x00FF; regtemp = reg & 0x00FF; if (!(wcmdtemp == regtemp)) { regerror++; } } /*F*************************************************************************** * NAME: void write_to_register_structure ( void ) * * DESCRIPTION: * when reading a register, this function will write the contents of it to * a structure. * * NOTES: * *F***************************************************************************/ void write_to_register_structure ( void ) { switch (read_register) { case 1: codec_reg.reg1 = codec_control.read_buffer; reg_read_error(codec_reg.reg1); break; case 2: codec_reg.reg2 = codec_control.read_buffer; reg_read_error(codec_reg.reg2); break; case 3: codec_reg.reg3 = codec_control.read_buffer; reg_read_error(codec_reg.reg3); break; case 4: codec_reg.reg4 = codec_control.read_buffer; reg_read_error(codec_reg.reg4); break; default: break; } regcount++; } /*F*************************************************************************** * NAME: void write_codec_ctl( unsigned short data, * unsigned short write_command) * * DESCRIPTION: * this will carry out the user's codec request. * * NOTES: However, it does not overrule the ISR. * *F***************************************************************************/ void write_codec_ctl( unsigned short data, unsigned short write_cmd) { while (codec_control.ctl_xfer_busy) { ; } switch( user_request ) { case USER_NOTHING: // codec_control.data_buffer = data; break; case USER_RESET: codec_control.write_cmd = codec_control.sw_reset_cmd; codec_secondary_req(); codec_control.sw_reset_count--; if (codec_control.sw_reset_count == 0) { user_request = USER_NOTHING; } break; case USER_WRITE: codec_control.write_cmd = write_cmd; read_register = write_cmd; read_register = read_register >> 8; break; case USER_READ: read_register = codec_control.read_count; codec_control.read_count--; if (codec_control.read_count == 0) { user_request = USER_NOTHING; } break; default: break; } GLOBAL_INT_DISABLE; codec_control.ctl_xfer_busy = 1; GLOBAL_INT_ENABLE; } /*F*************************************************************************** * NAME: void send_read_cmd (unsigned short reg) * * DESCRIPTION: * determines which command to send depending on which register to read. * * NOTES: * *F***************************************************************************/ void send_read_cmd (unsigned short reg) { switch (reg) /* which register to read */ { case 1: codec_control.read_cmd = 0x2100; break; case 2: codec_control.read_cmd = 0x2200; break; case 3: codec_control.read_cmd = 0x2300; break; case 4: codec_control.read_cmd = 0x2400; break; default: break; } }