move lpc_chip_13xx files
This commit is contained in:
496
hw/mcu/nxp/lpc_chip_13xx/src/ssp_13xx.c
Normal file
496
hw/mcu/nxp/lpc_chip_13xx/src/ssp_13xx.c
Normal file
@@ -0,0 +1,496 @@
|
||||
/*
|
||||
* @brief LPC13xx SSP Registers and control functions
|
||||
*
|
||||
* @note
|
||||
* Copyright(C) NXP Semiconductors, 2012
|
||||
* All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* Software that is described herein is for illustrative purposes only
|
||||
* which provides customers with programming information regarding the
|
||||
* LPC products. This software is supplied "AS IS" without any warranties of
|
||||
* any kind, and NXP Semiconductors and its licensor disclaim any and
|
||||
* all warranties, express or implied, including all implied warranties of
|
||||
* merchantability, fitness for a particular purpose and non-infringement of
|
||||
* intellectual property rights. NXP Semiconductors assumes no responsibility
|
||||
* or liability for the use of the software, conveys no license or rights under any
|
||||
* patent, copyright, mask work right, or any other intellectual property rights in
|
||||
* or to any products. NXP Semiconductors reserves the right to make changes
|
||||
* in the software without notification. NXP Semiconductors also makes no
|
||||
* representation or warranty that such application will be suitable for the
|
||||
* specified use without further testing or modification.
|
||||
*
|
||||
* @par
|
||||
* Permission to use, copy, modify, and distribute this software and its
|
||||
* documentation is hereby granted, under NXP Semiconductors' and its
|
||||
* licensor's relevant copyrights in the software, without fee, provided that it
|
||||
* is used in conjunction with NXP Semiconductors microcontrollers. This
|
||||
* copyright, permission, and disclaimer notice must appear in all copies of
|
||||
* this code.
|
||||
*/
|
||||
|
||||
#include "chip.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Private types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Public types/enumerations/variables
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Private functions
|
||||
****************************************************************************/
|
||||
|
||||
STATIC void SSP_Write2BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
|
||||
{
|
||||
if (xf_setup->tx_data) {
|
||||
Chip_SSP_SendFrame(pSSP, (*(uint16_t *) ((uint32_t) xf_setup->tx_data +
|
||||
xf_setup->tx_cnt)));
|
||||
}
|
||||
else {
|
||||
Chip_SSP_SendFrame(pSSP, 0xFFFF);
|
||||
}
|
||||
|
||||
xf_setup->tx_cnt += 2;
|
||||
}
|
||||
|
||||
/** SSP macro: write 1 bytes to FIFO buffer */
|
||||
STATIC void SSP_Write1BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
|
||||
{
|
||||
if (xf_setup->tx_data) {
|
||||
Chip_SSP_SendFrame(pSSP, (*(uint8_t *) ((uint32_t) xf_setup->tx_data + xf_setup->tx_cnt)));
|
||||
}
|
||||
else {
|
||||
Chip_SSP_SendFrame(pSSP, 0xFF);
|
||||
}
|
||||
|
||||
xf_setup->tx_cnt++;
|
||||
}
|
||||
|
||||
/** SSP macro: read 1 bytes from FIFO buffer */
|
||||
STATIC void SSP_Read2BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
|
||||
{
|
||||
uint16_t rDat;
|
||||
|
||||
while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) &&
|
||||
(xf_setup->rx_cnt < xf_setup->length)) {
|
||||
rDat = Chip_SSP_ReceiveFrame(pSSP);
|
||||
if (xf_setup->rx_data) {
|
||||
*(uint16_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat;
|
||||
}
|
||||
|
||||
xf_setup->rx_cnt += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/** SSP macro: read 2 bytes from FIFO buffer */
|
||||
STATIC void SSP_Read1BFifo(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
|
||||
{
|
||||
uint16_t rDat;
|
||||
|
||||
while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) &&
|
||||
(xf_setup->rx_cnt < xf_setup->length)) {
|
||||
rDat = Chip_SSP_ReceiveFrame(pSSP);
|
||||
if (xf_setup->rx_data) {
|
||||
*(uint8_t *) ((uint32_t) xf_setup->rx_data + xf_setup->rx_cnt) = rDat;
|
||||
}
|
||||
|
||||
xf_setup->rx_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns clock for the peripheral block */
|
||||
STATIC CHIP_SYSCTL_CLOCK_T Chip_SSP_GetClockIndex(LPC_SSP_T *pSSP)
|
||||
{
|
||||
CHIP_SYSCTL_CLOCK_T clkSSP;
|
||||
|
||||
if (pSSP == LPC_SSP0) {
|
||||
clkSSP = SYSCTL_CLOCK_SSP0;
|
||||
}
|
||||
else {
|
||||
clkSSP = SYSCTL_CLOCK_SSP1;
|
||||
}
|
||||
|
||||
return clkSSP;
|
||||
}
|
||||
|
||||
/* Returns reset ID for the peripheral block */
|
||||
STATIC CHIP_SYSCTL_PERIPH_RESET_T Chip_SSP_GetResetIndex(LPC_SSP_T *pSSP)
|
||||
{
|
||||
CHIP_SYSCTL_PERIPH_RESET_T resetSSP;
|
||||
|
||||
if (pSSP == LPC_SSP0) {
|
||||
resetSSP = RESET_SSP0;
|
||||
}
|
||||
else {
|
||||
resetSSP = RESET_SSP1;
|
||||
}
|
||||
|
||||
return resetSSP;
|
||||
}
|
||||
|
||||
/* Returns reset ID for the peripheral block */
|
||||
STATIC void Chip_SSP_SetSSPClkDivider(LPC_SSP_T *pSSP, uint32_t div)
|
||||
{
|
||||
if (pSSP == LPC_SSP0) {
|
||||
Chip_Clock_SetSSP0ClockDiv(div);
|
||||
}
|
||||
else {
|
||||
Chip_Clock_SetSSP1ClockDiv(div);
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns SSP peripheral clock for the peripheral block */
|
||||
STATIC uint32_t Chip_SSP_GetPCLKkRate(LPC_SSP_T *pSSP)
|
||||
{
|
||||
uint32_t sspCLK = Chip_Clock_GetMainClockRate();
|
||||
|
||||
if (pSSP == LPC_SSP0) {
|
||||
sspCLK /= Chip_Clock_GetSSP0ClockDiv();
|
||||
}
|
||||
else {
|
||||
sspCLK /= Chip_Clock_GetSSP1ClockDiv();
|
||||
}
|
||||
|
||||
return sspCLK;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Public functions
|
||||
****************************************************************************/
|
||||
|
||||
/*Set up output clocks per bit for SSP bus*/
|
||||
void Chip_SSP_SetClockRate(LPC_SSP_T *pSSP, uint32_t clk_rate, uint32_t prescale)
|
||||
{
|
||||
uint32_t temp;
|
||||
temp = pSSP->CR0 & (~(SSP_CR0_SCR(0xFF)));
|
||||
pSSP->CR0 = temp | (SSP_CR0_SCR(clk_rate));
|
||||
pSSP->CPSR = prescale;
|
||||
}
|
||||
|
||||
/* SSP Polling Read/Write in blocking mode */
|
||||
uint32_t Chip_SSP_RWFrames_Blocking(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
|
||||
{
|
||||
/* Clear all remaining frames in RX FIFO */
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
|
||||
Chip_SSP_ReceiveFrame(pSSP);
|
||||
}
|
||||
|
||||
/* Clear status */
|
||||
Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
|
||||
|
||||
if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
|
||||
while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
|
||||
/* write data to buffer */
|
||||
if (( Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
|
||||
SSP_Write2BFifo(pSSP, xf_setup);
|
||||
}
|
||||
|
||||
/* Check overrun error */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for any data available in RX FIFO */
|
||||
SSP_Read2BFifo(pSSP, xf_setup);
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (xf_setup->rx_cnt < xf_setup->length || xf_setup->tx_cnt < xf_setup->length) {
|
||||
/* write data to buffer */
|
||||
if (( Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && ( xf_setup->tx_cnt < xf_setup->length) ) {
|
||||
SSP_Write1BFifo(pSSP, xf_setup);
|
||||
}
|
||||
|
||||
/* Check overrun error */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for any data available in RX FIFO */
|
||||
SSP_Read1BFifo(pSSP, xf_setup);
|
||||
}
|
||||
}
|
||||
if (xf_setup->tx_data) {
|
||||
return xf_setup->tx_cnt;
|
||||
}
|
||||
else if (xf_setup->rx_data) {
|
||||
return xf_setup->rx_cnt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* SSP Polling Write in blocking mode */
|
||||
uint32_t Chip_SSP_WriteFrames_Blocking(LPC_SSP_T *pSSP, uint8_t *buffer, uint32_t buffer_len)
|
||||
{
|
||||
uint32_t tx_cnt = 0, rx_cnt = 0;
|
||||
|
||||
/* Clear all remaining frames in RX FIFO */
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
|
||||
Chip_SSP_ReceiveFrame(pSSP);
|
||||
}
|
||||
|
||||
/* Clear status */
|
||||
Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
|
||||
|
||||
if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
|
||||
uint16_t *wdata16;
|
||||
|
||||
wdata16 = (uint16_t *) buffer;
|
||||
|
||||
while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
|
||||
/* write data to buffer */
|
||||
if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
|
||||
Chip_SSP_SendFrame(pSSP, *wdata16);
|
||||
wdata16++;
|
||||
tx_cnt += 2;
|
||||
}
|
||||
|
||||
/* Check overrun error */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for any data available in RX FIFO */
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET) {
|
||||
Chip_SSP_ReceiveFrame(pSSP); /* read dummy data */
|
||||
rx_cnt += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint8_t *wdata8;
|
||||
|
||||
wdata8 = buffer;
|
||||
|
||||
while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
|
||||
/* write data to buffer */
|
||||
if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
|
||||
Chip_SSP_SendFrame(pSSP, *wdata8);
|
||||
wdata8++;
|
||||
tx_cnt++;
|
||||
}
|
||||
|
||||
/* Check overrun error */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for any data available in RX FIFO */
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
|
||||
Chip_SSP_ReceiveFrame(pSSP); /* read dummy data */
|
||||
rx_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return tx_cnt;
|
||||
|
||||
}
|
||||
|
||||
/* SSP Polling Read in blocking mode */
|
||||
uint32_t Chip_SSP_ReadFrames_Blocking(LPC_SSP_T *pSSP, uint8_t *buffer, uint32_t buffer_len)
|
||||
{
|
||||
uint32_t rx_cnt = 0, tx_cnt = 0;
|
||||
|
||||
/* Clear all remaining frames in RX FIFO */
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
|
||||
Chip_SSP_ReceiveFrame(pSSP);
|
||||
}
|
||||
|
||||
/* Clear status */
|
||||
Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
|
||||
|
||||
if (Chip_SSP_GetDataSize(pSSP) > SSP_BITS_8) {
|
||||
uint16_t *rdata16;
|
||||
|
||||
rdata16 = (uint16_t *) buffer;
|
||||
|
||||
while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
|
||||
/* write data to buffer */
|
||||
if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
|
||||
Chip_SSP_SendFrame(pSSP, 0xFFFF); /* just send dummy data */
|
||||
tx_cnt += 2;
|
||||
}
|
||||
|
||||
/* Check overrun error */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for any data available in RX FIFO */
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
|
||||
*rdata16 = Chip_SSP_ReceiveFrame(pSSP);
|
||||
rdata16++;
|
||||
rx_cnt += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
uint8_t *rdata8;
|
||||
|
||||
rdata8 = buffer;
|
||||
|
||||
while (tx_cnt < buffer_len || rx_cnt < buffer_len) {
|
||||
/* write data to buffer */
|
||||
if ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF) == SET) && (tx_cnt < buffer_len)) {
|
||||
Chip_SSP_SendFrame(pSSP, 0xFF); /* just send dummy data */
|
||||
tx_cnt++;
|
||||
}
|
||||
|
||||
/* Check overrun error */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for any data available in RX FIFO */
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE) == SET && rx_cnt < buffer_len) {
|
||||
*rdata8 = Chip_SSP_ReceiveFrame(pSSP);
|
||||
rdata8++;
|
||||
rx_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rx_cnt;
|
||||
|
||||
}
|
||||
|
||||
/* Clean all data in RX FIFO of SSP */
|
||||
void Chip_SSP_Int_FlushData(LPC_SSP_T *pSSP)
|
||||
{
|
||||
if (Chip_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_BSY)) {}
|
||||
}
|
||||
|
||||
/* Clear all remaining frames in RX FIFO */
|
||||
while (Chip_SSP_GetStatus(pSSP, SSP_STAT_RNE)) {
|
||||
Chip_SSP_ReceiveFrame(pSSP);
|
||||
}
|
||||
|
||||
/* Clear status */
|
||||
Chip_SSP_ClearIntPending(pSSP, SSP_INT_CLEAR_BITMASK);
|
||||
}
|
||||
|
||||
/* SSP Interrupt Read/Write with 8-bit frame width */
|
||||
Status Chip_SSP_Int_RWFrames8Bits(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
|
||||
{
|
||||
/* Check overrun error in RIS register */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
|
||||
/* check if RX FIFO contains data */
|
||||
SSP_Read1BFifo(pSSP, xf_setup);
|
||||
|
||||
while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
|
||||
/* Write data to buffer */
|
||||
SSP_Write1BFifo(pSSP, xf_setup);
|
||||
|
||||
/* Check overrun error in RIS register */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for any data available in RX FIFO */
|
||||
SSP_Read1BFifo(pSSP, xf_setup);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* SSP Interrupt Read/Write with 16-bit frame width */
|
||||
Status Chip_SSP_Int_RWFrames16Bits(LPC_SSP_T *pSSP, Chip_SSP_DATA_SETUP_T *xf_setup)
|
||||
{
|
||||
/* Check overrun error in RIS register */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
if ((xf_setup->tx_cnt != xf_setup->length) || (xf_setup->rx_cnt != xf_setup->length)) {
|
||||
/* check if RX FIFO contains data */
|
||||
SSP_Read2BFifo(pSSP, xf_setup);
|
||||
|
||||
while ((Chip_SSP_GetStatus(pSSP, SSP_STAT_TNF)) && (xf_setup->tx_cnt != xf_setup->length)) {
|
||||
/* Write data to buffer */
|
||||
SSP_Write2BFifo(pSSP, xf_setup);
|
||||
|
||||
/* Check overrun error in RIS register */
|
||||
if (Chip_SSP_GetRawIntStatus(pSSP, SSP_RORRIS) == SET) {
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Check for any data available in RX FIFO */
|
||||
SSP_Read2BFifo(pSSP, xf_setup);
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
/* Set the SSP operating modes, master or slave */
|
||||
void Chip_SSP_SetMaster(LPC_SSP_T *pSSP, bool master)
|
||||
{
|
||||
if (master) {
|
||||
Chip_SSP_Set_Mode(pSSP, SSP_MODE_MASTER);
|
||||
}
|
||||
else {
|
||||
Chip_SSP_Set_Mode(pSSP, SSP_MODE_SLAVE);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the clock frequency for SSP interface */
|
||||
void Chip_SSP_SetBitRate(LPC_SSP_T *pSSP, uint32_t bitRate)
|
||||
{
|
||||
uint32_t ssp_clk, cr0_div, cmp_clk, prescale;
|
||||
|
||||
ssp_clk = Chip_SSP_GetPCLKkRate(pSSP);
|
||||
|
||||
cr0_div = 0;
|
||||
cmp_clk = 0xFFFFFFFF;
|
||||
prescale = 2;
|
||||
|
||||
while (cmp_clk > bitRate) {
|
||||
cmp_clk = ssp_clk / ((cr0_div + 1) * prescale);
|
||||
if (cmp_clk > bitRate) {
|
||||
cr0_div++;
|
||||
if (cr0_div > 0xFF) {
|
||||
cr0_div = 0;
|
||||
prescale += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Chip_SSP_SetClockRate(pSSP, cr0_div, prescale);
|
||||
}
|
||||
|
||||
/* Initialize the SSP */
|
||||
void Chip_SSP_Init(LPC_SSP_T *pSSP)
|
||||
{
|
||||
Chip_Clock_EnablePeriphClock(Chip_SSP_GetClockIndex(pSSP));
|
||||
Chip_SSP_SetSSPClkDivider(pSSP, 1);
|
||||
Chip_SYSCTL_PeriphReset(Chip_SSP_GetResetIndex(pSSP));
|
||||
|
||||
Chip_SSP_Set_Mode(pSSP, SSP_MODE_MASTER);
|
||||
Chip_SSP_SetFormat(pSSP, SSP_BITS_8, SSP_FRAMEFORMAT_SPI, SSP_CLOCK_CPHA0_CPOL0);
|
||||
Chip_SSP_SetBitRate(pSSP, 100000);
|
||||
}
|
||||
|
||||
/* De-initializes the SSP peripheral */
|
||||
void Chip_SSP_DeInit(LPC_SSP_T *pSSP)
|
||||
{
|
||||
Chip_SSP_Disable(pSSP);
|
||||
|
||||
Chip_Clock_DisablePeriphClock(Chip_SSP_GetClockIndex(pSSP));
|
||||
Chip_SSP_SetSSPClkDivider(pSSP, 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user