Skip to content

Commit

Permalink
Merge pull request #1 from toitware/florian/initial
Browse files Browse the repository at this point in the history
Initial release.
  • Loading branch information
floitsch authored Apr 5, 2022
2 parents a35370a + 3adf3be commit a3531af
Show file tree
Hide file tree
Showing 11 changed files with 205 additions and 1 deletion.
12 changes: 12 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Publish package
on:
push:
tags:
- 'v*'
jobs:
create-release:
name: Create new release
runs-on: ubuntu-latest
steps:
- name: Publish
uses: toitlang/[email protected]
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
packages/
.jaguar
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
## v1.0.0 - 2021-11-19
Initial version.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Toit
Copyright (c) 2022 Toitware ApS

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# CAT24C32

Toit driver for the CAT24C32 (or similar) EEPROM.

## Usage

A simple usage example.

```
import gpio
import i2c
import cat24c32
main:
bus := i2c.Bus
--sda=gpio.Pin 21
--scl=gpio.Pin 22
device := bus.device cat24c32.I2C_ADDRESS
eeprom := cat24c32.Cat24c32 device
eeprom[0] = 0x63
eeprom.write 4 #[ 1, 2 3 ]
8.repeat: print eeprom[it]
print (eeprom.read 0 --size=10)
```

See the `examples` folder for more examples.

## References

Datasheet: https://www.onsemi.com/pdf/datasheet/cat24c32-d.pdf

## Features and bugs

Please file feature requests and bugs at the [issue tracker][tracker].

[tracker]: https://github.com/toitware/toit-cat24c32/issues
14 changes: 14 additions & 0 deletions examples/EXAMPLES_LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Zero-Clause BSD License

Copyright (C) 2022 Toitware ApS

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
32 changes: 32 additions & 0 deletions examples/main.toit
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Copyright (C) 2022 Toitware ApS. All rights reserved.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the EXAMPLES_LICENSE file.
import gpio
import i2c
import cat24c32

main:
bus := i2c.Bus
--sda=gpio.Pin 21
--scl=gpio.Pin 22

device := bus.device cat24c32.I2C_ADDRESS
eeprom := cat24c32.Cat24c32 device

eeprom[0] = 0x63
eeprom.write 1 #[
0, 1, 2, 3,
4, 5, 6, 7,
8, 9, 10, 11,
12, 13, 14, 15,
16, 17, 18, 19,
20, 21, 22, 23,
24, 25, 26, 27,
28, 29, 30, 31,
32, 33, 34, 35,
36, 37, 38, 39,
]
45.repeat:
print "$(%2d it): 0x$(%02x eeprom[it])"
print (eeprom.read 1 --size=10)
5 changes: 5 additions & 0 deletions examples/package.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
prefixes:
cat24c32: ..
packages:
..:
path: ..
3 changes: 3 additions & 0 deletions examples/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies:
cat24c32:
path: ..
1 change: 1 addition & 0 deletions package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

95 changes: 95 additions & 0 deletions src/cat24c32.toit
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (C) 2022 Toitware ApS. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be found
// in the LICENSE file.
/**
Driver for the CAT24C32 EEPROM.
*/

import binary
import math
import i2c

/// The start I2C address is 0x50, but alts go up to 0x57.
I2C_ADDRESS ::= 0x50

/**
Driver for the CAT24C32 EEPROM.
*/
class Cat24c32:

/** Size in bytes. */
static SIZE ::= 4096

static MAX_WRITE_OFFLINE_US_ ::= 5_000
static PAGE_SIZE_ ::= 32
static PAGE_MASK_ ::= ~0x1F

device_ /i2c.Device ::= ?
last_write_us_ /int := -MAX_WRITE_OFFLINE_US_

constructor .device_:

/**
Reads a single byte at address $at.
The address must satisfy 0 <= $at < $SIZE.
*/
operator[] at/int -> int:
return (read at --size=1)[0]

/**
Writes a single byte $new_value at address $at.
The address must satisfy 0 <= $at < $SIZE.
*/
operator[]= at/int new_value/int -> none:
write at #[new_value]

/**
Reads $size bytes starting at $address.
The address must satisfy 0 <= $address <= $SIZE - $size.
*/
read address/int --size=1 -> ByteArray:
if size < 0: throw "INVALID_ARGUMENT"
if not 0 <= address << address + size <= SIZE: throw "OUT_OF_RANGE"
if size == 0: return #[]
return try_: return device_.read_address #[ address >> 8, address & 0xFF ] size

/**
Writes the given $bytes starting at $address.
The address must satisfy 0 <= $address <= $SIZE - ($bytes).size.
*/
write address/int bytes/ByteArray -> none:
if not 0 <= address << address + bytes.size <= SIZE: throw "OUT_OF_RANGE"
if bytes.size == 0: return
// The device is split into pages of 32 bytes.
// Never write across page boundaries. The device would just wrap around.
if address & PAGE_MASK_ == (address + bytes.size - 1) & PAGE_MASK_:
write_page_ address bytes
return

// The address bits of the first page.
first_page_offset := address - (address & PAGE_MASK_)
first_page_bytes := PAGE_SIZE_ - first_page_offset
List.chunk_up 0 bytes.size first_page_bytes PAGE_SIZE_: | from to |
write_page_ (address + from) bytes[from..to]

/**
Writes the given $bytes to the $address.
The $bytes must only write to one page.
*/
write_page_ address/int bytes/ByteArray -> none:
assert: address & PAGE_MASK_ == (address + bytes.size - 1) & PAGE_MASK_
try_:
device_.write_address #[ address >> 8, address & 0xFF ] bytes
last_write_us_ = Time.monotonic_us

try_ [block]:
// After a write the device is offline for up to MAX_WRITE_OFFLINE_MS_.
// Try the operation, but be ok if it fails.
now := Time.monotonic_us
while last_write_us_ + MAX_WRITE_OFFLINE_US_ >= now:
catch: return block.call
sleep --ms=1
// If the device should have written, just do the operation.
return block.call

0 comments on commit a3531af

Please sign in to comment.