Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions hardware/arduino/sam/libraries/Wire/Wire.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,10 +92,11 @@ static inline bool TWI_STATUS_NACK(uint32_t status) {
return (status & TWI_SR_NACK) == TWI_SR_NACK;
}

TwoWire::TwoWire(Twi *_twi, void(*_beginCb)(void)) :
TwoWire::TwoWire(Twi *_twi, void(*_beginCb)(void), void(*_endCb)(void)) :
twi(_twi), rxBufferIndex(0), rxBufferLength(0), txAddress(0),
txBufferLength(0), srvBufferIndex(0), srvBufferLength(0), status(
UNINITIALIZED), onBeginCallback(_beginCb), twiClock(TWI_CLOCK) {
UNINITIALIZED), onBeginCallback(_beginCb),
onEndCallback(_endCb), twiClock(TWI_CLOCK) {
}

void TwoWire::begin(void) {
Expand Down Expand Up @@ -126,6 +127,16 @@ void TwoWire::begin(int address) {
begin((uint8_t) address);
}

void TwoWire::end(void) {
TWI_Disable(twi);

// Enable PDC channel
twi->TWI_PTCR &= ~(UART_PTCR_RXTDIS | UART_PTCR_TXTDIS);

if (onEndCallback)
onEndCallback();
}

void TwoWire::setClock(uint32_t frequency) {
twiClock = frequency;
TWI_SetClock(twi, twiClock, VARIANT_MCK);
Expand Down Expand Up @@ -381,7 +392,18 @@ static void Wire_Init(void) {
NVIC_EnableIRQ(WIRE_ISR_ID);
}

TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init);
static void Wire_Deinit(void) {
NVIC_DisableIRQ(WIRE_ISR_ID);
NVIC_ClearPendingIRQ(WIRE_ISR_ID);

pmc_disable_periph_clk(WIRE_INTERFACE_ID);

// no need to undo PIO_Configure,
// as Peripheral A was enable by default before,
// and pullups were not enabled
}

TwoWire Wire = TwoWire(WIRE_INTERFACE, Wire_Init, Wire_Deinit);

void WIRE_ISR_HANDLER(void) {
Wire.onService();
Expand All @@ -408,7 +430,18 @@ static void Wire1_Init(void) {
NVIC_EnableIRQ(WIRE1_ISR_ID);
}

TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init);
static void Wire1_Deinit(void) {
NVIC_DisableIRQ(WIRE1_ISR_ID);
NVIC_ClearPendingIRQ(WIRE1_ISR_ID);

pmc_disable_periph_clk(WIRE1_INTERFACE_ID);

// no need to undo PIO_Configure,
// as Peripheral A was enable by default before,
// and pullups were not enabled
}

TwoWire Wire1 = TwoWire(WIRE1_INTERFACE, Wire1_Init, Wire1_Deinit);

void WIRE1_ISR_HANDLER(void) {
Wire1.onService();
Expand Down
9 changes: 8 additions & 1 deletion hardware/arduino/sam/libraries/Wire/Wire.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@

#define BUFFER_LENGTH 32

// WIRE_HAS_END means Wire has end()
#define WIRE_HAS_END 1

class TwoWire : public Stream {
public:
TwoWire(Twi *twi, void(*begin_cb)(void));
TwoWire(Twi *twi, void(*begin_cb)(void), void(*end_cb)(void));
void begin();
void begin(uint8_t);
void begin(int);
void end();
void setClock(uint32_t);
void beginTransmission(uint8_t);
void beginTransmission(int);
Expand Down Expand Up @@ -85,6 +89,9 @@ class TwoWire : public Stream {
// Called before initialization
void (*onBeginCallback)(void);

// Called after deinitialization
void (*onEndCallback)(void);

// TWI instance
Twi *twi;

Expand Down
2 changes: 2 additions & 0 deletions hardware/arduino/sam/system/libsam/include/twi.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ extern void TWI_SetClock( Twi *pTwi, uint32_t dwTwCk, uint32_t dwMCk );

extern void TWI_ConfigureSlave(Twi *pTwi, uint8_t slaveAddress);

extern void TWI_Disable(Twi *pTwi);

extern void TWI_Stop(Twi *pTwi);

extern void TWI_StartRead(
Expand Down
38 changes: 23 additions & 15 deletions hardware/arduino/sam/system/libsam/source/twi.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,8 @@ void TWI_ConfigureMaster( Twi* pTwi, uint32_t dwTwCk, uint32_t dwMCk )

/* SVEN: TWI Slave Mode Enabled */
pTwi->TWI_CR = TWI_CR_SVEN ;
/* Reset the TWI */
pTwi->TWI_CR = TWI_CR_SWRST ;
pTwi->TWI_RHR ;

/* TWI Slave Mode Disabled, TWI Master Mode Disabled. */
pTwi->TWI_CR = TWI_CR_SVDIS ;
pTwi->TWI_CR = TWI_CR_MSDIS ;
TWI_Disable(pTwi);

/* Set master mode */
pTwi->TWI_CR = TWI_CR_MSEN ;
Expand Down Expand Up @@ -156,15 +151,7 @@ void TWI_ConfigureSlave(Twi *pTwi, uint8_t slaveAddress)
{
uint32_t i;

/* TWI software reset */
pTwi->TWI_CR = TWI_CR_SWRST;
pTwi->TWI_RHR;

/* Wait at least 10 ms */
for (i=0; i < 1000000; i++);

/* TWI Slave Mode Disabled, TWI Master Mode Disabled*/
pTwi->TWI_CR = TWI_CR_SVDIS | TWI_CR_MSDIS;
TWI_Disable(pTwi);

/* Configure slave address. */
pTwi->TWI_SMR = 0;
Expand All @@ -178,6 +165,27 @@ void TWI_ConfigureSlave(Twi *pTwi, uint8_t slaveAddress)
assert( (pTwi->TWI_CR & TWI_CR_SVDIS)!= TWI_CR_SVDIS ) ;
}

/**
* \brief Disables the TWI.
* \param pTwi Pointer to an Twi instance.
*/
void TWI_Disable(Twi *pTwi)
{
assert( pTwi ) ;

uint32_t i;

/* TWI software reset */
pTwi->TWI_CR = TWI_CR_SWRST;
pTwi->TWI_RHR;

/* Wait at least 10 ms */
for (i=0; i < 1000000; i++);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this loop really needed?
Probably the compiler is optimizing it away...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cmaglie I would agree. When I try the following sketch, millis does not increase at all.

#include <Wire.h>

void setup() {
  unsigned long start;
  unsigned long afterBegin;
  unsigned long afterEnd;

  Serial.begin(9600);

  start = millis();
  Wire.begin(42);
  afterBegin = millis();
  Wire.end();
  afterEnd = millis();

  Serial.println(start);
  Serial.println(afterBegin);
  Serial.println(afterEnd);
}

void loop() {
  unsigned long l = millis();

  Serial.println(l);
  delay(1000);              // wait for a second
}

Output was:

2
2
2
2
1002
2002
...

There are two "delay" loops which are run, this one and one in TWI_ConfigureSlave.


/* TWI Slave Mode Disabled, TWI Master Mode Disabled*/
pTwi->TWI_CR = TWI_CR_SVDIS | TWI_CR_MSDIS;
}

/**
* \brief Sends a STOP condition on the TWI.
* \param pTwi Pointer to an Twi instance.
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,6 @@ pmc.o:
00000000 T pmc_switch_udpck_to_upllck

pwmc.o:
00000000 r C.9.8054
00000000 t FindClockConfiguration
00000000 T PWMC_ConfigureChannel
00000000 T PWMC_ConfigureChannelExt
Expand Down Expand Up @@ -100,14 +99,14 @@ pwmc.o:
00000000 T PWMC_SetSyncChannelUpdateUnlock
00000000 T PWMC_WriteBuffer
U __assert_func
00000000 r __func__.6635
00000000 r __func__.6646
00000000 r __func__.6661
00000000 r __func__.6672
00000000 r __func__.6683
00000000 r __func__.6690
00000000 r __func__.6774
00000000 r __func__.6780
00000000 r __func__.6793
00000000 r __func__.6804
00000000 r __func__.6819
00000000 r __func__.6830
00000000 r __func__.6841
00000000 r __func__.6848
00000000 r __func__.6932
00000000 r __func__.6938

rtc.o:
00000000 T RTC_ClearSCCR
Expand All @@ -123,9 +122,9 @@ rtc.o:
00000000 T RTC_SetTime
00000000 T RTC_SetTimeAlarm
U __assert_func
00000000 r __func__.6632
00000000 r __func__.6641
00000000 r __func__.6646
00000000 r __func__.6790
00000000 r __func__.6799
00000000 r __func__.6804

rtt.o:
00000000 T RTT_EnableIT
Expand All @@ -134,8 +133,8 @@ rtt.o:
00000000 T RTT_SetAlarm
00000000 T RTT_SetPrescaler
U __assert_func
00000000 r __func__.6639
00000000 r __func__.6647
00000000 r __func__.6797
00000000 r __func__.6805

spi.o:
00000000 T SPI_Configure
Expand All @@ -161,9 +160,9 @@ tc.o:
00000000 T TC_Start
00000000 T TC_Stop
U __assert_func
00000000 r __func__.6634
00000000 r __func__.6640
00000000 r __func__.6646
00000000 r __func__.6792
00000000 r __func__.6798
00000000 r __func__.6804

timetick.o:
00000000 T GetTickCount
Expand All @@ -178,6 +177,7 @@ twi.o:
00000000 T TWI_ByteSent
00000000 T TWI_ConfigureMaster
00000000 T TWI_ConfigureSlave
00000000 T TWI_Disable
00000000 T TWI_DisableIt
00000000 T TWI_EnableIt
00000000 T TWI_GetMaskedStatus
Expand All @@ -191,19 +191,20 @@ twi.o:
00000000 T TWI_TransferComplete
00000000 T TWI_WriteByte
U __assert_func
00000000 r __func__.7004
00000000 r __func__.7010
00000000 r __func__.7028
00000000 r __func__.7032
00000000 r __func__.7039
00000000 r __func__.7043
00000000 r __func__.7048
00000000 r __func__.7056
00000000 r __func__.7070
00000000 r __func__.7075
00000000 r __func__.7079
00000000 r __func__.7084
00000000 r __func__.7088
00000000 r __func__.7151
00000000 r __func__.7157
00000000 r __func__.7172
00000000 r __func__.7176
00000000 r __func__.7184
00000000 r __func__.7191
00000000 r __func__.7195
00000000 r __func__.7200
00000000 r __func__.7208
00000000 r __func__.7222
00000000 r __func__.7227
00000000 r __func__.7231
00000000 r __func__.7236
00000000 r __func__.7240

usart.o:
00000000 T USART_Configure
Expand All @@ -222,7 +223,7 @@ usart.o:
00000000 T USART_Write
00000000 T USART_WriteBuffer
U __assert_func
00000000 r __func__.6928
00000000 r __func__.7068

wdt.o:
00000000 T WDT_Disable
Expand Down Expand Up @@ -300,7 +301,6 @@ startup_sam3xa.o:
U main

adc.o:
00000000 r C.0.8146
00000000 T adc_configure_power_save
00000000 T adc_configure_sequence
00000000 T adc_configure_timing
Expand Down Expand Up @@ -485,12 +485,12 @@ efc.o:
00000000 T efc_get_wait_state
00000000 T efc_init
00000000 T efc_perform_command
00000070 T efc_perform_fcr
0000006c T efc_perform_fcr
00000000 T efc_perform_read_sequence
00000000 T efc_set_flash_access_mode
00000000 T efc_set_wait_state
0000006c T efc_write_fmr
00000000 b iap_perform_command.6909
00000068 T efc_write_fmr
00000000 b iap_perform_command.7049

gpbr.o:
00000000 T gpbr_read
Expand Down Expand Up @@ -568,7 +568,6 @@ emac.o:
00000000 T emac_phy_write
00000000 t emac_reset_rx_mem
00000000 t emac_reset_tx_mem
00000000 t emac_wait_phy.clone.1
00000000 b gs_rx_desc
00000000 b gs_tx_callback
00000000 b gs_tx_desc
Expand Down