📄 blisrchdl.c
字号:
/**************************************************
*
* blisrchdl.c
*
* CVS ID: $Id: blisrchdl.c,v 1.13 2007/10/16 07:37:01 marcucci Exp $
* Author: Maurizio Marcucci [MM] - STM
* Date: $Date: 2007/10/16 07:37:01 $
* Revision: $Revision: 1.13 $
*
* Description:
*
*
***************************************************
*
* COPYRIGHT (C) ST Microelectronics 2005
* All Rights Reserved
*
***************************************************
*
* STM CVS Log:
*
* $Log: blisrchdl.c,v $ * Revision 1.13 2007/10/16 07:37:01 marcucci * Provide I2C message at the end of Data Download *
* Revision 1.12 2007/10/12 13:21:15 marcucci
* I2C interrupt procedure modified for high speed
*
* Revision 1.11 2007/07/11 10:11:43 marcucci
* Set BUSY condition on I2C Start Detection and I2C emergency Init added
*
* Revision 1.10 2007/07/04 14:22:57 marcucci
* Continuous Data Transfer Added
*
* Revision 1.9 2007/07/02 08:40:58 marcucci
* I2C Bootloader
*
* Revision 1.8 2007/02/15 13:09:40 marcucci
* Bootloader Optimization
*
* Revision 1.7 2006/09/18 09:55:20 belardi
* Corrected CVS keyword usage
*
* Revision 1.6 2006/09/18 09:22:15 belardi
* Added Log CVS keyword into file header
*
*
***************************************************/
#include "blgendef.h"
#include "blmsgdef.h"
#include "hwreg.h"
#include "blscidef.h"
#define RWBIT_MASK 0x01
//#define BITSTREAM11 1
//extern uint32 bl_TimerCntr;
//extern uint32 bl_CD_BLOCK;
//extern void bl_Input2Output(uint32 *in_ptr, uint32 *out_ptr);
//uint32 bl_GetStartLBA(void);
//uint32 bl_GetStopLBA(void);
//uint32 bl_GetSubcode(uint32 InputBufferPtr);
//extern uint32 bl_SIN100048K[];
//extern uint32 bl_SIN100032K[];
//void bl_ClearI2cDebInfo(void);
//void bl_set_gpio(unsigned int port, unsigned int bit, unsigned int val);
//#pragma import(__use_no_semihosting_swi)
extern BL_STRUCT * bl;
void bl_i2c_isr(void);
/******************************************************************************/
/* Function: bl_i2c_event_isr */
/* */
/*! \brief I2C event interrupt Service Routine
* \param void
* \return void
* \remark
*/
/******************************************************************************/
__irq void bl_i2c_event_isr(void)
{
bl_i2c_isr();
EIC_IPR = BL_EIC_I2C_EVENT_MASK;
}
/******************************************************************************/
/* Function: bl_i2c_xfer_isr */
/* */
/*! \brief I2C transfer interrupt Service Routine
* \param void
* \return void
* \remark
*/
/******************************************************************************/
__irq void bl_i2c_xfer_isr(void)
{
bl_i2c_isr();
EIC_IPR = BL_EIC_I2C_XFER_MASK;
}
/******************************************************************************/
/* Function: bl_i2c_isr */
/* */
/*! \brief I2C interrupt service routine
* \param void
* \return void
* \remark
*/
/******************************************************************************/
void bl_i2c_isr(void)
{
I2C_SR1_UNION i2c_sr1;
I2C_SR2_UNION i2c_sr2;
uint8 i2c_slave_addr;
//DISABLE_INTERRUPTS();// To Do Disable Interrupts by acting on I bit
i2c_sr1.all = I2C0_SR1.all;
i2c_sr2.all = I2C0_SR2.all;
//if(i2c_sr1.field.evf)
//{
if(i2c_sr1.field.adsl)
{
// Start Condition
// Good Slave Address Detected
bl->i2c_flags.af = 0;
if(bl->i2c_flags.i2c_tx_ready == 0)
{
// Start received while I2C Receiver is active.
// It is Stop Condition
// Repeated Start Condition
bl->i2c_flags.i2c_tx_ready = 1;
bl->i2c_flags.tx_msg_done = 1;
}
if(bl->i2c_flags.i2c_rx_ready == 0)
{
// Start received while I2C Receiver is active.
// It is Stop Condition
// Repeated Start Condition
bl->i2c_flags.i2c_rx_ready = 1;
bl->i2c_flags.msg_rcvd = 1;
bl->i2c_irq_tx_buffer[0] = 0; // Invalidate Tx Message
BL_I2C_BUSY();
}
/* First data byte after I2C Start condition */
/* is the address, read to check if it is a read or write */
i2c_slave_addr = I2C0_DR;
if(i2c_slave_addr & RWBIT_MASK)
{
// Slave Transmitter (Read Condition)
bl->i2c_irq_tx_buffer_idx = 0;
bl->i2c_flags.i2c_tx_ready = 0;
}
else
{
// Slave Receiver (Write Condition)
bl->i2c_irq_rx_buffer_idx = 0;
bl->i2c_flags.i2c_rx_ready = 0;
BL_I2C_BUSY(); // Set Busy at reception of Start Condition
}
}//if(i2c_sr1.field.adsl)
else if (i2c_sr2.field.af == 1)
{
// Acknowledgement Failure
bl->i2c_flags.af = 1;
/* Send event to the HostIF, but only if it is a real AF situation: */
/* The last byte of the transfer may not be ack, this is not an error */
/* Use the Length field to understand if the AF was generated on he last byte */
if (bl->i2c_irq_tx_buffer_idx != bl->i2c_irq_tx_buffer[0] + 1)
{
//hostif_inevent |= HOSTIF_EVT_LL_AF_ERR;
//OSAL_wake_thread(OSAL_THREAD_HostIfTask);
// Error Condition !!!!
}
}
else
{
if (i2c_sr2.field.stopf)
{
// Stop Condition Detected
if(bl->i2c_flags.i2c_rx_ready == 0)
{
// Message Reception On Going
bl->i2c_flags.i2c_rx_ready = 1; // Release Receiver
// Invalidate Tx Message on each Stop Condition
// To avoid that ACK/NACK message be equal to the
// ACK/NACK message of the Previous Received message.
bl->i2c_irq_tx_buffer[0] = 0; // Invalidate Tx Message
if(!bl->dwn_ctrl_flags.continous_xfer)
{
bl->i2c_flags.msg_rcvd = 1;
//BL_I2C_BUSY(); // Set CRQ Off
}
else
{
bl_i2c_ack(0x00); // Added to provide something to Host
bl->dwn_ctrl_flags.continous_xfer = 0;
BL_I2C_READY();
}
}
if(bl->i2c_flags.i2c_tx_ready == 0)
{
bl->i2c_flags.i2c_tx_ready = 1;
/* [RB] signal to application that the tx buffer is ready */
bl->i2c_flags.tx_msg_done = 1;
}
}
}
//}
/* The i2c_xfer_isr interrupt handler began here */
/* Byte Transfer Finished */
if(i2c_sr1.field.btf == 1)
{
/* TRA field provides info on the direction of the transfer */
if(i2c_sr1.field.tra == 1)
{
// Send Bytes
if(bl->i2c_flags.af == 0)
{
if(bl->i2c_irq_tx_buffer_idx < bl->i2c_irq_tx_buffer[0] + 1)
{
I2C0_DR = bl->i2c_irq_tx_buffer[bl->i2c_irq_tx_buffer_idx];
bl->i2c_irq_tx_buffer_idx++;
}
else
{
I2C0_DR = 0x00;
}
}
else
{
/* Acknowledge Failure error condition: release the SDA lines */
/* See datasheet Page 220 */
I2C0_DR = 0xFF;
}
}
else
{
if(bl->dwn_ctrl_flags.continous_xfer)
{
//BL_I2C_BUSY();
bl->code_data.byte[bl->code_data_byte_idx++] = I2C0_DR;
if((bl->code_data_byte_idx & 0x03) == 0x00)
{
*bl->ram_ptr++ = bl->code_data.all;
*bl->code_checksum_ptr += bl->code_data.all;
*bl->code_size_ptr += 4;
*bl->max_addr_ptr = (uint32) bl->ram_ptr;
bl->code_data_byte_idx = 0;
}
}
else
{
if(bl->i2c_irq_rx_buffer_idx < BL_DEFAULT_MAX_I2C_RX_FRAME_SIZE)
{
bl->i2c_irq_rx_buffer[bl->i2c_irq_rx_buffer_idx++] = I2C0_DR;
}
else
{
// Warning: If Host sends continous data without sending XFER_ON before, or without
// waiting CRQ_LOW after XFER_ON could happen that we are in this case
bl->dummy = I2C0_DR;
}
}
}
}
//EIC_IPR = BL_EIC_I2C_XFER_MASK; // EOI
//ENABLE_INTERRUPTS();
}
#if 0
__irq void bl_i2c_err(void)
{
EIC_IPR = BL_EIC_I2C_XFER_MASK; // EOI
}
#endif
/******************************************************************************/
/* Function: bl_bspi_glb_isr */
/* */
/*! \brief BSPI interrupt service routine
* \param void
* \return void
* \remark
*/
/******************************************************************************/
__irq void bl_bspi_glb_isr(void)
{
BSPI_CSR2_UNION bl_bspi_csr2;
while(1)
{
bl_bspi_csr2.all = BSPI_CSR2.all;
if(bl_bspi_csr2.field.rfne)
{
if(bl->bspi.bspi_rx_buffer_idx < 300)
{
bl->bspi.bspi_rx_buffer[bl->bspi.bspi_rx_buffer_idx++] = (BSPI_RXR & 0xFF);
}
bl->bspi.bspi_rx_bytes++;
}
else
{
break;
}
}
EIC_IPR = BL_BSPI_GLB_INT_MASK; // EOI
}
/******************************************************************************/
/* Function: bl_RS232_Int */
/* */
/*! \brief RS232 interrupt service routine
* \param void
* \return void
* \remark
*/
/******************************************************************************/
__irq void bl_RS232_Int(void)
{
UART_SR_UNION bl_uart_sr;
uint32 bl_tx_data;
#if (BL_UART == 0)
bl_uart_sr = UART0_SR;
#else
bl_uart_sr = UART1_SR;
#endif
// Interrupt = (uint8) ((SCISR.all & SCICR2.all & 0xE0) | (SCISR.all & SCICR1.all & 0x0F));
// RS232_Status = SCISR.all & 0x1F;
if (bl_uart_sr.field.RxBuffNotEmpty && (bl->RS232_Status & BL_RS232_RX_READY))
{
//if (bl->RS232_RxIndex < (sizeof(bl->RS232_RxBuffer) >> 2)) /* BB041104 */
if (bl->RS232_RxIndex < sizeof(bl->RS232_RxBuffer)) /* BB041104 */
{
#if (BL_UART == 0)
bl->RS232_RxBuffer[bl->RS232_RxIndex] = UART0_RXBUF; /* Store the receive data */
#else
bl->RS232_RxBuffer[bl->RS232_RxIndex] = UART1_RXBUF; /* Store the receive data */
#endif
bl->RS232_RxBuffer[bl->RS232_RxIndex] &= 0xFF;
//bl_deb_rs232_rx_buf[bl_deb_rs232_rx_buf_idx] = bl_RS232_RxBuffer[bl_RS232_RxIndex];
//bl_deb_rs232_rx_buf[bl_deb_rs232_rx_buf_idx] &= 0xFF;
//bl_deb_rs232_rx_buf_idx++;
//bl_deb_rs232_rx_buf_idx &= 0xFF;
}
bl->RS232_RxIndex++;
/* {{{ Check if the frame all the frame have been received */
if(bl->RS232_RxIndex > bl->RS232_RxBuffer[0])
{
//BitClr(RS232_Status,RS232_RX_READY); /* Driver is no more ready to reveive */
bl->RS232_Status &= ~BL_RS232_RX_READY;
//BitSet(RS232_Status,RS232_NEW_MSG); /* Set the new message flag */
bl->RS232_Status |= BL_RS232_NEW_MSG;
//SCICR2.field.rie = 0; /* Disable receiver interrupt */
#if (BL_UART == 0)
UART0_IER.field.RxBuffNotEmptyIe = 0;
#else
UART1_IER.field.RxBuffNotEmptyIe = 0;
#endif
bl->RS232_RxIndex = 0;
//UartTestVectIdx = 0;
}
}
#if (BL_UART == 0)
if ((bl_uart_sr.field.TxEmpty) && (UART0_IER.field.TxEmptyIe)) //(Interrupt, RS232_TRANSMIT_IT))
#else
if ((bl_uart_sr.field.TxEmpty) && (UART1_IER.field.TxEmptyIe)) //(Interrupt, RS232_TRANSMIT_IT))
#endif
{
bl_tx_data = bl->RS232_TxBuffer[bl->RS232_TxIndex++];
bl_tx_data &= 0xFF;
#if (BL_UART == 0)
//UART0_TXBUF = RS232_TxBuffer[RS232_TxIndex++];
UART0_TXBUF = bl_tx_data;
#else
//UART1_TXBUF = RS232_TxBuffer[RS232_TxIndex++];
UART1_TXBUF = bl_tx_data;
#endif
//bl_deb_rs232_tx_buf[bl_deb_rs232_tx_buf_idx++] = bl_tx_data;
//bl_deb_rs232_tx_buf_idx &= 0x0F;
//UartTestVect[UartTestVectIdx++] = RS232_TxBuffer[RS232_TxIndex++];
//UartTestVectIdx &= 0x0F;
if (bl->RS232_TxIndex > bl->RS232_TxBuffer[0])
{
//BitSet(RS232_Status,RS232_TX_READY); /* Driver is now ready to send another frame */
bl->RS232_Status |= BL_RS232_TX_READY;
bl->RS232_TxIndex = 0;
//SCICR2.field.tcie = 0; /* Disable transmiter interrupt */
#if (BL_UART == 0)
UART0_IER.field.TxEmptyIe = 0;
#else
UART1_IER.field.TxEmptyIe = 0;
#endif
}
}
/* }}} */
/* {{{ Parity interrupt */
// if(BitMsk(Interrupt,RS232_PARITY_IT))
// {
// SCIDR; /* Just to release the parity interrupt */
// }
/* }}} */
#if (BL_UART == 0)
EIC_IPR = BL_EIC_UART0_MASK; // EOI
#else
EIC_IPR = BL_EIC_UART1_MASK; // EOI
#endif
}
/* PUBLIC FUNCTIONS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -